實現兩級調度 Discuz! 論壇服務器

1、一級調度器;

   選擇使用工作在四層的LVS。因爲它工作在內核空間。它的調度效率要比七層調度器高几百倍。

它直接面向用戶的請求。

2、二級調度器;

  選擇使用工作在七層的:haproxy。因爲它工作在七層,能夠識別用戶請求的資源是什麼,方便做訪問控制。

如:

  根據用戶請求的資源類別做動靜分離。請求動態內容由動態服務器響應,靜態資源由靜態服務器響應。這樣大大提高動態服務器處理動態內容的效率。

  當用戶上傳數據時,把用戶的請求調度到專門服務用戶上傳數據的服務器組。

拓撲圖如下:

wKioL1QgC5vBHpdKAANrP7Ce8QM043.jpg

地址使用情況如下:

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!進入安裝引導頁面,進行安裝操作

如圖:

wKiom1QgFCqQNxaLAARgjuG5OFM814.jpg下一步:

wKiom1QgFE7iUwquAAJAxlxEIVE710.jpg

下一步:

wKioL1QgFKGA-NzwAAHsNDAr7xo294.jpg

下一步:

wKioL1QgFLuzqqIAAAL3Xnq9w5o534.jpg

安裝完成:

wKiom1QgFM-y5mxkAAFUgFskBG8712.jpg


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!論壇程序,查看是否能夠正常工作。

如下圖:

wKiom1QgFYbTfQ3NAAGoSeHOS8U222.jpg

說明:

    該臺服務器已經能夠正常工作了!!!!

四、配置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  ]

上傳附件時候出現錯誤如圖:

wKioL1QgGEPhuMBGAAShRD982Uw872.jpg

啓動上傳服務器,查看是否能夠上傳成功

[root@haproxy ~]# ssh 172.16.0.99 'service httpd start'
[email protected]'s password:
Starting httpd: [  OK  ]

如下圖:

wKioL1QgGICTv9BXAATWKkVYt38368.jpg

wKioL1QgGNKRU_XVAANnLo2DH4c193.jpg

從上圖可以看出,當用戶使用,上傳附件或圖片時,已經能夠,把用戶請求路由至指定服務器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

如圖:

wKiom1QgGbDidLPTAAZOIsV7IHo229.jpg再次刷新訪問

wKioL1QgGhKQmwB7AAYfxdirqg0174.jpg

五、爲了避免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.

訪問測試:

wKiom1QgHbehxXRqAAM_BH5t7aM681.jpg一直刷新查看LVS的調度情況

wKioL1QgHgHidmLmAAKCEMvNlCE303.jpg

到此爲止,二層高度Discuz!論壇已經成功!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章