1、一级调度器;
选择使用工作在四层的LVS。因为它工作在内核空间。它的调度效率要比七层调度器高几百倍。
它直接面向用户的请求。
2、二级调度器;
选择使用工作在七层的:haproxy。因为它工作在七层,能够识别用户请求的资源是什么,方便做访问控制。
如:
根据用户请求的资源类别做动静分离。请求动态内容由动态服务器响应,静态资源由静态服务器响应。这样大大提高动态服务器处理动态内容的效率。
当用户上传数据时,把用户的请求调度到专门服务用户上传数据的服务器组。
拓扑图如下:
地址使用情况如下:
LVS 的VIP 10.10.60.22
DIP 192.168.60.99
keepalived 双主模型的流动VIP:192.168.60.78(RIP)
流动VIP: 192.168.60.55(RIP)
server1.9527.com:172.16.0.88
server2.9527du.com:172.16.0.99
dataserver.9527du.com:172.16.0.44
一、解决两台Discuz!论坛服务器的非结构化数据的共享
使用:rsync + inotify 解决两台Diacuz!论坛服务器数据共享问题。
1、rsync 的服务器的设置
创建rsync服务器输出的存储空间
[root@server1 /]# mkdir we
因为rsync工作在服务器模式要为其提供配置文件,配置文件如下:
[root@server1 ~]# cat /etc/rsyncd.conf uid = nobody gid = nobody use chroot = no max connections = 10 # 最大并发连接数 strict modes = yes # 当启用基于口令认证客户端时,是否检查口令文件的权限 pid file = /var/run/rsyncd.pid log file = /var/log/rsyncd.log # 日志文件的输出路径 [web] # rsync服务器输出的存储空间叫啥名 path = /web # 定义rsync服务器输出的存储空间的位置 ignore errors =yes # 在数据传输中,出现错误是否忽略继续传输数据 read only = no # 允许客户端下载数据(从rsync服务器拉取数据) write only = no # 允许客户端上传数据(往rsync服务器推送数据) hosts allow = 172.16.0.0/24 # 允许访问rsync服务器的客户端地址 hosts deny = * # 只允许hostsallow指令定义的客户端访问,其它的都不允许 list = false # 当客户端请求服务器输出的存储空间列表时,是否列出来。 uid = root gid = root
2、rsync的服务端设置
(1)、安装inotify
[root@server2 /]# mkdir data [root@server2 admin]# tar -xf inotify-tools-3.14.tar.gz [root@server2 admin]# cd inotify-tools-3.14 [root@server2 inotify-tools-3.14]# ./configure --prefix=/usr/local/inotify [root@server2 inotify-tools-3.14]# make && make install
(2)、创建监控脚本,当/data文件系统中有:delete、move、modify、create事件发生,就触发rsync客户端推送数据到rsync服务器输出的存储空间。
脚本如下:
[root@server2 ~]# vim inotify.sh #/bin/bash # rsync服务器 rsyncServer=172.16.0.88 #初监控的文件系统(也就是同步数据源) src=/data/ #远程rsync服务器导出的存储空间 dst=web #一开始就进行一次数据同步操作 rsync -azrtopg --delete $src $rsyncServer::$dst /usr/local/inotify-tools/bin/inotifywait -mrq -e create,move,delete,modify $src | while read files;do rsync -azrtopg --delete $src $rsyncServer::$dst done
给脚本添加执行权限
[root@server2 ~]# chmod u+x inotify.sh [root@server2 ~]# ll inotify.sh -rwxr--r-- 1 root root 389 Sep 19 11:46 inotify.sh
3、测试rsync + inotify 是否能够实现数据实时同步
(1)、启动rsync服务端
让rsync服务以实时守护进程方式工作
[root@server1 ~]# rsync --daemon --config=/etc/rsyncd.conf -4
查看rsync服务监听的端口
[root@server1 ~]# netstat -anptl | grep rsync tcp 0 0 0.0.0.0:873 0.0.0.0:* LISTEN 3480/rsync
(2)、以后台方式启动rsync客户端监控脚本
[root@server2 ~]# ./inotify.sh & [1] 6629
(3)、测试/data文件系统那生下述事件是否会向rsync服务器推送数据
测试当/data文件系统发生create事件,是否能够实现数据同步
[root@server2 data]# touch test.txt [root@server2 data]# ssh 172.16.0.88 'hostname;ls -l /web ' server1.9527du.com total 4 -rw-r--r-- 1 root root 0 Sep 19 11:56 test.txt
说明:
从上述结果可以看出,当/data文件系统中有create事件发生时,rsync客户端会向rsync输出的存空间推送数据。
测试当/data文件系统发生modify 事件,是否能够实现数据同步
[root@server2 data]# echo "test inotify is ok ?" > test.txt [root@server2 data]# ssh 172.16.0.88 'hostname;cat /web/test.txt ' server1.9527du.com test inotify is ok ?
说明:
从上述结果可以看出,当/data文件系统中有modify事件发生时,rsync客户端会向rsync输出的存空间推送数据。
测试当/data文件系统发生move事件,是否能够实现数据同步
[root@server2 data]# mkdir test [root@server2 data]# mv test.txt test [root@server2 data]# ssh 172.16.0.88 'hostname;tree /web/ ' server1.9527du.com /web/ |-- 172.16.0.88 `-- test `-- test.txt 1 directory, 2 files
说明:
从上述结果可以看出,当/data文件系统中有move事件发生时,rsync客户端会向rsync输出的存空间推送数据。
测试当/data文件系统发生delete事件,是否能够实现数据同步
[root@server2 data]# rm -rf test/ [root@server2 data]# ssh 172.16.0.88 'hostname;ls -l /web ' server1.9527du.com
说明:
从上述结果可以看出,当/data文件系统中有move事件发生时,rsync客户端会向rsync输出的存空间推送数据。
inotify+rsync已经能够实现数据实现同步。
二、由于部署的是Discuz!论坛程序是由php语言开发的,提供的是动态页面程序 ,所以这里提供LAMP平台运行Discuz!应用程序。
这里选择使用rpm包安装httpd和php。php以模块的方式与httpd结合。数据库做为单台服务器(172.16.0.44)
<一>、安装数据库
1、创建数据库数据目录的存放位置;
使用lvm逻辑卷作为数据库数据目录存储位置。考滤到使用lvm的快照功能备份数据。
(1)、查看逻辑卷组是否有空闲空间
[root@dataserver /]# vgdisplay myvg | grep "PE[[:space:]]*\/[[:space:]]*Size" Alloc PE / Size 256 / 2.00 GiB Free PE / Size 1024 / 8.00 GiB
(2)、创建lvm
[root@dataserver /]# lvcreate -L 2G -n mysqldata myvg Logical volume "mysqldata" created
(3)、格式化
[root@dataserver /]# mke2fs -t ext4 /dev/myvg/mysqldata ^C [root@dataserver /]# echo $? 0
2、创建安装mysql数据时使用的用户
把mysql创建在系统用户
[root@dataserver /]# groupadd -r mysql [root@dataserver /]# useradd -r -g mysql -s /sbin/nologin mysql [root@dataserver /]# id mysql uid=403(mysql) gid=403(mysql) groups=403(mysql)
3、挂载数据目录,并创建mysql目录用为数据库的datadir.
(1)、创建挂载点
[root@dataserver /]# mkdir /mydata
(2)、编辑/etc/fstab文件,开机的时候可以自动挂载
[root@dataserver /]# vim /etc/fstab /dev/mapper/myvg-mysqldata /mydata ext4 defaults 0 0
(3)、挂载
[root@dataserver /]# mount -a [root@dataserver /]# mount | grep mysqldata /dev/mapper/myvg-mysqldata on /mydata type ext4 (rw)
(4)、创建mysql目录
[root@dataserver /]# mkdir /mydata/mysql
(5)、把该目录的属主属组修改成:mysql
[root@dataserver /]# chown mysql:mysql /mydata/mysql/ [root@dataserver /]# ll -d /mydata/mysql/ drwxr-xr-x 2 mysql mysql 4096 Sep 19 12:28 /mydata/mysql/
2、安装数据库
(1)、把mysql的二进制程序安装包解压到指定目录下
[root@dataserver user]# tar -xf mysql-5.5.22-linux2.6-i686.tar.gz -C /usr/local/ [root@dataserver user]# cd /usr/local/
做软连接
[root@dataserver local]# ln -sv mysql-5.5.22-linux2.6-i686 mysql `mysql' -> `mysql-5.5.22-linux2.6-i686' [root@dataserver local]# ll mysql lrwxrwxrwx 1 root root 26 Sep 19 12:33 mysql -> mysql-5.5.22-linux2.6-i686
(2)、初始化数据库
改变mysql的程序的属主属组为mysql,因为初始化数据库的时候,使用mysql用户运行一些程序。
[root@dataserver mysql]# chown -R mysql:mysql ./* [root@dataserver mysql]# ll total 76 drwxr-xr-x 2 mysql mysql 4096 Sep 19 12:33 bin -rw-r--r-- 1 mysql mysql 17987 Mar 3 2012 COPYING drwxr-xr-x 4 mysql mysql 4096 Sep 19 12:33 data drwxr-xr-x 2 mysql mysql 4096 Sep 19 12:33 docs drwxr-xr-x 3 mysql mysql 4096 Sep 19 12:33 include -rw-r--r-- 1 mysql mysql 7604 Mar 3 2012 INSTALL-BINARY drwxr-xr-x 3 mysql mysql 4096 Sep 19 12:33 lib drwxr-xr-x 4 mysql mysql 4096 Sep 19 12:33 man .....
初始化数据库
[root@dataserver mysql]# ./scripts/mysql_install_db --datadir=/mydata/mysql/ --user=mysql Installing MySQL system tables... OK Filling help tables... OK
说明:
从上述可以看出,初始化数据已经成功。
(3)、为启动数据库做准备工作
提供数据库运行所需的匹配文件
[root@dataserver mysql]# cp support-files/my-large.cnf /etc/mysql/my.cnf
在配置文件中设置数据库的数据目录的位置
[root@dataserver mysql]# vim /etc/mysql/my.cn thread_concurrency = 2 datadir = /mydata/mysql/
提供LSB风格的启动脚本
[root@dataserver mysql]# cp support-files/mysql.server /etc/init.d/mysqld [root@dataserver mysql]# ll /etc/init.d/mysqld -rwxr-xr-x 1 root root 10650 Sep 19 12:37 /etc/init.d/mysqld
改变mysql的程序的属主为root。属组为mysql
[root@dataserver mysql]# chown -R root:mysql ./* [root@dataserver mysql]# ll total 76 drwxr-xr-x 2 root mysql 4096 Sep 19 12:33 bin -rw-r--r-- 1 root mysql 17987 Mar 3 2012 COPYING drwxr-xr-x 4 root mysql 4096 Sep 19 12:33 data drwxr-xr-x 2 root mysql 4096 Sep 19 12:33 docs drwxr-xr-x 3 root mysql 4096 Sep 19 12:33 include -rw-r--r-- 1 root mysql 7604 Mar 3 2012 INSTALL-BINARY drwxr-xr-x 3 root mysql 4096 Sep 19 12:33 lib 。。。
4、测试是否能够启动数据库
(1)、启动数据库
[root@dataserver mysql]# service mysqld start Starting MySQL.. [ OK ]
(2)、连接数据库给数据库设置密码
[root@dataserver mysql]# mysql Welcome to the MySQL monitor. Commands end with ; or \g. ...... Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | +--------------------+ 4 rows in set (0.00 sec)
根据需要删除安装数据库默认的用户
mysql> drop user 'root'@'dataserver.9527du.com'; mysql> drop user 'root'@'::1'; mysql> drop user ''@'dataserver.9527du.com'; mysql> drop user ''@'localhost';
给保留的用户设置密码
mysql> set password for 'root'@'localhost' = password('root'); mysql> set password for 'root'@'127.0.0.1' = password('root');
设置能够远程管理数据库的用户
mysql> grant all on *.* to 'admin'@'%.%.%.%' identified by 'admin'; Query OK, 0 rows affected (0.00 sec)
5、创建Discuz! 所用的数据库,并创建仅能操作使用Discuz!论坛的数据库的用户
(1)、创建Discuz!论坛使用的数据库
mysql> create database discuz; Query OK, 1 row affected (0.00 sec)
(2)、创建并授权具有discuz数据库一切权限的用户discuz
mysql> grant all on discuz.* to 'discuz'@'172.16.0.%' identified by 'discuz'; Query OK, 0 rows affected (0.00 sec) mysql> flush privileges; Query OK, 0 rows affected (0.00 sec)
修改后数据的用户如下:
mysql> select user,host,password from mysql.user; +--------+------------+-------------------------------------------+ | user | host | password | +--------+------------+-------------------------------------------+ | root | localhost | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B | | root | 127.0.0.1 | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B | | admin | %.%.%.% | *4ACFE3202A5FF5CF467898FC58AAB1D615029441 | | discuz | 172.16.0.% | *B085E56614DFB3DF10A282ACE192776DE8BB4FA4 | +--------+------------+-------------------------------------------+ 4 rows in set (0.00 sec)
6、测试两台服务是否能够连接数据库
(1)、测试server1.9527du.com(172.16.0.88)
[root@server1 web]# mysql -udiscuz -h 172.16.0.44 -p Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. ,。。。。。。 MySQL [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | discuz | | test | +--------------------+ 3 rows in set (0.00 sec) MySQL [(none)]>
说明:
从上述结果,得知该服务器可以连接数据库了。
(2)、测试server2.9527du.com(172.16.0.99)
[root@server2 data]# mysql -udiscuz -h 172.16.0.44 -p Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. ...... MySQL [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | discuz | | test | +--------------------+ 3 rows in set (0.00 sec)
说明:
从上述结果,得知该服务器可以连接数据库了。
数据库已经安装成功!!!
<二>、分别在两台主机安装httpd 和 php
1、在server2.9527du.com(172.16.0.99)主机安装程序;
(1)、安装:httpd、php以及php也MySQL数据库交互的驱动
[root@server2 html]# yum install httpd php php-mysql
(2)、启动httpd服务器,并测试;
启动httpd服务
[root@server2 ~]# service httpd start Starting httpd: [ OK ]
提供测试页面
[root@server2 html]# vim test.php 如果能够连接数据库就会输出:Success.... else echo "Failure..."; ------> 如果不能够连接数据库就会输出:Failure... ?>
使用【curl】访问测试页
[root@server2 /]# curl http://172.16.0.99/test.php Success...
说明:
连接数据库成功。
关闭数据库服务器再进行访问测试
[root@server2 /]# ssh 172.16.0.44 'hostname;service mysqld stop' dataserver.9527du.com Shutting down MySQL.[ OK ] [root@server2 /]# curl http://172.16.0.99/test.php Failure...
说明:
server2.9527du.com的lamp平台已经搭建成功
2、在server1.9527du.com(172.16.0.88)主机安装程序;
(1)、安装:httpd、php以及php也MySQL数据库交互的驱动
[root@server1 ~]# yum install php httpd php-mysql
(2)、复制远程主机172.16.0.88的测试页test.php到当前服务器
[root@server1 ~]# scp 172.16.0.99:/var/www/html/test.php /var/www/html/ test.php 100% 140 0.1KB/s 00:00
(3)、启动httpd服务
[root@server1 ~]# service httpd start Starting httpd: [ OK ]
(4)、访问测试lamp平台
使用【curl】命令访问测试页,看看是否能够与MySQL交互。
[root@server1 ~]# curl http://172.16.0.88/test.php Failure...
说明:
从测试结果看出,连接数据库失败。
开户数据库,再次访问测试页查看结果是否还是:Failure....
开启远程数据库服务
[root@server1 ~]# ssh 172.16.0.44 'hostname;service mysqld start' dataserver.9527du.com Starting MySQL..[ OK ]
访问测试
[root@server1 ~]# curl http://172.16.0.88/test.php Success...
说明:
从上述测试结果得知server1.9527du.com 的lamp平台已经搭建成功。
到此为止,Discuz!论坛程序工作的环境已经准备好。
三、部署Discuz!论坛程序
提供的Discuz!论坛程序包:
Discuz_X2.5_SC_GBK.zip
部署方法:
先在server2.9527du.com(172.16.0.9)主机部署安装好Discuz!论坛程序,再开启rsync + inotify 数据同步服务,把应用程序同步到server1.9527du.com(172.16.0.88)服务器。
1、在server2.9527du.com 部署Discuz!
(1)、解压
[root@server2 /data]# unzip Discuz_X2.5_SC_GBK.zip
(2)、修改httpd服务器的网页根目录位置
[root@server2 upload]# vim /etc/httpd/conf/httpd.conf DocumentRoot "/data/upload"Options -Indexes FollowSymLinks AllowOverride None Order allow,deny Allow from all
(3)、重启 httpd服务
[root@server2 upload]# service httpd restart Stopping httpd: [ OK ] Starting httpd: [ OK ]
(4)、访问Discuz!进入安装引导页面,进行安装操作
如图:
下一步:
下一步:
安装完成:
2、开如rsync 服务,让Discuz!论坛程序同步到server1.9527du.com(172.16.0.88),并访问测试
(1)、修改该服务器的httpd服务的网页根目录。
[root@server1 /]# vim /etc/httpd/conf/httpd.conf DocumentRoot "/web/upload"Options -Indexes FollowSymLinks AllowOverride None Order allow,deny Allow from all
(2)、重启httpd服务
[root@server1 /]# service httpd restart Stopping httpd: [ OK ] Starting httpd: [ OK ]
(3)、开启rsync服务器
[root@server1 /]# rsync --daemon --config=/etc/rsyncd.conf --ipv4 [root@server1 /]# netstat -anptl | grep rsync tcp 0 0 0.0.0.0:873 0.0.0.0:* LISTEN 3530/rsync
(4)、启动rsync客户端的inotify脚本,让它触动rsync客户端程序把数据推送到rsync服务器输出的存储空间。
[root@server2 ~]# ./inotify.sh & [1] 3650
(5)、查看数据是否已经同步过去
[root@server2 ~]# ssh 172.16.0.88 'hostname;ls -l /web' [email protected]'s password: server1.9527du.com total 9352 -rw-r--r-- 1 root root 9522601 Sep 19 16:14 Discuz_X2.5_SC_GBK.zip drwxr-xr-x 2 root root 4096 Oct 31 2012 readme drwxr-xr-x 12 root root 4096 Oct 31 2012 upload drwxr-xr-x 4 root root 4096 Oct 31 2012 utility
说明:
从上述结果可以看出数据已经从172.16.0.99同步到172.16.0.88主机上去了。
(6)、通过访问172.16.0.88主机的Discuz!论坛程序,查看是否能够正常工作。
如下图:
说明:
该台服务器已经能够正常工作了!!!!
四、配置haproxy调度两台Discuz!论坛服务器;
使用七层调度程序:haproxy来调度两台提供Discuz!论坛服务的服务器。
提供论坛服务的服务器要有两种类型的数据要处理:
1、结构化的数据;
如:用户在Discuz!中注册的帐号和发的贴子,要保存在数据库中;
使用数据库共享来解决。
2、非结构化的数据;
如:用户上传的附件、图片要保存在文件系统中;
由于,使用两台服务器同时向外提供Discuz!论坛服务,所以两台服务器要共享上述的两种数据。上传两种数据的共享解决方案:
1、非结构数据的共享
rsync + inotify 提供数据实时同步是单方向的数据共享解决方案。如果用户上传附件或图片时,被haproxy调度到server1.9527du.com(172.16.0.88)该服务器(也就是rsync的服务器端),当下一个用户访问Discuz!论坛时,被调度到server2.9527du.com(172.16.0.99)服务器(也就是rsync的客户端),是无法下载附件以及无法浏览刚才用户上传的图片的。
所以,最好在用户上传附件或图片时,把它路由到server2.9527du.com服务器,再把数据同步到另一台服务器。
根据客户端向服务器请求资源的方法,用户上传附件或图片,属于客户端向服务器发起POST请求。所以,这里使用七层调度器haproxy,接收用户的请求报文后,拆开请求报文分析http报文中请求资源的方法。haproxy根据请求方法把用户路由到不同的后端服务器。这就是haproxy的访问控制列表acl,
2、结构化数据的共享
MySQL数据库解决结构化数据的共享。
(1)、配置haproxy
frontend main *:80 acl http_method method -i POST -------> 设置访问控制列表,只有客户端使用POST方法向服务器请求资源,都符合该acl. use_backend updataserver if http_method ------> 如果用户的请求报文中,请求资源的方法是:POST。都把它路由到:updataserver定义的后端服务器中。 default_backend webservers ---------> 非POST方法的请求,都反它路由到webservers定义的后端服务器中。 backend webservers ---------> 定义后端服务器组的 balance roundrobin ---------> 调度方法 server s1 172.16.0.88:80 check weight 1 ----> 后端服务器。 server s2 172.16.0.99:80 check weight 1 server b1 127.0.0.1:8080 ------> 为haproxy提供状态页。 stats enable stats hide-version stats uri /haproxy?stats stats scope . stats realm HAPorxy\ Statistics stats auth admin:admin stats admin if TRUE ------> 开户状态页的管理功能。 backend updataserver -------> 定义后端服务器组 balance roundrobin server s2 172.16.0.99:80 check
(2)、启动 haproxy 服务
[root@haproxy ~]# service haproxy start Starting haproxy [ ok ]
(3)、访问上传附件或图片测试,是否能够把用户路由到指定的updataserver上传服务组中。
停止上传服务器
[root@haproxy ~]# ssh 172.16.0.99 'service httpd stop' [email protected]'s password: Stopping httpd: [ OK ]
上传附件时候出现错误如图:
启动上传服务器,查看是否能够上传成功
[root@haproxy ~]# ssh 172.16.0.99 'service httpd start' [email protected]'s password: Starting httpd: [ OK ]
如下图:
从上图可以看出,当用户使用,上传附件或图片时,已经能够,把用户请求路由至指定服务器172.16.0.99。
这样,通过innotify就可以把附件同步到server1.9527du.com(172.16.0.88)服务器了。
(4)、通过日志也可以查看用户向服务器请求资源时使用POST方法,把它路由到哪台服务器。
查看:server2.9527du.com(172.16.0.99)服务器的访问日志
[root@server2 ~]# ifconfig | grep "[[:space:]]*inet[[:space:]]*addr:[1][^2]"; echo "Total_POST= `cat /var/log/httpd/access_log | grep "\" | wc -l`" inet addr:172.16.0.99 Bcast:172.16.255.255 Mask:255.255.0.0 Total_POST= 7
查看:server1.9527du.com(172.16.0.88)服务器的访问日志
[root@server1 ~]# ifconfig | grep "[[:space:]]*inet[[:space:]]*addr:[1][^2]"; echo "Total_POST= `cat /var/log/httpd/access_log | grep "\" | wc -l`" inet addr:172.16.0.88 Bcast:172.16.255.255 Mask:255.255.0.0 Total_POST= 0
说明:
POST请求已经定向到 server2.9527du.com(172.16.0.99)服务器。
(5)、由于http协议是无状态的,要基于session的方式识别用户。由于使用haproxy做上游服务器的负载均衡,假如用户现在被调度到的上游服务器是:RealServer1,
用户一刷新页面,有可能用户的请求就会被haproxy重新调度到的上游服务器是:RealServer2.由于cookie信息是保存在RealServer1服务器的,这时候会提示用户输入
用户名和密码才可以登陆系统进行发贴等操作的。所以,使用调度器调度用户的请求,要考虑session保持的。意思是说,始终把用户的请求定向到同一个上游服务器。
在haproxy中实现session保持的方法有:
A、使用 source 调度访求; 根据用户的来源地址做调度 B、基于cookie的绑定,实现session保持; D、使用共享存储,存储所有用户的sesssion信息;
基于,现在用户上网的方式考滤和易用性,以及对haproxy负载均衡效果影响等方面考滤,这里使用:基于cookie绑定的方式,实现session的保持。
配置如下:
backend webservers cookie webserver insert nocache option httpchk server s1 172.16.0.99 cookie s1 check port 80 weight 1 server s2 172.16.0.88 cookie s2 check port 80 weight 1
如图:
五、为了避免haproxy调度器成为单点故障,使用keepalived为其提供高可用。考滤到,资源的利用率把keepalived做成双主模型。
1、配置HA高可用服务,的准备工作。
使用两台主机基于主机名或IP地址都能够通讯
[root@node2 ~]# cat /etc/hosts 192.168.60.22 haproxy.9527du.com haproxy 192.168.60.128 haproxy2.9527du.com haproxy2
让新的主机名立即生效
[root@node2 ~]# hostname haproxy2.9527du.com
通过编辑配置文件,让主机名永久有效
[root@node2 ~]# vim /etc/sysconfig/network HOSTNAME=haproxy2.9527du.com haproxy2
为了,操作方便把两台主机配置成基于ssh的密钥通讯
[root@haproxy2 ~]# ssh-keygen -t rsa [root@haproxy2 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.60.22
[root@haproxy ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub 192.168.60.128 [root@haproxy ~]# ssh-keygen -t rsa [root@haproxy2 ~]# scp /etc/hosts 192.168.60.22:/etc/ hosts 100% 83 0.1KB/s 00:00
要保证两个节点的时间同步
[root@haproxy2 ~]# hostname;date;ssh haproxy.9527du.com -- 'hostname;date' haproxy2.9527du.com Sat Sep 20 13:16:56 CST 2014 haproxy.9527du.com Sat Sep 20 13:16:11 CST 2014
2、配置文件如下:
(1)、为haproxy2.9527du.com主机提供配置文件
[root@haproxy2 ~]# cat /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { ----> 全局配置段。使用邮件接收keepalive的信息。可以通过监测节点的状态转换的管理员发自定义邮件: -----> notify_master “bash shell 脚本” 说明:当该节点从backup状态转为master状态,就执行双引号("")的脚本。 ------>notify_backup "bash shell 脚本" ------>notify_fault "bash shell 脚本" notification_email { root@localhost } notification_email_from [email protected] smtp_server 192.168.60.128 -----> 邮件服务器的地址 smtp_connect_timeout 30 } vrrp_script chk_haproxy { -----> 检测haproxy服务的脚本 script "killall -0 haproxy" -----> 通过向服务发送“0”信号检测服务是否在线 interval 2 ---> 检测的时间间隔 weight -5 ---> 当检测失败了,调整节点的分在先级的 fall 2 ---> 当检测失败,检测两次都是失败的结果,才判断最终结果为失败的。为了避免误判。 rise 1 ----> 检测结果从失败转为成功,只需要检测一次就可以确定最终结果 } vrrp_instance VI_1 { -----> 定义vrrp实例为:VI_1。在该实例中,该节点是工作在BACKUP状态。 state BACKUP interface eth0 virtual_router_id 53 -----> 虚拟路由ID priority 99 -----> 该节点在VRRP实例VI_1中拥有的优先级 advert_int 1 -----> 每隔多长时间向vrrp实例的成员通告自己的优先级。 authentication { ----> vrrp实例VI_1的成员之间的认证 auth_type PASS auth_pass 2222 } virtual_ipaddress { ----->vrrp实例VT_1的流动IP 192.168.60.78 } track_script { 在vrrp实例VI_1中调用检测脚本chk_harproxy chk_haproxy } notify_master "/etc/init.d/haproxy start" ------> 当该节点的状态转为MASTER就执行后面的脚本 notify_fault "/etc/init.d/haproxy stop" --------> 当节点错误就会执行后面的脚本 } vrrp_instance VI_3 { -----> 定义的又一个vrrp实例为:VI_3。 在该实例中,该节点是工作在MASTER状态。 state MASTER interface eth0 virtual_router_id 56 priority 105 -------> 该节点在vrrp实例VT_3中拥有的优先级为:105 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { ----> VRRP实例VT_3的流动VIP 192.168.60.55 } track_script { chk_haproxy } notify_master "/etc/init.d/haproxy start" notify_fault "/etc/init.d/haproxy stop" }
(2)、为haproxy.9527du.com 主机提供的配置文件
[root@haproxy ~]# cat /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { notification_email { root@localhost } notification_email_from [email protected] smtp_server 192.168.60.22 smtp_connect_timeout 30 } vrrp_script chk_haproxy { script "killall -0 haproxy" interval 2 weight -5 fall 2 rise 1 } vrrp_instance VI_1 { ----> vrrp实例VI_1, 在该实例中开节点拥有的最高的优先级,它工作在MASTER状态 state MASTER interface eth0 virtual_router_id 53 priority 105 -----> 在vrrp实例VT_1中,该节点拥有的优先级. advert_int 1 authentication { auth_type PASS auth_pass 2222 } virtual_ipaddress { 192.168.60.78 } track_script { chk_haproxy } notify_master "/etc/init.d/haproxy start" notify_fault "/etc/init.d/haproxy stop" } vrrp_instance VI_3 { -----> vrrp实例VI_3,在该实例中,该节点工作在BACKUP状态。 state BACKUP interface eth0 virtual_router_id 56 priority 99 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.60.55 } track_script { chk_haproxy } notify_master "/etc/init.d/haproxy start" notify_fault "/etc/init.d/haproxy stop" }
3、启动测试
(1)、启动haproxy2.9527du.com节点
[root@haproxy2 ~]# service keepalived start Starting keepalived: [ OK ]
(2)、查看配置的VIP
[root@haproxy2 ~]# ip add show eth0 | grep "[[:space:]]*inet[[:space:]]" inet 192.168.60.128/24 brd 192.168.60.255 scope global eth0 inet 192.168.60.55/32 scope global eth0 inet 192.168.60.78/32 scope global eth0
(3)、查看haproxy服务
[root@haproxy2 ~]# netstat -anptl | grep haproxy tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 4890/haproxy tcp 0 1 172.16.0.1:54298 172.16.0.99:80 SYN_SENT 4890/haproxy ------> haproxy 检测后端RealServer使用的方法。 tcp 0 1 172.16.0.1:54297 172.16.0.99:80 SYN_SENT 4890/haproxy tcp 0 1 172.16.0.1:51605 172.16.0.88:80 SYN_SENT 4890/haproxy
(4)、启动haproxy.9527du.com 节点
[root@haproxy ~]# service keepalived start Starting keepalived: [ OK ]
(5)、查看VI_1实例中,流动IP:192.168.60.78 是否流动到haproxy1.9527du.com节点,
[root@haproxy ~]# hostname; ip add show eth0 | grep "[[:space:]]*inet[[:space:]]" haproxy.9527du.com inet 192.168.60.22/24 brd 192.168.60.255 scope global eth0 inet 192.168.60.78/32 scope global eth0
说明:
从上述结果,看得出,在VI_3实例,主节点已经获取到配置VIP的权限。
也可以查看日志
[root@haproxy ~]# tail /var/log/messages ep 21 14:10:57 haproxy Keepalived_vrrp[4034]: VRRP_Instance(VI_1) Transition to MASTER STATE -----> 该节点向外通告自己的优先级 Sep 21 14:10:58 haproxy Keepalived_vrrp[4034]: VRRP_Instance(VI_1) Entering MASTER STATE -----> 该节点处于 MASTER状态 Sep 21 14:10:58 haproxy Keepalived_vrrp[4034]: VRRP_Instance(VI_1) setting protocol VIPs. ----> 配置VIP Sep 21 14:10:58 haproxy Keepalived_vrrp[4034]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.60.78 ---> 向外发送ARP广播 Sep 21 14:10:58 haproxy Keepalived_healthcheckers[4033]: Netlink reflector reports IP 192.168.60.78 added Sep 21 14:10:58 127.0.0.1 haproxy[4052]: Proxy main started. Sep 21 14:10:58 127.0.0.1 haproxy[4052]: Proxy webservers started. Sep 21 14:10:58 127.0.0.1 haproxy[4052]: Proxy updataserver started. Sep 21 14:11:03 haproxy Keepalived_vrrp[4034]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.60.78
(6)、查看haproxy服务
[root@haproxy ~]# netstat -anptl | grep haproxy tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 4053/haproxy
(7)、查看另一台主机
[root@haproxy ~]# ssh 192.168.60.128 'hostname; netstat -anptl | grep haproxy' haproxy2.9527du.com tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2035/haproxy tcp 0 1 172.16.13.1:38386 172.16.0.99:80 SYN_SENT 2035/haproxy tcp 0 1 172.16.13.1:43858 172.16.0.88:80 SYN_SENT 2035/haproxy tcp 0 1 172.16.13.1:38387 172.16.0.99:80 SYN_SENT 2035/haproxy
4、再进行测试
(1)、关闭server2.9527du.com(192.168.60.128)的keepalived服务器查看VI_3实例的:VIP,192.168.60.55 是否流动过来
关闭keepalived服务
[root@haproxy ~]# ssh 192.168.60.128 'hostname;service keepalived stop' haproxy2.9527du.com Stopping keepalived: [ OK ]
查看实例VI_3的VIP是否配置上
[root@haproxy ~]# ip add show eth0 | grep "[[:space:]]*inet[[:space:]]" inet 192.168.60.22/24 brd 192.168.60.255 scope global eth0 inet 192.168.60.78/32 scope global eth0 inet 192.168.60.55/32 scope global eth0
查看是否影响当前主机的haproxy服务
[root@haproxy ~]# netstat -anplt | grep haproxy tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2193/haproxy tcp 0 1 172.16.0.2:50880 172.16.0.99:80 SYN_SENT 2193/haproxy tcp 0 1 172.16.0.2:50879 172.16.0.99:80 SYN_SENT 2193/haproxy
(2)、启动;server2.9527du.com(192.168.60.22)的keepalived服务器,关闭server1.9527du.com的keepalived服务,查看VI_1实例的VIP:192.168.60.78 是否流动过来
[root@haproxy2 ~]# service keepalived start Staring keepalived: [ ok ]
停止haproxy.9527du.com的keepalived服务。
[root@haproxy2 ~]# ssh 192.168.60.22 'hostname;service keepalived stop' haproxy.9527du.com Stopping keepalived: [ OK ]
查看实例VI_1的VIP是不流动过来
[root@haproxy2 ~]# ip add show eth0 | grep "[[:space:]]*inet[[:space:]]" inet 192.168.60.128/24 brd 192.168.60.255 scope global eth0 inet 192.168.60.55/32 scope global eth0 inet 192.168.60.78/32 scope global eth0
查看是否影响当前节点的haproxy服务
[root@haproxy2 ~]# netstat -anptl | grep haproxy tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2035/haproxy tcp 0 1 172.16.13.1:38519 172.16.0.99:80 SYN_SENT 2035/haproxy tcp 0 1 172.16.13.1:38520 172.16.0.99:80 SYN_SENT 2035/haproxy tcp 0 1 172.16.13.1:43991 172.16.0.88:80 SYN_SENT 2035/haproxy
说明:
两个流动VIP已经能够随着节点的状态转变在两个节点流动。
5、启动haproxy.9527.com节点后,查看两个节点的VIP以及haproxy服务。
[root@haproxy2 ~]# ssh 192.168.60.22 'hostname;service keepalived start;ip add show eth0 | grep "[[:space:]]*inet[[:space:]]";netstat -anptl | grep haproxy' haproxy.9527du.com inet 192.168.60.22/24 brd 192.168.60.255 scope global eth0 inet 192.168.60.78/32 scope global eth0 tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2193/haproxy tcp 0 1 172.16.0.2:51197 172.16.0.99:80 SYN_SENT 2193/haproxy tcp 0 1 172.16.0.2:51196 172.16.0.99:80 SYN_SENT 2193/haproxy
[root@haproxy2 ~]# hostname;ip add show eth0 | grep "[[:space:]]*inet[[:space:]]";netstat -anptl | grep haproxy haproxy2.9527du.com inet 192.168.60.128/24 brd 192.168.60.255 scope global eth0 inet 192.168.60.55/32 scope global eth0 tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2035/haproxy tcp 0 1 172.16.13.1:38728 172.16.0.99:80 SYN_SENT 2035/haproxy tcp 0 1 172.16.13.1:44200 172.16.0.88:80 SYN_SENT 2035/haproxy tcp 0 1 172.16.13.1:38729 172.16.0.99:80 SYN_SENT 2035/haproxy
说明:
基于keepalived 实现haproxy的双主高可用已经搭建成功。
六、前端使用 LVS 的nat工作模型负载均衡两台haproxy服务器。
1、为lvs的nat工作模型提供条件
(1)、开启lvs所在服务器的ip地址转发功能。
[root@lvs network-scripts]# echo 1 > /proc/sys/net/ipv4/ip_forward
(2)、在后端各个RealServer设置默认网关,把响应的数据报文送达Director,由lvs进行源地址转换后发送给客户端。
在haproxy.9527du.com主机设置默认网关。
[root@haproxy ~]# route add default gw 192.168.60.99 [root@haproxy ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.60.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 172.16.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth1 169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0 0.0.0.0 192.168.60.99 0.0.0.0 UG 0 0 0 eth0
在haproxy2.9527du.com主机设置默认网关
[root@haproxy2 ~]# route add default gw 192.168.60.99 [root@haproxy2 ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.60.0 0.0.0.0 255.255.255.0 U 1 0 0 eth0 172.16.0.0 0.0.0.0 255.255.0.0 U 1 0 0 eth1 0.0.0.0 192.168.60.99 0.0.0.0 UG 0 0 0 eth0 0.0.0.0 172.16.0.1 0.0.0.0 UG 0 0 0 eth
2、在Diector配置LVS规则
添加集群服务
[root@lvs /]# ipvsadm -A -t 10.10.60.22:80 -s wlc
向集群服务添加RealServer
[root@lvs /]# ipvsadm -a -t 10.10.60.22:80 -r 192.168.60.78:80 -m -w 1 [root@lvs /]# ipvsadm -a -t 10.10.60.22:80 -r 192.168.60.55:80 -m -w 1
查看配置的lvs规则
[root@lvs /]# ipvsadm -L -n IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.10.60.22:80 wlc -> 192.168.60.55:80 Masq 1 0 0 -> 192.168.60.78:80 Masq 1 0 0
3、访问测试:
关闭haproxy.9527du.com这台主机的keepalive服务。
[root@haproxy ~]# service keepalived stop Stopping keepalived: [ OK ]
在haproxy2.9527du.com查看是否有两个VIP接收LVS转发过来的请求。
[root@haproxy2 ~]# netstat -anpt | grep "\<80\>" tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 10114/haproxy tcp 0 0 192.168.60.78:80 10.10.60.1:62593 ESTABLISHED 10114/haproxy tcp 0 0 192.168.60.55:80 10.10.60.1:62590 ESTABLISHED 10114/haproxy tcp 0 0 192.168.60.78:80 10.10.60.1:62599 ESTABLISHED 10114/haproxy tcp 0 0 192.168.60.55:80 10.10.60.1:62597 ESTABLISHED 10114/haproxy tcp 0 0 192.168.60.78:80 10.10.60.1:62592 ESTABLISHED 10114/haproxy tcp 0 0 192.168.60.55:80 10.10.60.1:62598 ESTABLISHED 10114/haproxy
说明:
VI_1实例的VIP: 192.168.60.78 已经配置在haproxy2.9527du.com节点上,且接收LVS调度过来的请求了。
启动 haproxy.9527du.com 这台主机的keepalived服务.
[root@haproxy ~]# service keepalived start Starting keepalived: [ OK ]
查看VI_3实例的VIP是否在,haproxy2.9527du.com接收lvs调度的请求了。
[root@haproxy2 ~]# netstat -anpt | grep "\<80\>" tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 10114/haproxy tcp 0 0 192.168.60.55:80 10.10.60.1:62729 ESTABLISHED 10114/haproxy tcp 0 0 192.168.60.55:80 10.10.60.1:62727 ESTABLISHED 10114/haproxy tcp 0 0 192.168.60.55:80 10.10.60.1:62645 TIME_WAIT - tcp 0 0 192.168.60.55:80 10.10.60.1:62724 ESTABLISHED 10114/haproxy
查看VI_1实例的VIP是否在,haproxy1.9527du.com接收lvs调度的请求了。
[root@haproxy ~]# netstat -anpt | grep "\<80\>" tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 4187/haproxy tcp 0 0 192.168.60.78:80 10.10.60.1:62646 TIME_WAIT - tcp 0 0 192.168.60.78:80 10.10.60.1:62725 ESTABLISHED 4187/haproxy tcp 0 0 192.168.60.78:80 10.10.60.1:62648 TIME_WAIT - tcp 0 0 192.168.60.78:80 10.10.60.1:62726 ESTABLISHED 4187/haproxy tcp 0 0 192.168.60.78:80 10.10.60.1:62650 TIME_WAIT - tcp 0 0 192.168.60.78:80 10.10.60.1:62647 TIME_WAIT - tcp 0 0 192.168.60.78:80 10.10.60.1:62728 ESTABLISHED 4187/haproxy tcp 0 0 192.168.60.78:80 10.10.60.1:62649 TIME_WAIT -
说明:
从上述结果,可以看出keepalived的双主模型已经正常工作;
lvs也能够调度前端的用户请求到不同的RealServer.
访问测试:
到此为止,二层高度Discuz!论坛已经成功!!