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 <?php $link = mysql_connect('172.16.0.44','discuz','discuz'); if ($link) echo "Success..."; ------> 如果能夠連接數據庫就會輸出: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" <Directory "/data/upload"> Options -Indexes FollowSymLinks AllowOverride None Order allow,deny Allow from all </Directory>
(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" <Directory "/web/upload"> Options -Indexes FollowSymLinks AllowOverride None Order allow,deny Allow from all </Directory>
(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 "\<POST\>" | 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 "\<POST\>" | 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!論壇已經成功!!