一、 项目名称 LAMP+Nginx+Squid搭建web集群环境 二、 项目拓扑 三、 项目描述 3.1 项目环境
某部队为了满足信息化政治工作建设需要,用以丰富官兵日常生活内容,活化教育形式,更好的建设部队人文环境,准备架设部队内部的网站服务器,并申请使用军内公网IP:1.1.1.1 基于以上情况为该部提出以下解决方案。
3.2 实施方案
3.2.1 服务器操作系统与软件版本选择
操作系统选择RedHat企业版5.10; Nginx选择1.2.0版本源码安装包 Squid选择系统镜像自带的版本squid-2.6.STABLE21-6.el5 Apache选择系统镜像自带的版本httpd-2.2.3-82.el5_9 PHP 选择源码包php-5.4.9 MySql代理选择官方的免安装版本mysql-proxy-0.8.3-linux-rhel5-x86-64bit MySql选择源码包版本为mysql-5.5.13 以下是IP规划: Server Name
| Port
| IP
| Function
| client
| eth0
| 1.1.1.2
| 模拟外部网络客户端
| Nginx_1
| eth0
| 1.1.1.1
| 负载均衡
| eth1
| 192.168.1.254
| Squid_1
| eth0
| 192.168.1.10
| 页面缓存
| Squid_2
| eth0
| 192.168.1.20
| 页面缓存
| Web_4
| eth0
| 192.168.1.30
| 提供web服务
| Web_5
| eth0
| 192.168.1.40
| 提供web服务
| Mysql_proxy6
| eth0
| 192.168.1.60
| 数据库代理,读写分离
| Mysql_master7
| eth0
| 192.168.1.70
| 主数据库,可读写
| Mysql_slave8
| eth0
| 192.168.1.80
| 从数据库
| Backup_9
| eth0
| 192.168.1.90
| 整个网络数据的备份
|
3.2.2 在名为nginx_1的服务上部署nginx,作为负载均衡器,把用户访问http://www.tarena.com的请求以轮询的方式连接到服务器squid_2和服务器squid_3.。
3.2.3 squid_2和squid_3的服务器作为页面缓存服务器,能够缓存用户访问网站服务器web_4、web_5上的网页文件。
3.2.4 服务器mysql_master7 提供mysql数据库服务,用来存储网站服务器web_4、web_5服务器的数据;数据库服务器mysql_slave8自动同步mysql_master7服务器上的所有表。
3.2.5 为了减轻数据库服务器mysql_master7的压力,在名为mysql_proxy6的主机上部署mysql代理服务。
3.2.6 backup_9服务器做数据备份服务器,备份网站服务器web_4、web_5的网页文件。 web_4服务器的网页文件备份到本机的 /backup/web_4目录下;
web_5服务器的网页文件备份到本机的 /backup/web_5目录下; 每天凌晨3点开始备份网站服务器web_4、web_5的网页文件; 同步数据时使用的用户名都是webuser密码都tarenapa55且用户有上传和下载的权限; 说明:备份的数据会越来越大,为了避免存储空间不足情况的发生,把用户上传的文件存储到backup_9服务器的LV设备里,这样可以随时对存储设备做扩容操作。backup_9备份服务器保持与源网站服务器数据一致且保存源服务器上删除的文件。 3.2.7 在backup_9服务器上部署pxe服务,为所有服务器方便快捷地安装rhel5 /rhel6 操作系统
3.2.8 为了保证数据库的冗余,在数据库服务器mysql_master7上每天23点执行备份脚本mysqlbak.sh。
脚本mysqlbak.sh的功能如下:备份每天新生成的binlog文件,把备份的文件打包并压缩到系统的/dbbak目录下;用系统日期做打包压缩文件名;然后把打包压缩的文件上传到backup_9服务器的/backup/mysqlbak目录下。 3.2.9 每周一早上7点,对服务器mysql_slave8做完整备份;备份文件存放到本地的/sdb1分区里。
3.2.10 在nginx_1服务器上编写触发更新网页文件的shell脚本。程序员新添加的网页文件能够及时的同步到2台网站服务器上。
四、 配置过程 4.1 配置网站服务
4.1.1 安装提供服务的软件包
在web_4(192.168.1.40)和web_5(192.168.1.50)上分别做如下操作: # yum -y install httpd httpd-devel # yum -y install php php-*.x86_64 # service httpd restart 4.1.2 修改配置文件 在web_4上写个php测试网页
[iyunv@web_4 ~]# cat /var/www/html/test.php <?php echo"This is web_4";
?> 在web_5上写个php测试网页 [iyunv@web_5 ~]# cat /var/www/html/test.php <?php echo"This is web_5";
?>
4.1.3 验证服务配置
[iyunv@web_4 ~]# elinks --dumphttp://localhost/test.php Thisis web_4 [iyunv@web_5 ~]# elinks --dumphttp://localhost/test.php Thisis web_5
4.2 配置squid服务
4.2.1 安装squid软件包
分别在squid_2(192.168.1.20)和squid_3(192.168.1.30)上yum安装squid和elinks,elinks作为网页测试工具。 命令如下: # yum -y install squid # yum -y install elinks 4.2.2 修改配置文件
squid_2上的配置: [iyunv@squid_2 ~]# cd /etc/squid/ [iyunv@squid_2 squid]# egrep -v"^#|^$" squid.conf.default > squid.conf [iyunv@squid_2~]# cat /etc/squid/squid.conf
......
http_access allow all icp_accessallow all
http_port80 vhost
cache_peer192.168.1.40 parent 80 0 originserver
cache_peer192.168.1.50 parent 80 0 originserver
cache_dirufs /var/spool/squid 200 16 256
cache_mem150 MB
visible_hostnamesquid_2.example.com
access_log/var/log/squid/access.log squid
...... [iyunv@squid_2~]# service squid restart
[iyunv@squid_2~]# chkconfig squid on
Squid_3上的配置: [iyunv@squid_3~]# yum -y install squid
[iyunv@squid_3~]# scp 192.168.1.20:/etc/squid/squid.conf /etc/squid/squid.conf
[iyunv@squid_3~]# vim /etc/squid/squid.conf
...... http_accessallow all
icp_accessallow all
http_port80 vhost
cache_peer192.168.1.40 parent 80 0 originserver
cache_peer192.168.1.50 parent 80 0 originserver
cache_dirufs /var/spool/squid 200 16 256
cache_mem150 MB
visible_hostnamesquid_3.example.com
access_log/var/log/squid/access.log squid
...... [iyunv@squid_3~]# service squid restart
[iyunv@squid_3~]# chkconfig squid on
4.2.3 验证服务配置
[iyunv@squid_2 ~]# elinks --dumphttp://localhost/test.php [iyunv@squid_3 ~]# elinks --dumphttp://localhost/test.php 在web_4上关闭httpd服务,检查是否自动切换到web_5 [iyunv@web_4 ~]# service httpd stop
[iyunv@squid_2 ~]# elinks --dumphttp://localhost/test.php
[iyunv@squid_3~]# elinks --dump http://localhost/test.php
4.3 配置nginx代理服务
4.3.1 安装提供服务的软件包
在192.168.1.254上源码安装nginx >--prefix=/usr/local/nginx \ >--pid-path=/usr/local/nginx/nginx.pid \ > --user=nginx --group=nginx \ >--with-http_ssl_module --with-http_flv_module \ >--with-http_stub_status_module \ >--with-http_gzip_static_module \ [iyunv@nginx_1~]# ls /usr/local/nginx/ conf html logs sbin 4.3.2 修改配置文件
[iyunv@nginx_1 ~]# cat/usr/local/nginx/conf/nginx.conf worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; upstream "webgroup" { server 192.168.1.20:80; server 192.168.1.30:80; } server { listen 80; location / { proxy_pass http://webgroup; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } } 4.3.3 验证服务配置
启动nginx服务 [iyunv@nginx_1~]# /usr/local/nginx/sbin/nginx 访问nginx服务 [iyunv@nginx_1~]# elinks --dump http://localhost Welcome tonginx!
4.4 配置数据库服务
4.4.1 安装提供服务的软件包
准备mysql运行账户: [iyunv@mysql_master7 ~]# useradd -M -u49 -s /sbin/nologin mysql [iyunv@mysql_master7 ~]# tar zxfmysql-5.1.62.tar.gz [iyunv@mysql_master7 ~]# cd mysql-5.1.62 [iyunv@mysql_master7 mysql-5.1.62]#./configure \ > --prefix=/usr/local/mysql \ > --with-charset=utf8 \ >--with-collation=utf8_general_ci \ >--with-extra-charset=gbk,gb2312 [iyunv@mysql_master7 mysql-5.1.62]#make && make install [iyunv@mysql_master7 mysql-5.1.62]#cd /usr/local/mysql/ [iyunv@mysql_master7 mysql]#./bin/mysql_install_db --user=mysql 调整mysql目录权限: [iyunv@mysql_master7 ~]#chown -R root:mysql /usr/local/mysql/
[iyunv@mysql_master7 ~]# chown -R mysql/usr/local/mysql/var/ mysql执行优化、添加库路径: [iyunv@mysql_master7 ~]# cp -f /usr/local/mysql/share/mysql/my-medium.cnf/etc/my.cnf [iyunv@mysql_master7 ~]# ln -sf/usr/local/mysql/bin/* /usr/bin/ [iyunv@mysql_master7 ~]# vim/etc/ld.so.conf.d/mysql-64.conf /usr/local/mysql/lib/mysql [iyunv@mysql_master7 ~]# ldconfig -v 建立mysql控制脚本: [iyunv@mysql_master7 ~]# cp -f/usr/local/mysql/share/mysql/mysql.server /etc/init.d/mysqld [iyunv@mysql_master7 ~]# chmod +x/etc/init.d/mysqld [iyunv@mysql_master7 ~]# chkconfig --addmysqld [iyunv@mysql_master7 ~]# chkconfig --listmysqld mysqld 0:off 1:off 2:on 3:on 4:on 5:on 6:off 修改root登录密码 [iyunv@mysql_master7 ~]# mysqladmin -u rootpassword tarenapa55 重启服务: [iyunv@mysql_master7 ~]# service mysqldrestart MySQL manager or server PID file could not befound! [FAILED] Starting MySQL. [ OK ] 在mysql_salve8(192.168.1.80)上做以上同样操作。
4.4.2 修改配置文件
Master(192.168.1.70)上的配置如下: [iyunv@mysql_master7 ~]# vim/etc/my.cnf [mysqld] log-bin=master //binlog日志名称前缀 server-id=7 //id号,必须唯一 ... ... [iyunv@mysql_master7 ~]# servicemysqld restart Stopping mysqld: [ OK ] Starting mysqld: [ OK ] [iyunv@mysql_master7 ~]# mysql-uroot -ptarenapa55 mysql> GRANT REPLICATION SLAVEON *.* TO webuser@"192.168.1.80" IDENTIFIED BY"tarenapa55"; //授权用户,用于slave访问 Query OK, 0 rows affected (0.00sec)
Slave(192.168.1.80)上的配置如下: [iyunv@mysql_salve8 ~]# mysqladmin-u root password tarenapa55 [iyunv@mysql_salve8 ~]# vim/etc/my.cnf [mysqld] log-bin=slave server_id=8 ... ... [iyunv@mysql_salve8 ~]# servicemysqld restart Stopping mysqld: [ OK ] Starting mysqld: [ OK ] [iyunv@mysql_salve8 ~]# mysql-uroot -ptarenapa55 mysql> CHANGE MASTER TO -> MASTER_HOST="192.168.1.70", -> MASTER_USER="webuser", -> MASTER_PASSWORD="tarenapa55", -> MASTER_LOG_FILE="master.000001", -> MASTER_LOG_POS=1; Query OK, 0 rows affected (0.03sec) mysql> START SLAVE; Query OK, 0 rows affected (0.00sec) mysql> SHOW SLAVE STATUS\G; Slave_IO_Running: Yes //确保为Yes才算成功 Slave_SQL_Running: Yes //确保为Yes才算成功
4.4.3 验证服务配置
在主服务器上新建stu库: [iyunv@mysql_master7 ~]# mysql -uroot -ptarenapa55 mysql> CREATE DATABASE stu; Query OK, 1 row affected (0.00 sec) mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | stu | | test | +--------------------+ 4 rows in set (0.01 sec) 在从服务器上可以查看到stu库,表示主从同步正常: [iyunv@mysql_salve8 ~]# mysql -uroot -ptarenapa55 mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | stu | | test | +--------------------+ 4 rows in set (0.00 sec) 4.5 配置数据库代理服务
4.5.1 安装提供服务的软件包
[iyunv@mysql_proxy6 ~]# tar zxfmysql-proxy-0.8.3-linux-rhel5-x86-64bit.tar.gz -C /usr/local/ [iyunv@mysql_proxy6 ~]# cd /usr/local/ [iyunv@mysql_proxy6 local]# mvmysql-proxy-0.8.3-linux-rhel5-x86-64bit/ mysql-proxy [iyunv@mysql_proxy6 local]# cdmysql-proxy/ [iyunv@mysql_proxy6 mysql-proxy]# chmod+x share/doc/mysql-proxy/rw-splitting.lua 4.5.2 启动服务 [iyunv@mysql_proxy6 mysql-proxy]#./bin/mysql-proxy \ > -P 192.168.1.60:3306 \ //代理的IP地址和端口 > -b 192.168.1.70:3306 \ //进行写操作数据库的IP地址和端口 > -r 192.168.1.80:3306 \ //进行读操作数据库的IP地址和端口 > -s rw-splitting.lua & //指定读写分离的脚本文件 [iyunv@mysql_proxy6 mysql-proxy]# netstat-anptu | grep :3306 tcp 0 0 192.168.1.60:3306 0.0.0.0:* LISTEN 8872/mysql-proxy 在主服务器(192.168.1.70)上授权用户对stu库有完全读写权限: [iyunv@mysql_master7 ~]# mysql -uroot -ptarenapa55 mysql> GRANT ALL ON stu.* TOuser02@"192.168.1.%" IDENTIFIED BY "pwd123"; Query OK, 0 rows affected (0.00 sec)
4.5.3 验证服务配置
在主服务器上的stu库新建表info mysql> USE stu; Database changed mysql> CREATE TABLE info( id int(2) ,name varchar(10) ); Query OK, 0 rows affected (0.01 sec) 停掉从服务器上的从服务 mysql> STOP SLAVE; Query OK, 0 rows affected (0.00 sec) 在主服务器上插入一条数据: mysql> INSERT INTO info VALUES(1,"master"); Query OK, 1 row affected (0.00 sec) mysql> SELECT * FROM stu.info; +------+--------+ | id | name | +------+--------+ | 1 | master | +------+--------+ 1 row in set (0.00 sec)
在从服务器上插入一条数据,并开启从服务: mysql> USE stu; Database changed mysql> INSERT INTO info VALUES(1,"slave"); Query OK, 1 row affected (0.01 sec) mysql> START SLAVE; Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM stu.info; +------+-------+ | id |name | +------+-------+ | 1 | slave | +------+-------+ 1 row in set (0.01 sec) 在web_4上访问数据库代理192.168.1.60: [iyunv@mysql_proxy6~]# mysql -h192.168.1.60 -uuser02 -ppwd123 mysql> SELECT* FROM stu.info; +------+-------+ | id | name | +------+-------+ | 1 | slave | //看出读数据用的是从服务器 +------+-------+ 1 row in set(0.00 sec) 插入数据成功: mysql> INSERTINTO stu.info VALUES(2,"slave2"); Query OK, 1 rowaffected (0.01 sec)
当停掉主服务器上的mysql服务 mysql> SELECT* FROM stu.info; +------+--------+ | id | name | +------+--------+ | 1 | slave | +------+--------+ 1 row in set(0.00 sec) 插入数据不成功 mysql> INSERTINTO stu.info VALUES(2,"slave2"); ERROR 2013(HY000): Lost connection to MySQL server during query 4.5.4 测试网站与数据库的连接
在两台网站服务器编写连接数据库服务器的测试文件
[iyunv@web_4 ~]# cat /var/www/html/test.php <?php echo "This isweb_5...."; $links=mysql_connect("192.168.1.60","user02","pwd123"); if($links){ echo "link dbok!!!"; } else{ echo "link dbno!!!"; } ?> [iyunv@web_4 ~]# scp /var/www/html/test.php192.168.1.50:/var/www/html/ 当停掉web_4的httpd服务,可以自动连接到web_5就成功了: [iyunv@web_4 ~]# service httpd stop Stopping httpd: [ OK ] 4.6 搭建rsync服务,实现web_4和web_5触发同步网页文件 4.6.1 安装提供服务的软件包
[iyunv@web_5 ~]# yum -y install rsync [iyunv@web_5 ~]# yum -y install xinetd [iyunv@web_5 ~]# service xinetd restart Stopping xinetd: [FAILED] Starting xinetd: [ OK ] [iyunv@web_5 ~]# chkconfig xinetd on [iyunv@web_5 ~]# chkconfig rsync on
[iyunv@web_4 ~]# tar zxfinotify-tools-3.14.tar.gz [iyunv@web_4 ~]# cd inotify-tools-3.14 [iyunv@web_4 inotify-tools-3.14]# ./configure [iyunv@web_4 inotify-tools-3.14]# make&& make install
4.6.2 修改配置文件
[iyunv@web_5 ~]# vim /etc/rsyncd.conf uid = nobody gid = nobody use chroot = yes log file = /var/log/rsyncd.log pid file = /var/run/rsyncd.pid [web] path = /var/www/html comment = Apache sync read only = no dont compress = *.gz *.bz2 *.tgz *.zip
[iyunv@web_4 ~]# vim /root/ruser.pass [iyunv@web_4 ~]# chmod 600 /root/ruser.pass 4.6.3 测试
[iyunv@web_4 ~]# inotifywait -mrq -e modify,move,create,delete,attrib /var/www/html | while read X Y Z ; dorsync -avz --password-file=pass.txt /var/www/html/ root@192.168.1.50::web&>/etc/null; done & [iyunv@web_4 ~]# ls /var/www/html index.html test.php [iyunv@web_5 ~]# ls /var/www/html index.html test.php [iyunv@web_4 ~]# touch /var/www/html/123.html [iyunv@web_4 ~]# ls /var/www/html/ 123.html index.html test.php [iyunv@web_5 ~]# ls /var/www/html/ 123.html index.html test.php
验证成功后让命令开机在后台执行 [iyunv@web_4 ~]# vim /etc/rc.local ...... /usr/local/bin/inotifywait -mrq -e modify,move,create,delete,attrib /var/www/html | while read X Y Z ; do/usr/bin/rsync -avz --password-file=pass.txt --delete /var/www/html/root@192.168.1.50::web &>/etc/null; done &
4.7 将数据备份到backup_9
4.7.1 备份网页文件
[iyunv@backup_9 ~]# yum -y install rsync 建立同步账号文件 [iyunv@backup_9 ~]# vim/etc/rsyncd_users.db webuser:tarenapa55 建立 /etc/rsyncd.conf 共享设置 [iyunv@backup_9 ~]# chmod 600/etc/rsyncd_users.db [iyunv@backup_9 ~]# vim /etc/rsyncd.conf uid = nobody gid = nobody use chroot = yes log file = /var/log/rsyncd.log pid file = /var/run/rsyncd.pid [web4] path = /backup/server4 comment = Rsync web4 read only = no dont compress = *.gz *.bz2 *.tgz *.zip auth users = webuser secrets file = /etc/rsyncd_users.db [web5] path = /backup/server5 comment = Rsync web5 read only = no dont compress = *.gz *.bz2 *.tgz *.zip auth users = webuser secrets file = /etc/rsyncd_users.db 给backup_9划分个逻辑卷,并且挂载到/backup [iyunv@backup_9 ~]# mkdir -m 777 /backup [iyunv@backup_9 ~]# mount /dev/vgdata/lvdata /backup/
[iyunv@backup_9 ~]# mkdir -p -m 777/backup/server{4,5} 启用 rsync --daemon 服务 [iyunv@backup_9 ~]# yum -y install xinetd [iyunv@backup_9 ~]# chkconfig rsync on [iyunv@backup_9 ~]# chkconfig xinetd on [iyunv@backup_9 ~]# service xinetd restart
在web4(192.168.1.50)和web5(192.168.1.50)分别做如下从操作 # vim /root/sync.pass //存放同步时的密码 tarenapa55 # chmod 600 /root/sync.pass # crontab -e //编辑周期性任务 00 3 * * * /usr/bin/rsync -avz --delete--password-file=/root/sync.pass /var/www/html/ webuser@192.168.1.90::web4&>/dev/null [iyunv@web_4 ~]# chkconfig crond on
4.7.2 备份数据库文件
[iyunv@backup_9~]# mkdir -m 777 /backup/mysqlbak [iyunv@backup_9~]# vim /etc/rsyncd.conf ...... [mysql] path = /backup/mysqlbak comment = Rsync mysql read only = no dont compress = *.gz *.bz2 *.tgz *.zip auth users = webuser secrets file = /etc/rsyncd_users.db
[iyunv@mysql_master7~]# echo "tareanapa55" >/root/sync.pass [iyunv@mysql_master7~]# chmod 600 /root/sync.pass [iyunv@mysql_master7~]# vim /root/mysqlbak.sh #!/bin/bash dbdir=/var/lib/mysql index=`grep"log-bin" /etc/my.cnf | awk -F"=" '{print $2}'` bindir=/binlogdir tardir=/dbbak if [ ! -d$bindir ];then mkdir $bindir fi if [ ! -d$tardir ];then mkdir $tardir fi lastname=`tail-1 $dbdir/$index.index | awk -F"/" '{print $2}'` for i in `cat$dbdir/$index.index` do logname=`echo $i | awk -F"/"'{print $2}'` cd $dbdir if [ -e $bindir/$logname ];then continue else if [ $logname != $lastname ];then cp $logname $bindir fi fi done tar zcf/dbbak/`date +%Y%m%d`.tgz $tardir/ [iyunv@mysql_master7~]# crontab -e 00 23 * * */bin/bash /root/mysqlbak.sh 五、 项目总结 项目缺陷:
1. Nginx和mysql代理容易出现单点故障,只要nginx和mysql代理任意一台宕机,web服务不能正常访问 2. 两台mysql服务器只做了主从,一旦主服务器宕机,就不能写入数据,只能读数据。可换成互为主从的架构。
|