LNMP应用于中小型企业架构
网站架构图
说明:
1. 两台web服务器放置在公司外网网段(192.168.232.0/24),两台web服务器通过Keepalived实现主备切换,保障web服务高可靠性。
2. web服务器之间通过rsync+inotify来实现网站目录数据同步,保证主备切换以后的数据一致性。
3. 两台mysql服务器放置在公司内网网段(10.0.0.0/24),采用mysql的主从同步架构来保障后台数据库的高可靠性;通过mysql-proxy实现读写分离。
4. 通过rsync+inotify来实现mysql的本地备份。
5. 通过zabbix来监控两台web服务器和两台mysql服务器。
安装步骤
操作系统环境:5台服务器全部用户用centos6.7版本,内核版本2.6.32-573.el6.x86_64
(1) 安装Keepalived
a) web1配置
安装依赖:
# yum installgcc gcc-c++ autoconf automake -y
# yum installzlib zlib-devel openssl openssl-devel -y
# tar xvf keepalived-1.2.20.tar.gz -C /usr/local/src ;cd /usr/local/src/keepalived-1.2.20
# ./configure--prefix=/usr/local/keepalived
#make &&make install
#ln -s/usr/local/keepalived/sbin/keepalived /sbin/
# ln -s/usr/local/keepalived/bin/genhash /bin/
# ln -s /usr/local/keepalived/etc/sysconfig/keepalived/etc/sysconfig/keepalived
# mkdir /etc/keepalived/
# cp/usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
# cp/usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
# servicekeepalived start
# chkconfigkeepalived on
Master配置
#vim /etc/keepalived/keepalived.conf
vrrp_sync_groupVG1 { #vrrp同步组定义
group {
VI_1 #vrrp实例 VI_1
VI_2
}
}
vrrp_instanceVI_1 { #vrrp实例定义
stateMASTER #实例初始化状态,还可以是master!
nopreempt #不抢占,用于state 状态中,而且优先级要高于第二个backup
interface eth1 #实例绑定的网卡
#track_interface{ #设定额外监控的网卡,以下任意网卡故障,状态fault
#eth0
#eth1
#}
virtual_router_id51 #虚拟路由id(0-255)
priority100 #优先级,高优先级的将竞选为MASTER
advert_int 1 #检查间隔,默认1s
authentication {
auth_typePASS #认证方式,pass
auth_passVI_1 #认证密码
}
virtual_ipaddress{ #虚拟ip地址(vip 可以为多个)
192.168.232.110/24dev eth1 scope global #虚拟ip地址 绑定在 eth0 网卡
}
}
vrrp_instanceVI_2 {
state MASTER
nopreempt
interface eth0
#track_interface{
#eth0
#eth1
#}
virtual_router_id52
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass VI_2
}
virtual_ipaddress{
10.0.0.110/24dev eth0 scope global
}
}
b) web2配置
keepalived安装方式同web1
#vim /etc/keepalived/keepalived.conf
Backup配置
vrrp_sync_groupVG1 {
group {
VI_1
VI_2
}
}
vrrp_instanceVI_1 { #vrrp实例定义
stateBACKUP #实例初始化状态,还可以是master!
#nopreempt #不抢占,用于state 状态中,而且优先级要高于第二个backup
interfaceeth1 #实例绑定的网卡
#track_interface{ #设定额外监控的网卡,以下任意网卡故障,状态fault
#eth0
#eth1
#}
virtual_router_id51 #虚拟路由id(0-255)
priority100 #优先级,高优先级的将竞选为MASTER
advert_int1 #检查间隔,默认1s
authentication {
auth_typePASS #认证方式,pass
auth_passVI_1 #认证密码
}
virtual_ipaddress{ #虚拟ip地址(vip 可以为多个)
192.168.232.110/24dev eth1 scope global #虚拟ip地址 绑定在 eth0 网卡
}
}
vrrp_instanceVI_2 {
state BACKUP
#nopreempt
interface eth0
#track_interface{
#eth0
#eth1
#}
virtual_router_id52
priority 50
advert_int 1
authentication {
auth_type PASS
auth_pass VI_2
}
virtual_ipaddress{
10.0.0.110/24dev eth0 scope global
}
}
(2)在webserver上安装nginx
解决pcre依赖
# tar xvfpcre-8.37.tar.bz2 -C /usr/local/src/
编译安装nginx
#tar xvf nginx-1.9.4.tar.gz -C /usr/local/src/ ; cd/usr/local/src/nginx-1.9.4
#./configure --prefix=/usr/local/nginx --with-http_dav_module--with-http_stub_status_module --with-http_addition_module--with-http_sub_module --with-http_flv_module --with-http_mp4_module--with-pcre=/usr/local/src/pcre-8.37
# make ; make install ; cd
# useradd -M -u 8001 -s /sbin/nologin nginx
# vim /usr/local/nginx/conf/nginx.conf
user nginx nginx;
location / {
root html;
index index.php index.htmlindex.htm;
}
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name;
include fastcgi_params;
}
#/usr/local/nginx/sbin/nginx
#echo "/usr/local/nginx/sbin/nginx " >>/etc/rc.local
(3)在webserver上安装php
# tar xvf libmcrypt-2.5.8.tar.bz2 -C /usr/local/src/ ; cd/usr/local/src/libmcrypt-2.5.8/
# ./configure --prefix=/usr/local/libmcrypt ; make ; makeinstall ; cd
# vim /etc/ld.so.conf
includeld.so.conf.d/*.conf
/usr/local/libmcrypt/lib
# yum install php-pear
# ldconfig
# echo 'ldconfig' >> /etc/rc.local
# yum install -ylibxml2-devel libcurl-devel libjpeg-devel libpng-devel freetype freetype-devel
# tar xvfphp-5.6.13.tar.bz2 -C /usr/local/src/ ; cd /usr/local/src/php-5.6.13
#./configure --prefix=/usr/local/php \
--with-mysql=mysqlnd \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd \
--with-iconv-dir \
--with-freetype-dir \
--with-jpeg-dir \
--with-png-dir \
--with-zlib \
--with-libxml-dir \
--enable-xml \
--disable-rpath \
--enable-bcmath \
--enable-shmop \
--enable-sysvsem \
--enable-inline-optimization \
--with-curl \
--with-mcrypt=/usr/local/libmcrypt \
--enable-mbregex \
--enable-fpm \
--enable-mbstring \
--with-gd \
--enable-gd-native-ttf \
--with-openssl \
--with-mhash \
--enable-pcntl \
--enable-sockets \
--with-xmlrpc \
--enable-zip \
--enable-soap
# make -j 4 ; make install ; cd
#cp /usr/local/src/php-5.6.13/php.ini-production/usr/local/php/php.ini
# cp /usr/local/php/etc/php-fpm.conf.default/usr/local/php/etc/php-fpm.conf
# cp /usr/local/src/php-5.6.13/sapi/fpm/init.d.php-fpm/etc/init.d/php-fpm
#chmod +x /etc/init.d/php-fpm
# chkconfigphp-fpm on
#/etc/init.d/php-fpm start
(4)在dataserver上安装mysql
#!/bin/bash
yum remove -y mysql mysql-server
clear
yum install gcc gcc-c++ autoconf automake -y
echo'This shell willAuto Install Mysql5.6'
yum install -y cmake ncurses-devel
tar-zxf mysql-5.6.26.tar.gz -C /usr/local/src &&cd/usr/local/src/mysql-5.6.26
useradd -M -s /sbin/nologinmysql
mkdir/usr/local/mysql
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DMYSQL_UNIX_ADDR=/tmp/mysql.sock-DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=all -DWITH_MYISAM_STORAGE_ENGINE=1-DWITH_INNOBASE_STORAGE_ENGINE=1-DWITH_MEMORY_STORAGE_ENGINE=1-DWITH_READLINE=1-DENABLED_LOCAL_INFILE=1-DMYSQL_DATADIR=/usr/local/mysql/data -DMYSQL_USER=mysql
make&&makeinstall
chown -R mysql:mysql /usr/local/mysql
/usr/local/mysql/scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
mv/etc/my.cnf/etc/my.cnf.bak
cp/usr/local/mysql/support-files/my-default.cnf/etc/my.cnf
sed-i '/^\[mysqld\]/adatadir = /usr/local/mysql/data'/etc/my.cnf
sed-i '/^\[mysqld\]/abasedir = /usr/local/mysql'/etc/my.cnf
cp/usr/local/mysql/support-files/mysql.server/etc/init.d/mysqlsev
chmod+x /etc/init.d/mysqlsev
echo"PATH=/usr/local/mysql/bin:$PATH">>/etc/profile
chkconfig mysqlsev on
echo
echo"installsuccess"
source /etc/profile
echo"source/etc/profile">>/etc/rc.local
service mysqlsev restart
echo "If you now running mysql andothers commands,Please running: source /etc/profile"
#mysql_secure_installation #给数据库安全加固
# mysql -u root-p #登录数据库
a) mysql1配置
建立php连接数据库的帐号
mysql> createuser '1511'@'10.0.0.120' identified by '123456'
mysql> GRANTALL ON db_1511.* TO '1511'@'10.0.0.120';
mysql> flush privileges;
主从配置(主):
# vim/etc/my.cnf
[mysqld]
basedir =/usr/local/mysql
datadir=/usr/local/mysql/data
user=mysql
# Disablingsymbolic-links is recommended to prevent assorted security risks
symbolic-links=0
#
#####replication
server-id=1
log-bin=mysqlmaster-bin-log
binlog-do-db=db_1511
binlog-ignore-db=mysql
# servicemysqlsev start
# mysql -uroot-p
mysql> GRANTREPLICATION SLAVE ON *.* TO 'mm'@'10.0.0.30' IDENTIFIED BY '123456';
mysql> flushtables with read lock;
mysql> showmaster status; # 记录下file名和position值
+------------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB |Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------------+----------+--------------+------------------+-------------------+
|mysqlmaster-bin.000004 | 327 | | | |
+------------------------+----------+--------------+------------------+-------------------+
1 row in set(0.00 sec)
# mysqldump-uroot -p -h127.0.0.1 -P3306 --all-databases --triggers --routines --events>>/root/all.sql
# mysql -uroot-p
mysql> unlocktables;
# scp /root/all.sqlroot@10.0.0.30:/root/
b) mysql2配置
建立php连接数据库的帐号
mysql> createuser '1511'@'10.0.0.130' identified by '123456'
mysql> GRANTALL ON db_1511.* TO '1511'@'10.0.0.130';
mysql> flush privileges;
主从配置(从):
# vim/etc/my.cnf
[mysqld]
basedir =/usr/local/mysql
datadir=/usr/local/mysql/data
user=mysql
# Disablingsymbolic-links is recommended to prevent assorted security risks
symbolic-links=0
#
#####replication
server-id=2
log-bin=mysqlslave-bin-log
binlog-do-db=db_1511
binlog-ignore-db=mysql
# servicemysqlsev start
# mysql -uroot-p -h127.0.0.1 -P3306 < /root /all.sql
# mysql -uroot-p
mysql> changemaster to master_host = '10.0.0.20',master_user='mm',master_password='123456',master_log_file='mysqlmaster-bin.000004',master_log_pos=327;
mysql> startslave;
mysql> showslave status \G
......
Slave_IO_Running:Yes
Slave_SQL_Running:Yes
......
c) mysql-proxy配置
# tar xvf mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz
# mv mysql-proxy-0.8.5-linux-el6-x86-64bit/usr/local/mysql-proxy
# echo"PATH=$PATH:/usr/local/mysql-proxy/bin" >> /etc/bashrc
#echo "mysql-proxy -r 10.0.0.30:3306 -b 10.0.0.20:3306 -P 10.0.0.10:3306 -s/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua & ">> /etc/rc.local
# mysql-proxy -r10.0.0.30:3306 -b 10.0.0.20:3306 -P 10.0.0.10:3306 -s/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua &
(5) 分别在web1和web2服务器上安装应用
(6) 在webserver上安装rsync+inotify
a) 在web1和web2安装xinetd
# yum installxinetd -y
# vim/etc/xinetd.d/rsync
service rsync
{
disable = no
flags = IPv6
socket_type = stream
wait = no
user = root
server = /usr/bin/rsync
server_args = --daemon
log_on_failure += USERID
}
# [root@web1 ~]#service xinetd restart
Stoppingxinetd: [FAILED]
Startingxinetd: [ OK ]
#[root@web1 ~]#netstat -antup | grep xinet
tcp 0 0 :::873 :::* LISTEN 2459/xinetd
b) 在web1和web2上编辑以下两个配置文件
# vim /etc/rsyncd.conf
uid = nginx
gid = nginx
use chroot = yes
max connections =200
timeout = 600
pid file =/var/run/rsyncd.pid
lock file =/var/run/rsyncd.lock
log file =/var/log/rsyncd.log
[backup]
path =/usr/local/nginx/html/
ignore errors
read only = no
list = no
hosts allow =192.168.232.0/255.255.255.0
auth users = test
secrets file =/etc/rsyncd.password
#chownnginx:nginx /usr/local/nginx/html/ -R
#vim /etc/rsyncd.password
test:test #user:password
#chmod 600 /etc/rsyncd.password
文件编辑好以后重启服务
# service xinetdrestart
c) 在web1和web2上安装inotify
优化系统内核:
# vim/etc/sysctl.conf
fs.inotify.max_queued_events= 32768
fs.inotify.max_user_instances= 1024
fs.inotify.max_user_watches= 90000000
# sysctl -p
#tar -zxvf inotify-tools-3.13.tar.gz
# cdinotify-tools-3.13
#./configure
#make -j 4
# make install
d) 生成开机启动脚本
在web1上生成脚本:
#vim nginx_rsync.sh
#!/bin/sh
exportRSYNC_PASSWORD=test
SRC=/usr/local/nginx/html/
DST=test@192.168.232.130::backup
inotifywait -mrq-e modify,delete,create,attrib ${SRC} | while read D E F
do
/usr/bin/rsync -ahqzt --delete $SRC$DST
done
#echo"/root/nginx_rsync.sh &" >>/etc/rc.local
在web2上生成脚本
#vim nginx_rsync.sh
#!/bin/sh
exportRSYNC_PASSWORD=test
SRC=test@192.168.232.120::backup
DST=/usr/local/nginx/html/
inotifywait -mrq-e modify,delete,create,attrib ${DST} | while read D E F
do
/usr/bin/rsync -ahqzt --delete $SRC$DST
done
#echo"/root/nginx_rsync.sh &" >>/etc/rc.local
(7) 安装zabbix
a) 编译lnmp环境
注意编译PHP时需要加上--with-gettext模块
b) 编译安装zabbix server端
# tar xvf zabbix-3.0.1.tar.gz -C/usr/local/src/
# cd/usr/local/src/zabbix-3.0.1/
# mysql -uzabbix-pzabbix zabbix < database/mysql/schema.sql
# echo $?
# mysql -uzabbix-pzabbix zabbix < database/mysql/p_w_picpaths.sql
# mysql -uzabbix-pzabbix zabbix < database/mysql/data.sql
# yum install -ynet-snmp-devel
# ./configure--prefix=/usr/local/zabbix --enable-server --enable-agent--with-mysql=/usr/local/mysql/bin/mysql_config --with-net-snmp
--with-libcurl
# echo $?
# make install
# echo $?
# cd/usr/local/zabbix/
# vimetc/zabbix_server.conf
DBHost=localhost
DBName=zabbix
DBUser=zabbix
DBPassword=zabbix
# vim/usr/local/zabbix/etc/zabbix_agentd.conf
Server=127.0.0.1
ServerActive=127.0.0.1
Hostname=Zabbix server
UnsafeUserParameters=1
# vim /etc/ld.so.conf
include ld.so.conf.d/*.conf
/usr/local/libmcrypt/lib
/usr/local/mysql/lib/
# ldconfig
#/usr/local/zabbix/sbin/zabbix_server
# echo"/usr/local/zabbix/sbin/zabbix_server" >> /etc/rc.local
# cp -r/usr/local/src/zabbix-3.0.1/frontends/php/* /usr/local/nginx/html/
# vim /usr/local/php/lib/php.ini # 修改安装前端所需参数
c) 汉化zabbix server
vim /usr/local/nginx/html/include/locales.inc.php
'zh_CN' => ['name' => _('Chinese(zh_CN)'), 'display' => true],
vim /usr/local/nginx/html/include/defines.inc.php
define('ZBX_GRAPH_FONT_NAME', ' msyh'); // font file name
define('ZBX_FONT_NAME', ' msyh');
将windows系统中的C:\Windows\Fonts\微软雅黑\msyh.ttf 文件放到zabbixserver的/usr/local/nginx/html/fonts/目录下
再去zabbix web管理页面修改语言为中文即可
d) 在被监控的server上安装zabbix agent
# yum install -y curl curl-devel net-snmpnet-snmp-devel perl-DBI
# useradd -u 9001 -M -s /sbin/nologin zabbix
# tar xvf zabbix-3.0.1.tar.gz -C/usr/local/src/
# cd /usr/local/src/zabbix-3.0.1/
# ./configure --prefix=/usr/local/zabbix--enable-agent
# make install ; cd
# grep "zabbix" /etc/services --color
# grep "chkconfig"/usr/local/src/zabbix-3.0.1/ -R --color
# cp/usr/local/src/zabbix-3.0.1/misc/init.d/fedora/core/zabbix_agentd /etc/init.d/
# vim /etc/init.d/zabbix_agentd
BASEDIR=/usr/local/zabbix #修改此行
# chkconfig zabbix_agentd on
vim/usr/local/zabbix/etc/zabbix_agentd.conf
Server=192.168.232.220
ServerActive=192.168.232.220
Hostname=web1.1511.com
UnsafeUserParameters=1
# /etc/init.d/zabbix_agentd restart
在zabbix server上执行
[root@zabbix ~]# /usr/local/zabbix/bin/zabbix_get -s192.168.232.120 -p10050 -k system.uname
Linux web1.1511.com 2.6.32-573.el6.x86_64#1 SMP Thu Jul 23 15:44:03 UTC 2015 x86_64
至此zabbix_agentd 和zabbixserver通讯正常
e) 监控nginx
修改nginx 配置文件,在server 下面增加以下代码
location /ngx_status {
stub_status on;
access_log off;
#allow 127.0.0.1;
#deny all;
}
重启nginx进程。
配置zabbix_agentd
# vim/usr/local/zabbix/etc/zabbix_agentd.conf
增加以下行
UserParameter=nginx.status[*],/usr/local/zabbix/scripts/ngx-status.sh$1
编写监控nginx脚本
vim /usr/local/zabbix/scripts/ngx-status.sh
#!/bin/bash
# DateTime: 2015-10-25
# AUTHOR:凉白开
# WEBSITE: http://www.ttlsa.com
# Description:zabbix监控nginx性能以及进程状态
# Note:此脚本需要配置在被监控端,否则ping检测将会得到不符合预期的结果
# 文章地址:<spanid="sample-permalink"tabindex="-1">http://www.ttlsa.com/zabbix/<spanid="editable-post-name" title="临时固定链接,点击可更改这部分。">zabbix-monitor-nginx-performance</span>/</span>
HOST="127.0.0.1"
PORT="80"
# 检测nginx进程是否存在
function ping {
/sbin/pidof nginx | wc -l
}
# 检测nginx性能
function active {
/usr/bin/curl "http://$HOST:$PORT/ngx_status/" 2>/dev/null|grep 'Active' | awk '{print $NF}'
}
function reading {
/usr/bin/curl "http://$HOST:$PORT/ngx_status/" 2>/dev/null|grep 'Reading' | awk '{print $2}'
}
function writing {
/usr/bin/curl "http://$HOST:$PORT/ngx_status/" 2>/dev/null|grep 'Writing' | awk '{print $4}'
}
function waiting {
/usr/bin/curl "http://$HOST:$PORT/ngx_status/" 2>/dev/null|grep 'Waiting' | awk '{print $6}'
}
function accepts {
/usr/bin/curl "http://$HOST:$PORT/ngx_status/" 2>/dev/null|awk NR==3 | awk '{print $1}'
}
function handled {
/usr/bin/curl "http://$HOST:$PORT/ngx_status/" 2>/dev/null|awk NR==3 | awk '{print $2}'
}
function requests {
/usr/bin/curl "http://$HOST:$PORT/ngx_status/" 2>/dev/null|awk NR==3 | awk '{print $3}'
}
# 执行function
$1
给脚本增加执行权限
# chmod +x/usr/local/zabbix/scripts/ngx-status.sh
重启zabbix_agentd服务
# /etc/init.d/zabbix_agentd restart
去zabbix服务器web管理界面添加模版,为nginx服务器增加此模版
在测试机器上用webbench工具给nginx服务器发送流量
# webbench -c 2000 -t 300http://192.168.232.120/