php 云计算 程序员 Firefox Ubuntu nginx google 微软 wordpress Android Python shell 开源 apache java centos 编程 Windows mysql linux

搭建一個高可用負載均衡的集群架構

用15臺虛擬機搭建一個高可用負載均衡集群架構出來,並運行三個站點,具體需求如下。

1 設計你認為合理的架構,用visio把架構圖畫出來

2 搭建lnmp、tomcat+jdk環境

3 三個站點分別為:discuz論壇、dedecms企業網站以及zrlog博客

4 由於機器有限,盡可能地把三個站點放到同一臺服務器上,然後做負載均衡集群,要求所有站點域名解析到一個ip上,也就是說只有一個出口ip

5 需要共享靜態文件,比如discuz需要共享的目錄是 data/attachment,dedecms需要共享upload(具體目錄,你可以先上傳一個圖片,查看圖片所在目錄)

6 設計合理的目錄、文件權限,比如discuz的data目錄需要給PHP-fpm進程用戶可寫權限,其他目錄不用寫的就不要給寫權限(目錄755,文件644,屬主屬組root)

7 所有服務器要求只能普通用戶登錄,而且只能密鑰登錄,root只能普通用戶sudo

8 給所有服務器做一個簡單的命令審計功能

9 php-fpm服務要求設置慢執行日誌,超時時間為2s,並做日誌切割,日誌保留一月

10 所有站點都需要配置訪問日誌,並做日誌切割,要求靜態文件日誌不做記錄,日誌保留一月

11 制定合理的mysql數據備份方案,並寫備份腳本,要求把備份數據傳輸到備份服務器

12 制定代碼、靜態文件的備份方案,並寫備份腳本,要求把備份

12 編寫數據恢復文檔,能保證當數據丟失在2小時內恢復所有數據

13 搭建zabbix監控告警系統,要求監控各個基礎指標(cpu、內存、硬盤),網卡流量需要成圖,還需要監控web站點的可用性,

14 定制自定義監控腳本,監控web服務器的並發連接數,超過100告警

15 定制自定義監控腳本,監控mysql的隊列,隊列超過300告警

16 定制自定義監控腳本,監控mysql的慢查詢日誌,每分鐘超過60條日誌需要告警,需要仔細分析慢查詢日誌的規律,確定日誌條數

17 給三個站點的後臺訪問做二次認證,增加安全性

18 用Shell腳本實現文件、代碼同步上線(參考分發系統)

分析需求將需求分成幾個部分去完成

屬於第一部分的需求:

1 設計你認為合理的架構,用visio把架構圖畫出來

2 搭建lnmp、tomcat+jdk環境

3 三個站點分別為:discuz論壇、dedecms企業網站以及zrlog博客

4 由於機器有限,盡可能地把三個站點放到同一臺服務器上,然後做負載均衡集群,要求所有站點域名解析到一個ip上,也就是說只有一個出口ip

5 需要共享靜態文件,比如discuz需要共享的目錄是 data/attachment,dedecms需要共享upload(具體目錄,你可以先上傳一個圖片,查看圖片所在目錄)

6 設計合理的目錄、文件權限,比如discuz的data目錄需要給php-fpm進程用戶可寫權限,其他目錄不用寫的就不要給寫權限(目錄755,文件644,屬主屬組root)

18 給三個站點的後臺訪問做二次認證,增加安全性

屬於第二部分的需求:

14 搭建zabbix監控告警系統,要求監控各個基礎指標(cpu、內存、硬盤),網卡流量需要成圖,還需要監控web站點的可用性,

15 定制自定義監控腳本,監控web服務器的並發連接數,超過100告警

16 定制自定義監控腳本,監控mysql的隊列,隊列超過300告警

17 定制自定義監控腳本,監控mysql的慢查詢日誌,每分鐘超過60條日誌需要告警,需要仔細分析慢查詢日誌的規律,確定日誌條數

8 給所有服務器做一個簡單的命令審計功能

9 php-fpm服務要求設置慢執行日誌,超時時間為2s,並做日誌切割,日誌保留一月

10 所有站點都需要配置訪問日誌,並做日誌切割,要求靜態文件日誌不做記錄,日誌保留一月

屬於第三部分的需求:

11 制定合理的mysql數據備份方案,並寫備份腳本,要求把備份數據傳輸到備份服務器

12 制定代碼、靜態文件的備份方案,並寫備份腳本,要求備份

13 編寫數據恢復文檔,能保證當數據丟失在2小時內恢復所有數據

19 用shell腳本實現文件、代碼同步上線(參考分發系統)

7 所有服務器要求只能普通用戶登錄,而且只能密鑰登錄,root只能普通用戶sudo

完成第一部分需求


一、集群环境搭建

设计你认为合理的架构,用visio把架构图画出来
搭建一个高可用负载均衡的集群架构(第一部分)

实现:

1.分配机器:拿出两台作为负载均衡(dir角色),拿出三台作为数据库服务器,一台作为备份+读写分离调度服务器,剩下的作为web服务器(Real Server),然后再拿其中一台做zabbix服务器:

192.168.200.146
192.168.200.147
192.168.200.148
192.168.200.149
192.168.200.150
192.168.200.151
192.168.200.152
192.168.200.153
192.168.200.154
192.168.200.155
192.168.200.156
192.168.200.157
192.168.200.158
192.168.200.159
192.168.200.160

分配完成:

mysql服务器:
192.168.200.146   Master
192.168.200.147   Slave1
192.168.200.148   Slave2

Mycat读写分离调度器+备份服务器
192.168.200.149

负载均衡服务器:
192.168.200.150  dir
192.168.200.151  load dir

Web+Real服务器:
192.168.200.152  == zabbix + NFS服务器
192.168.200.153
192.168.200.154
192.168.200.155
192.168.200.156
192.168.200.157
192.168.200.158
192.168.200.159
192.168.200.160

因为拿到机器后有一个简单的初始密码,所以需要使用脚本批量修改密码,expect脚本如下:

[root@localhost ~]# vim mvPasswd.expect
#!/usr/bin/expect
set host [lindex $argv 0]
set passwd "root"
set password [lindex $argv 1]
spawn ssh root@$host
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}

expect "]*"
send "passwd\r"
expect ":"
send "$password\r"
expect ":"
send "$password\r"
expect "]*"
send "exit\r"

interact

[root@localhost ~]# chmod a+x mvPasswd.expect

shell调用脚本如下:

[root@localhost ~]# vim mvPasswd.sh
#!/bin/bash
for ip in `cat $1`
do
  ./mvPasswd.expect $ip $2
done

# 第一个参数存储ip列表的文件,第二个参数是需要修改的密码
[root@localhost ~]# sh mvPasswd.sh /root/ip.txt "lri35krJF;ba"   

然后再写一个通用的可以批量远程执行命令的expect脚本:

[root@localhost ~]# vim cmd.expect
#!/usr/bin/expect
set user [lindex $argv 0]  # 系统用户
set host [lindex $argv 1]  # 服务器地址
set passwd [lindex $argv 2]  # 密码
set cm [lindex $argv 3]  # 需要执行的命令
spawn ssh $user@$host
set timeout -1
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}

expect "]#"
send "$cm\r"
expect "]#"
send "exit\r"
interact

[root@localhost ~]# chmod a+x cmd.expect
[root@localhost ~]# vim cmd.sh  # 调用脚本
#!/bin/bash
user=$2
password=$3
cm=$4
for ip in `cat $1`
do
  ./cmd.expect "$user" "$ip" "$password" "$cm"
done

## 参数1是存储ip列表的文件路径
## 参数2是用户名
## 参数3是密码
## 参数4需要执行的命令

# 使用这个脚本批量安装一些基础通用的工具
[root@localhost ~]# sh ./cmd.sh "/root/ipAll.txt" "root" "lri35krJF;ba" "yum -y install expect vim-enhanced epel-release libmcrypt-devel libmcrypt"

2.分配好机器后,编写脚本配置所有机器的防火墙规则:


脚本使用批量执行命令的脚本即可,批量执行一下开放端口的命令:

# MySQL端口:
[root@localhost ~]# sh ./cmd.sh "/root/DBServerIP.txt" "root" "lri35krJF;ba" "firewall-add-port=3306/tcp --permanent"

# web端口:
[root@localhost ~]# sh ./cmd.sh "/root/WebServerIP.txt" "root" "lri35krJF;ba" "firewall-cmd --zone=public --add-port=80/tcp --permanent; firewall-cmd --zone=public --add-port=8080/tcp --permanent"

# NFS端口,客户端和服务端都需要监听:
[root@localhost ~]# sh ./cmd.sh "/root/ipAll.txt" "root" "lri35krJF;ba" "firewall-cmd --zone=public --add-port=111/tcp --permanent"

# zabbix端口:
[root@localhost ~]# sh ./cmd.sh "/root/ipAll.txt" "root" "lri35krJF;ba" "firewall-cmd --zone=public --add-port=10050/tcp --permanent"   # 客户端
[root@localhost ~]# sh ./cmd.sh "/root/zabixIP.txt" "root" "lri35krJF;ba" "firewall-cmd --zone=public --add-port=10051/tcp --permanent"  # 服务端

Mycat端口:
[root@localhost ~]# sh ./cmd.sh "/root/MycatIP.txt" "root" "lri35krJF;ba" "firewall-cmd --zone=public --add-port=8066/tcp --permanent; firewall-cmd --zone=public --add-port=9066/tcp --permanent"

# 重启firewall服务:
[root@localhost ~]# sh ./cmd.sh "/root/ipAll.txt" "root" "lri35krJF;ba" "systemctl stop firewalld.service; systemctl start firewalld.service"

3.数据库服务器安装MySQL,并配置主从复制(从库作为备份服务器)


安装mysql: 通过之前写的批量执行命令脚本安装mysql:

[root@localhost ~]# sh ./cmd.sh "/root/DBServerIP.txt" "root" "lri35krJF;ba" "cd /usr/local/src/; yum install -y epel-release wget perl-Module-Install.noarch libaio*; wget http://mirrors.sohu.com/mysql/MySQL-5.6/mysql-5.6.35-Linux-glibc2.5-x86_64.tar.gz; tar -zxvf mysql-5.6.35-linux-glibc2.5-x86_64.tar.gz; mv mysql-5.6.35-linux-glibc2.5-x86_64 ../mysql; cd /usr/local/mysql; mkdir /data/; useradd mysql; ./scripts/mysql_install_db --user=mysql --datadir=/data/mysql; echo $? > /root/downloadMySQL.log"

安装完之后先配置其中一台的配置文件,然后使用rsync同步到其他的机器上:

# 拷贝配置文件
[root@localhost ~]# cp /usr/local/mysql/support-files/my-default.cnf  /etc/my.cnf
[root@localhost ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/tmp/mysql.sock

# 拷贝启动脚本
[root@localhost ~]# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld

# 然后定义basedir和datadir的路径
[root@localhost ~]# vim /etc/init.d/mysqld
basedir=/usr/local/mysql
datadir=/data/mysql

# 将mysql加入服务列表里面去,并设置为开机启动:
[root@localhost ~]# chkconfig --add mysqld
[root@localhost ~]# chkconfig mysqld on

编写同步文件的expect脚本:

#!/usr/bin/expect

set host [lindex $argv 0]
set passwd [lindex $argv 1]
set file [lindex $argv 2]

spawn rsync -avR --files-from=$file / root@$host:/
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}

expect eof

调用脚本:

#!/bin/bash
passwd=$2
file=$3
for ip in `cat $1`
do
    ./sync.expect $ip $passwd $file
done

## 使用方式:##
## sh sync.sh "ip列表文件" "密码" "文件列表路径" ##

[root@localhost ~]$ sh ./sync.sh "/root/slaveIP.txt" "lri35krJF;ba" "/tmp/DBfile.txt"  # 同步配置文件
[root@localhost ~]$ sh ./cmd.sh "/root/slaveIP.txt" "root" "lri35krJF;ba" "/etc/init.d/mysqld start; chkconfig --add mysqld; chkconfig mysqld on"   # 启动服务并且将服务添加到服务列表里
[root@localhost ~]$ sh ./cmd.sh "/root/slaveIP.txt" "root" "lri35krJF;ba" "ln -s /usr/local/mysql/bin/mysql /usr/bin/mysql"  # 制作软链接到/usr/bin/目录下

错误解决:

如果出现密码明明是正确的但是却无法登陆报错的情况:

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

这是因为MySQL中默认存在一个用户名为空的账户,只要在本地,可以不用输入账号密码即可登录到MySQL中。mysql在验证用户登陆的时候,首先是验证host列,如果host列在验证user列,再password列,而现在按照我之前的连接语句:按照host列找到为空的那列(空匹配所有用户名),所以匹配到了这条记录,然后发现这条记录的密码为空,而我的语句里面有密码,那么就会报错。

解决办法:删除匿名用户:
首先修改my.cnf,增加以下语句跳过密码验证:

skip-grant-tables

然后登录root用户,执行以下语句删除匿名用户:

mysql> use mysql;
mysql> delete from user where user='';
Query OK, 2 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

然后重启mysql服务就可以正常登陆用户了:

[root@localhost ~]$ mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.

全部机器都安装好mysql后开始配置主从:

登录mysql,修改root用户密码:

[root@localhost ~]$ mysql -uroot
mysql> set password=password('123456');
[root@localhost ~]$ sh ./cmd.sh "/root/DBServerIP.txt" "root" "lri35krJF;ba" "service mysqld restart"

批量重启的时候遇到一个错误,/etc/init.d目录下没有functions文件,然后我从其他机器同步这个functions文件过来就解决了。

完成密码的修改和重启mysql服务器后,先配置主机器:
1.修改my.cnf配置文件:

[root@localhost ~]$ vim /etc/my.cnf
[mysqld]
server-id=146
log_bin=master-bin
[root@localhost ~]$ service mysqld restart  # 修改完配置文件后,重启mysqld服务
[root@localhost ~]$ ls /data/mysql  # 看看是否多了以下两个文件
master-bin.000001  master-bin.index

2.登录master上的mysql,为两台slave添加一个同步账号:

grant replication slave on *.* to 'repl'@'192.168.200.147' identified by '123456';
grant replication slave on *.* to 'repl'@'192.168.200.148' identified by '123456';

3.在两台slave上登录这个用户,看看是否能够成功登录,我这里是能够成功登录的:

mysql -urepl -h"192.168.200.146" -p'123456'

4.回到master机器上,进行锁表:

flush tables with read lock;

5.看一下master的状态,并记录:

mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 |      120 |              |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql>

完成以上master上的操作后,开始配置slave机器:
1.同样的从上也要修改my.cnf配置文件,只不过在从上只需要增加一个server-id即可,改完之后都要重启服务:

# slave1
[root@localhost ~]$ vim /etc/my.cnf
[mysqld]
server-id=147
[root@localhost ~]$ service mysqld restart

# slave2
[root@localhost ~]$ vim /etc/my.cnf
[mysqld]
server-id=148
[root@localhost ~]$ service mysqld restart

2.登录两台slave的mysql的root用户,分别执行以下命令:

 # slave1
 [root@localhost ~]$ mysql -uroot -p'123456'
 mysql> stop slave;
 mysql> change master to master_host='192.168.200.146', master_user='repl', master_password='123456', master_log_file='master-bin.000001', master_log_pos=120;
 mysql> start slave;

# slave2
[root@localhost ~]$ mysql -uroot -p'123456'
mysql> stop slave;
mysql> change master to master_host='192.168.200.146', master_user='repl', master_password='123456', masterr_log_file='master-bin.000001', master_log_pos=120;
mysql> start slave;

3.查看两台slave的主从状态是否正常,Slave_IO_Running和 Slave_SQL_Running要为yes:

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.200.146
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.000002
          Read_Master_Log_Pos: 120
               Relay_Log_File: localhost-relay-bin.000003
                Relay_Log_Pos: 284
        Relay_Master_Log_File: master-bin.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 120
              Relay_Log_Space: 1049
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 146
                  Master_UUID: 0bf106ef-e06a-11e7-8f8f-005056b31904
             Master_Info_File: /data/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0

4.回到master机器上解锁表,并执行一些sql语句,看看是否能够同步到slave机器上:

# master
mysql> unlock tables;
mysql> create database blog; # 创建一个数据库
mysql> use blog;
mysql> create table users( uid int primary key, uname varchar(100), sex varchar(5));
mysql> insert into users(uid,uname,sex) values(1,'Jon','man');

5.到slave上看看是否同步了数据:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| blog               |
| mysql              |
| performance_schema |
| test               |
+--------------------+
5 rows in set (0.00 sec)

mysql> use blog;
mysql> select * from users;
+-----+-------+------+
| uid | uname | sex  |
+-----+-------+------+
|   1 | Jon   | man  |
+-----+-------+------+
1 row in set (0.00 sec)

mysql>

可以看到从上已经同步了刚刚我在主上创建的数据库和插入的数据,这样就没问题了。

搭建Mycat服务器


主从搭建完成之后就可以搭建Mycat服务器实现读写分离了,因为Mycat是JAVA开发的,所以在安装Mycat之前得先安装好jdk环境。
1.下载并安装JDK:
jdk的下载地址要临时去官网获取,官网下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

下载到/usr/local/src目录下:

[root@localhost ~]$ cd /usr/local/src/
[root@localhost /usr/local/src]$ wget http://download.oracle.com/otn-pub/java/jdk/8u151-b12/e758a0de34e24606bca991d704f6dcbf/jdk-8u151-linux-x64.tar.gz?AuthParam=1513225205_78307ff96990fb6fae700bf92ace7867
[root@localhost /usr/local/src]$ tar -zxvf jdk-8u151-linux-x64.tar.gz\?AuthParam\=1513225205_78307ff96990fb6fae700bf92ace7867
[root@localhost /usr/local/src]$ mv jdk1.8.0_151/ /usr/local/jdk1.8

编辑/etc/profile环境变量配置文件加入以下内容:

JAVA_HOME=/usr/local/jdk1.8/    //JDK的主目录
JAVA_BIN=/usr/local/jdk1.8/bin  //JDK的主目录下的bin目录
JRE_HOME=/usr/local/jdk1.8/jre  //JDK的主目录下的jre目录
PATH=$PATH:/usr/local/jdk1.8/bin:/usr/local/jdk1.8/jre/bin  //添加JDK的bin目录和jre的bin目录到PATH中
CLASSPATH=/usr/local/jdk1.8/jre/lib:/usr/local/jdk1.8/lib:/usr/local/jdk1.8/jre/lib/charsets.jar  //Java类文件的路径

加载/etc/profile配置文件:

source /etc/profile

查看java版本,看看java环境是否搭建成功:

[root@localhost ~]$ java -version
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)

# 然后执行以下命令,看看是否有相应的输出,有则代表没问题
[root@localhost ~]$ java
[root@localhost ~]$ javac

2.下载安装Mycat:
下载地址:http://dl.mycat.io/1.6-RELEASE/
1.下载并解压到/usr/local目录下:

[root@localhost ~]$ cd /usr/local/src/
[root@localhost /usr/local/src]$ wget http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
[root@localhost /usr/local/src]$ tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
[root@localhost /usr/local/src]$ mv mycat/ /usr/local/
[root@localhost /usr/local/src]$ ls /usr/local/mycat/
bin  catlet  conf  lib  logs  version.txt

2.修改Mycat服务器参数调整和用户授权的配置文件server.xml。主要修改配置段如下:

[root@localhost ~]$ vim /usr/local/mycat/conf/server.xml
        # root用户对逻辑数据库ultrax,DedeCMS,zrlog具有增删改查的权限
        <user name="root">
                <property name="password">123456</property>
                <property name="schemas">ultrax,DedeCMS,zrlog</property>
        </user>

        # discuz用户对逻辑数据库ultrax具有增删改查的权限
        <user name="discuz">
                <property name="password">123456</property>
                <property name="schemas">ultrax</property>
        </user>

        # dedecms用户对逻辑数据库DedeCMS具有增删改查的权限
        <user name="dedecms">
                <property name="password">123456</property>
                <property name="schemas">DedeCMS</property>
        </user>

        # zrlog用户对逻辑数据库zrlog具有增删改查的权限
        <user name="zrlog">
                <property name="password">123456</property>
                <property name="schemas">zrlog</property>
        </user>

        # 该用户对逻辑数据库ultrax,DedeCMS,zrlog仅有只读的权限
        <user name="user">
                <property name="password">123456</property>
                <property name="schemas">ultrax,DedeCMS,zrlog</property>
                <property name="readonly">true</property>
        </user>

# 创建以上这些用户是用于连接mycat中间件。

3.修改逻辑库定义和表及分片定义的配置文件schema.xml:

# 把自带的配置文件重命名,作为备份
[root@localhost ~]$ mv /usr/local/mycat/conf/schema.xml /usr/local/mycat/conf/schema.xml_bak

# 新建配置文件
[root@localhost ~]$ vim /usr/local/mycat/conf/schema.xml

# 配置内容如下:
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
        <schema name="ultrax" checkSQLschema="false" sqlMaxLimit="1000" dataNode="dn1" />
        <schema name="DedeCMS" checkSQLschema="false" sqlMaxLimit="1000" dataNode="dn2" />
        <schema name="zrlog" checkSQLschema="false" sqlMaxLimit="1000" dataNode="dn3" />

        <dataNode name="dn1" dataHost="localhost1" database="ultrax" />
        <dataNode name="dn2" dataHost="localhost1" database="DedeCMS" />
        <dataNode name="dn3" dataHost="localhost1" database="zrlog" />
        <dataHost name="localhost1" maxCon="2000" minCon="1" balance="3"
                          writeType="1" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
            <heartbeat>select user()</heartbeat>

            <writeHost host="hostM1" url="192.168.200.146:3306" user="root" password="123456">
                  <!-- can have multi read hosts -->
                  <readHost host="hostS1" url="192.168.200.147:3306" user="root" password="123456" />
                  <readHost host="hostS2" url="192.168.200.148:3306" user="root" password="123456" />
            </writeHost>
        </dataHost>
</mycat:schema>

修改完成后如下图:
搭建一个高可用负载均衡的集群架构(第一部分)

schema.xml配置文件详解:

<?xml version="1.0"?>   xml文件格式;
<!DOCTYPE mycat:schema SYSTEM "schema.dtd"> 文件标签属性;
<mycat:schema xmlns:mycat="http://io.mycat/">  Mycat起始标签

配置逻辑库,与server.xml指定库名保持一致,绑定数据节点dn1;
<schema name="testdb" checkSQLschema="false" sqlMaxLimit="1000" dataNode="dn1"></schema> 

 添加数据节点dn1,设置数据节点host名称,同时设置数据节点真实database为discuz;
 <dataNode name="dn1" dataHost="localhost1" database="discuz" />

 数据节点主机,绑定数据节点,设置连接数及均衡方式、切换方法、驱动程序、连接方法; 
 <dataHost name="localhost1" maxCon="2000" minCon="1" balance="3" writeType="1" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">

Balance均衡策略设置:
1)  balance=0  不开启读写分离机制,所有读操作都发送到当前可用writehost;
2)  balance=1  全部的readHost与stand by writeHost参与select语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且M1与 M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡
3)  balance=2  所有读操作都随机的在readhost和writehost上分发;
4)  balance=3  所有读请求随机的分发到wiriterHost对应的readhost执行,writerHost不负担读压力。
writeType 写入策略设置
1)  writeType=0, 所有写操作发送到配置的第一个writeHost;
2)  writeType=1,所有写操作都随机的发送到配置的writeHost;
3)  writeType=2,不执行写操作。
switchType 策略设置
1)  switchType=-1,表示不自动切换;
2)  switchType=1,默认值,自动切换;
3)  switchType=2,基于MySQL 主从同步的状态决定是否切换;
4)  switchType=3,基于MySQL galary cluster的切换机制(适合集群)(1.4.1),心跳语句为 show status like 'wsrep%'。

检测后端MYSQL实例,SQL语句;
<heartbeat>select  user()</heartbeat>

指定读写请求,同时转发至后端MYSQL真实服务器,配置连接后端MYSQL用户名和密码(该用户名和密码为MYSQL数据库用户名和密码);
<writeHost host="hostM1" url="192.168.200.146:3306" user="root"  password="123456">
     <readHost host="hostS1" url="192.168.200.147:3306" user="root" password="123456" />
     <readHost host="hostS2" url="192.168.200.148:3306" user="root" password="123456" />
</writeHost>

</dataHost>    数据主机标签;
</mycat:schema>  mycat结束标签;

mycat配置完毕。启动mycat并查看端口8066和9066端口是否起来:

[root@localhost ~]$ /usr/local/mycat/bin/mycat start
[root@localhost ~]$ netstat -lntp
tcp6       0      0 :::9066                 :::*                    LISTEN      6746/java
tcp6       0      0 :::8066                 :::*                    LISTEN      6746/java

# 注意:如果没有这两个端口没有启动,查看java环境是否生效。
# 8066是用于web连接mycat.
# 9066是用于SA|DBA管理端口. 

回到master上,通过mycat机器的IP和8066端口连接mysql:

[root@localhost ~]$ mysql -h'192.168.200.149' -udiscuz -p'123456' -P'8066'
mysql> show databases;
+----------+
| DATABASE |
+----------+
| ultrax   |
+----------+
1 row in set (0.01 sec)

mysql>

可以正常登陆,也能查看到数据库。

使用root用户登录看看是否能查看到所有的数据库:

[root@localhost ~]$ mysql -h'192.168.200.149' -uroot -p'123456' -P'8066'
mysql> show databases;
+----------+
| DATABASE |
+----------+
| DedeCMS  |
| ultrax   |
| zrlog    |
+----------+
3 rows in set (0.00 sec)

mysql> 

然后以9066端口登陆查看数据源:

mysql> show @@datasource;
+----------+--------+-------+-----------------+------+------+--------+------+------+---------+-----------+------------+
| DATANODE | NAME   | type  | HOST            | PORT | w/R  | ACTIVE | IDLE | SIZE | EXECUTE | READ_LOAD | WRITE_LOAD |
+----------+--------+-------+-----------------+------+------+--------+------+------+---------+-----------+------------+
| dn1      | hostM1 | mysql | 192.168.200.146 | 3306 | W    |      0 |    0 | 2000 |       0 |         0 |          0 |
| dn1      | hostS1 | mysql | 192.168.200.147 | 3306 | R    |      0 |    0 | 2000 |       0 |         0 |          0 |
| dn1      | hostS2 | mysql | 192.168.200.148 | 3306 | R    |      0 |    0 | 2000 |       0 |         0 |          0 |
+----------+--------+-------+-----------------+------+------+--------+------+------+---------+-----------+------------+
3 rows in set (0.00 sec)

mysql>

没问题后,退出mycat中间件,在master上登录mysql,创建这三个数据库:

[root@localhost ~]$ mysql -uroot -p'123456'
mysql> create database ultrax default character set utf8;
mysql> create database DedeCMS default character set utf8;
mysql> create database zrlog default character set utf8;
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| DedeCMS            |
| mysql              |
| performance_schema |
| test               |
| ultrax             |
| zrlog              |
+--------------------+
7 rows in set (0.00 sec)

mysql>

完成以上操作后主从复制和读写分离就弄好了,接下来就是搭建web服务器,然后进行对接即可。

4.剩下的所有服务器先搭建LNMP环境,和Tomcat+Java环境,默认80端口给Nginx,Tomcat使用8080端口。


1.先在一台机器上部署好全部环境,然后通过rsync同步整个环境:

下载并安装Nginx:

[root@localhost ~]$ yum -y install epel-release wget gcc gcc-c++ libmcrypt-devel libmcrypt libcurl-devel libxml2-devel openssl-devel bzip2-devel libjpeg-devel libpng-devel freetype-devel libmcrypt-devel; cd /usr/local/src/; wget http://nginx.org/download/nginx-1.12.1.tar.gz; tar -zxvf nginx-1.12.1.tar.gz; cd nginx-1.12.1; ./configure --prefix=/usr/local/nginx --with-http_ssl_module; echo $? > /root/downloadNginx.log; make && make install; echo $? >> /root/downloadNginx.log

先配置其中一台机器的配置文件:
编辑启动脚本:

vim /etc/init.d/nginx
然后将这网址里的文件内容复制进去:
https://coding.net/u/aminglinux/p/aminglinux-book/git/blob/master/D15Z/etc_init.d_nginx

编辑完成后,给这个启动脚本文件设置755权限:

chmod 755 /etc/init.d/nginx

把nginx服务添加到服务列表,并设置开机启动:

chkconfig --add nginx
chkconfig nginx on

进入nginx的conf目录:

cd /usr/local/nginx/conf

然后重命名一下配置文件:

mv nginx.conf nginx.conf.bak

因为不使用nginx自带的配置文件,所以需要编辑一个配置文件:

vim nginx.conf
将以下网址里的文件内容复制到 nginx.conf 文件里:
https://coding.net/u/aminglinux/p/aminglinux-book/git/blob/master/D15Z/nginx.conf

检查配置文件有没有错误:

/usr/local/nginx/sbin/nginx -t

没有问题就可以启动nginx 了:

service nginx start

查看一下进程:

[root@localhost /usr/local/nginx/conf]$ ps aux |grep nginx
root     11752  0.0  0.1  45880  1144 ?        ss   16:09   0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
nobody   11753  0.0  0.3  48368  3792 ?        S    16:09   0:00 nginx: worker process
nobody   11754  0.0  0.3  48368  3792 ?        S    16:09   0:00 nginx: worker process
root     11756  0.0  0.0 112680   976 pts/0    S+   16:10   0:00 grep --color=auto nginx
[root@localhost /usr/local/nginx/conf]$

检查一下有没有在监听80端口:

[root@localhost /usr/local/nginx/conf]$ netstat -lntp |grep 80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      11752/nginx: master

确认启动成功后,使用curl测试一下是否能访问nginx,输出一堆html代码代表成功:

[root@localhost /usr/local/nginx/conf]$ curl localhost

2.因为jdk安装上面有过程,我这里就不演示了,直接安装Tomcat:
下载、解压、移动:

[root@localhost /usr/local/src]$ wget http://mirrors.shuosc.org/apache/tomcat/tomcat-8/v8.5.24/bin/apache-tomcat-8.5.24.tar.gz
[root@localhost /usr/local/src]$ tar -zxvf apache-tomcat-8.5.24.tar.gz
[root@localhost /usr/local/src]$ mv apache-tomcat-8.5.24 /usr/local/tomcat
[root@localhost /usr/local/src]$ ls !$
ls /usr/local/tomcat
bin  conf  lib  LICENSE  logs  NOTICE  RELEASE-NOTES  RUNNING.txt  temp  webapps  work

启动与关闭服务的命令:

/usr/local/tomcat/bin/startup.sh # 启动服务
/usr/local/tomcat/bin/shutdown.sh # 关闭服务

查看进程与端口:

netstat -lntp
ps aux |grep java

3.安装mysql,这是因为php需要用到mysql的驱动库,所以只需要安装即可,不需要进行配置:

[root@localhost ~]$ cd /usr/local/src/; yum install -y epel-release wget perl-Module-Install.noarch libaio*; wget http://mirrors.sohu.com/mysql/MySQL-5.6/mysql-5.6.35-linux-glibc2.5-x86_64.tar.gz; tar -zxvf mysql-5.6.35-linux-glibc2.5-x86_64.tar.gz; mv mysql-5.6.35-linux-glibc2.5-x86_64 ../mysql; cd /usr/local/mysql; mkdir /data/; useradd mysql; ./scripts/mysql_install_db --user=mysql --datadir=/data/mysql; echo $? > /root/downloadMySQL.log

4.安装PHP:
批量执行命令:

[root@localhost ~]$ cd /usr/local/src/; yum -y install epel-release wget gcc gcc-c++ libmcrypt-devel libmcrypt libcurl-devel libxml2-devel openssl-devel bzip2-devel libjpeg-devel libpng-devel freetype-devel libmcrypt-devel; wget http://cn2.php.net/distributions/php-5.6.30.tar.gz; tar -zxvf php-5.6.30.tar.gz; cd php-5.6.30/; ./configure --prefix=/usr/local/php-fpm --with-config-file-path=/usr/local/php-fpm/etc --enable-fpm --with-fpm-user=php-fpm --with-fpm-group=php-fpm --with-mysql=/usr/local/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-pdo-mysql=/usr/local/mysql --with-mysql-sock=/tmp/mysql.sock --with-libxml-dir --with-gd --with-jpeg-dir --with-png-dir --with-freetype-dir --with-iconv-dir --with-zlib-dir --with-mcrypt --enable-soap --enable-gd-native-ttf --enable-ftp --enable-mbstring --enable-exif --with-pear --with-curl  --with-openssl; echo $? > /root/downloadPHP.log; make && make install; echo $? >> /root/downloadPHP.log

安装完之后拷贝php的配置文件:

[root@localhost /usr/local/src/php-5.6.30]$ cp php.ini-production /usr/local/php-fpm/etc/php.ini

创建一个php-fpm.conf文件:

[root@localhost ~]$ vim /usr/local/php-fpm/etc/php-fpm.conf

# 内容如下:
[global]
pid = /usr/local/php-fpm/var/run/php-fpm.pid
error_log = /usr/local/php-fpm/var/log/php-fpm.log
[www]
listen = /tmp/php-fcgi.sock
listen.mode = 666
user = php-fpm
group = php-fpm
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
rlimit_files = 1024

拷贝启动脚本、更改文件权限、添加到服务列表里,并设置开机启动:

[root@localhost /usr/local/src/php-5.6.30]$ cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
chmod 755 /etc/init.d/php-fpm
chkconfig --add php-fpm
chkconfig php-fpm on

添加php-fpm服务用户:

useradd -s /sbin/nologin php-fpm

使用php-fpm -t检测一下配置文件有没有问题:

[root@localhost ~]$ /usr/local/php-fpm/sbin/php-fpm -t
[14-Dec-2017 17:25:43] NOTICE: configuration file /usr/local/php-fpm/etc/php-fpm.conf test is successful

没有问题后就启动服务,并检查进程:

[root@localhost ~]$ service php-fpm start
Starting php-fpm  done
[root@localhost ~]$ ps aux |grep php-fpm

最后检查一下nginx能否解析php,在nginx的html目录下创建一个php文件,写一句简单的php代码:

[root@localhost ~]$ vim /usr/local/nginx/html/1.php
<?php
echo "This Test Page!"
?>

使用curl命令进行访问,正常输出就代表没问题:

[root@localhost ~]$ curl localhost/1.php
This Test Page!
[root@localhost ~]$

配置nginx默认虚拟主机,方便以后可以直接使用:
首先把nginx配置文件里定义的虚拟主机删除:

vim /usr/local/nginx/conf/nginx.conf

删除后加上这一行,这是用来引用虚拟主机配置文件的:

include vhost/*.conf;

创建vhost目录:

mkdir /usr/local/nginx/conf/vhost

进入到vhost目录下,创建一个default.conf文件:

cd /usr/local/nginx/conf/vhost
vim default.conf

添加以下内容:

server
{
    listen 80 default_server;
    server_name aaa.com;
    index index.html index.htm index.php;
    root /data/wwwroot/default;

    location ~ \.php$
    {
        include fastcgi_params;
        fastcgi_pass unix:/tmp/php-fcgi.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /data/wwwroot/default$fastcgi_script_name;
    }
}

创建默认站点目录:

mkdir -p /data/wwwroot/default/

进入default目录,创建一个php文件:

cd /data/wwwroot/default/
vim index.php

文件内容如下:

<?php
    echo "defaultIndex"
?>

重新启动nginx:

service nginx restart

curl访问,输出结果如下代表配置成功:

[root@localhost /data/wwwroot/default]$ curl localhost
defaultIndex
[root@localhost /data/wwwroot/default]$

最后通过rsync把配置文件和安装包同步到其他机器上即可,因为机器不算多,所以我是直接把整个根目录给同步了,使用的是以下脚本:

#!/usr/bin/expect
set host [lindex $argv 0]
set passwd [lindex $argv 1]

spawn rsync -av / root@$host:/
expect {
"yes/no" { send "yes\r"}
"password:" { send "$passwd\r" }
}

interact

## 调用脚本
#!/bin/bash
passwd=$2
for ip in `cat $1`
do
    ./syncAll.expect $ip $passwd
done

如果其他机器上出现启动nginx服务失败,使用用find命令找到nginx.service文件,检查文件的配置内容,看看是否与以下内容一致,不是的话就修改一下:

# Automatically generated by systemd-sysv-generator
[Unit]
Documentation=man:systemd-sysv-generator(8)
SourcePath=/etc/rc.d/init.d/nginx
Description=SYSV: http service.
Before=runlevel2.target
Before=runlevel3.target
Before=runlevel4.target
Before=runlevel5.target
Before=shutdown.target
Before=php-fpm.service
After=network-online.target
After=network.service
Conflicts=shutdown.target

[Service]
Type=forking
Restart=no
TimeoutSec=5min
IgnoreSIGPIPE=no
KillMode=process
GuessMainPID=no
RemainAfterExit=yes
ExecStart=/etc/rc.d/init.d/nginx start
ExecStop=/etc/rc.d/init.d/nginx stop
ExecReload=/etc/rc.d/init.d/nginx reload

修改完之后此文件的内容后需要使用以下命令重新加载:

systemctl daemon-reload

5.在所有的web服务器上搭建discuz论坛、dedecms企业网站以及zrlog博客


这一步也是和搭建环境一样,先在一台机器上搭建好,然后再同步到其他机器上。
1.搭建discuz论坛,先给discuz配置一个虚拟主机站点,和配置默认虚拟主机差不多:

进入到vhost目录下,创建一个discuz.com.conf文件:

cd /usr/local/nginx/conf/vhost
vim discuz.com.conf

添加以下内容:

server
{
    listen 80;
    server_name www.discuz.com;
    index index.html index.htm index.php;
    root /data/wwwroot/discuz.com;

        location ~ \.php$
    {
        include fastcgi_params;
        fastcgi_pass unix:/tmp/php-fcgi.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /data/wwwroot/discuz.com$fastcgi_script_name;
    }
}

创建站点目录:

mkdir -p /data/wwwroot/discuz.com/

进入discuz.com目录,创建一个php文件:

cd /data/wwwroot/discuz.com/
vim index.php

文件内容和测试方式都是配置以上配置默认虚拟主机的过程一样,这里就不再赘述了。

记得每配置一个虚拟主机站点都要重启nginx服务。

开始安装Discuz
1.下载Discuz的压缩包:
Discuz的压缩包可以在官网下载自己需要的版本:http://www.discuz.net/forum.php

我这里使用的是3.3的UTF8版本:

[root@localhost ~]# cd /usr/local/src/
[root@localhost /usr/local/src]# wget http://download.comsenz.com/DiscuzX/3.3/Discuz_X3.3_SC_UTF8.zip

解压:

[root@localhost /usr/local/src]# unzip Discuz_X3.3_SC_UTF8.zip

解压后会有以下几个目录:

[root@localhost /usr/local/src]# ls
Discuz_X3.3_SC_UTF8.zip readme upload utility

下载好并解压后,先将之前用于测试的默认页文件给删掉,然后将以上解压的upload目录下所有的文件拷贝到discuz.com站点目录下:

[root@localhost /usr/local/src]# rm -f /data/wwwroot/discuz.com/index.php
[root@localhost /usr/local/src]# ls /data/wwwroot/discuz.com/
[root@localhost /usr/local/src]# cp -r upload/* /data/wwwroot/discuz.com/
[root@localhost /usr/local/src]# ls !$
ls /data/wwwroot/discuz.com/
admin.php  config           data         home.php    misc.php    search.php  uc_client
api        connect.php      favicon.ico  index.php   plugin.php  source      uc_server
api.php    cp.php           forum.php    install     portal.php  static      userapp.php
archiver   crossdomain.xml  group.php    member.php  robots.txt  template
[root@localhost /usr/local/src]#

ok之后到windows上配置hosts文件,windows的hosts文件默认在这个目录下:

C:\Windows\System32\drivers\etc

在hosts文件中加上这一句:

192.168.200.152 www.discuz.com

保存之后就可以在浏览器上直接进行访问 www.discuz.com 了,访问成功后会显示如下页面,点击同意进入下一步:
搭建一个高可用负载均衡的集群架构(第一部分)

然后就会进入目录、文件的权限检查界面,但是会发现这些目录或文件权限不足,所以都是不可写的状态:
搭建一个高可用负载均衡的集群架构(第一部分)

那么就只能自己写个脚本给这些目录赋予权限了,页面中显示的目录路径都是相对路径,所以这个脚本需要放在站点的根目录下:

[root@localhost ~]# cd /data/wwwroot/discuz.com/
[root@localhost /data/wwwroot/discuz.com]# vim fileList.txt  # 先把路径都放在一个文本文件中
./config
./data
./data/cache
./data/avatar
./data/plugindata
./data/download
./data/addonmd5
./data/template
./data/threadcache
./data/attachment
./data/attachment/album
./data/attachment/forum
./data/attachment/group
./data/log
./uc_client/data/cache
./uc_server/data/
./uc_server/data/cache
./uc_server/data/avatar
./uc_server/data/backup
./uc_server/data/logs
./uc_server/data/tmp uc_server/data/view
[root@localhost /data/wwwroot/discuz.com]# vim filePermission.sh
#!bin/bash
# 写个简单的循环脚本就搞定了
for file in `cat ./fileList.txt`
do
  chmod 777 $file
done

[root@localhost /data/wwwroot/discuz.com]# sh ./filePermission.sh

执行完脚本后刷新页面就会发现状态都变为可写了:
搭建一个高可用负载均衡的集群架构(第一部分)

没问题后就点击页面下方的”下一步“:
搭建一个高可用负载均衡的集群架构(第一部分)

1、選擇“全新安裝 Discuz! X (含 UCenter Server)”

如果你之前沒有安裝過Discuz就選擇此項。

2、選擇“僅安裝 Discuz! X (手工指定已經安裝的 UCenter Server )”

如果你之前安裝過Discuz,現在只是升級的話,選擇此項並保證之前的 UCenter 是 UCenter 1.6.0 版本,如果之前安裝的 UCenter Server 沒有進行升級操作的話,一般為 1.5.1 或 1.5.2 版本,你需要首先升級 Ucenter 到 1.6.0版本, 否則安裝程序會提示錯誤,無法繼續。因為我是沒安裝過的所以這裏以全新安裝 Discuz為例。

點擊“下一步”,進入安裝數據庫的界面,如下圖所示:

搭建一个高可用负载均衡的集群架构(第一部分)

这里只需要输入你数据库root用户的密码,然后再设置一个admin密码就可以了,发送告警邮件的邮箱写不写都可以,剩下的会自动进行安装:
搭建一个高可用负载均衡的集群架构(第一部分)

安装完成后点击访问即可,如果你不需要安装Discuz推荐的应用的话:
搭建一个高可用负载均衡的集群架构(第一部分)

访问:
搭建一个高可用负载均衡的集群架构(第一部分)

然后回到web服务器上修改discuz的配置文件。将dbhost,dbuser,dbpw,dbname中的参数改为和mycat一一对应。实现读写分离:

[root@localhost /data/wwwroot/discuz.com]$ vim /data/wwwroot/discuz.com/config/config_global.php
// ----------------------------  CONFIG DB  ----------------------------- //
$_config['db']['1']['dbhost'] = '192.168.200.149:8066';
$_config['db']['1']['dbuser'] = 'discuz';
$_config['db']['1']['dbpw'] = '123456';
$_config['db']['1']['dbcharset'] = 'utf8';
$_config['db']['1']['pconnect'] = '0';
$_config['db']['1']['dbname'] = 'ultrax';
$_config['db']['1']['tablepre'] = 'pre_';
$_config['db']['slave'] = '';
$_config['db']['common']['slave_except_table'] = '';

## 修改完成后重启nginx
[root@localhost /data/wwwroot/discuz.com]$ service nginx restart
Restarting nginx (via systemctl):                          [  确定  ]

然后登录discuz论坛的admin用户,能够成功登录代表没问题:
搭建一个高可用负载均衡的集群架构(第一部分)

然后随便浏览一下discuz论坛之后,登录mycat的9066端口查看数据源,如下可看到读写分离成功:
搭建一个高可用负载均衡的集群架构(第一部分)

2.搭建dedecms企业网站,同样的也需要先配置一个虚拟主机站点:
进入到vhost目录下,创建一个dedecms.com.conf文件:

cd /usr/local/nginx/conf/vhost
vim dedecms.com.conf

添加以下内容:

server
{
    listen 80;
    server_name www.dedecms.com;
    index index.html index.htm index.php;
    root /data/wwwroot/dedecms.com;

        location ~ \.php$
    {
        include fastcgi_params;
        fastcgi_pass unix:/tmp/php-fcgi.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /data/wwwroot/dedecms.com$fastcgi_script_name;
    }
}

创建站点目录:

mkdir -p /data/wwwroot/dedecms.com/

进入dedecms.com目录,创建一个php文件:

cd /data/wwwroot/dedecms.com/
vim index.php

内容和之前的一样,同样的也是要使用curl测试一下,验证能够正常解析php。

确定该站点能够正常解析php后,到官网上下载Dedecms的压缩包,官网下载地址如下:

http://www.dedecms.com/products/dedecms/downloads/

我这里下载的是5.7的UTF8版本的:

[root@localhost ~]# cd /usr/local/src/
[root@localhost /usr/local/src]# wget http://updatenew.dedecms.com/base-v57/package/DedeCMS-V5.7-UTF8-SP2.tar.gz

下载之后解压,可以看到以下几个目录:

[root@localhost /usr/local/src]# tar -zxvf DedeCMS-V5.7-UTF8-SP2.tar.gz
[root@localhost /usr/local/src]# ls
DedeCMS-V5.7-UTF8-SP2
[root@localhost /usr/local/src]# cd DedeCMS-V5.7-UTF8-SP2
[root@localhost /usr/local/src/DedeCMS-V5.7-UTF8-SP2]# ls
docs  uploads
[root@localhost /usr/local/src/DedeCMS-V5.7-UTF8-SP2]#

安装Dedecms:
首先将dedecms.com站点目录下的测试文件给删掉,然后再把解压后的uploads目录下的所有文件都拷贝到nginx默认站点目录下:

[root@localhost /usr/local/src/DedeCMS-V5.7-UTF8-SP2]# rm -f /data/wwwroot/dedecms.com/index.php
[root@localhost /usr/local/src/DedeCMS-V5.7-UTF8-SP2]# cp -r ./uploads/* /data/wwwroot/dedecms.com/
[root@localhost /usr/local/src/DedeCMS-V5.7-UTF8-SP2]# cd !$
cd /data/wwwroot/dedecms.com/
[root@localhost /data/wwwroot/dedecms.com]# ls
a     dede    favicon.ico  include    install  member  robots.txt  tags.php  uploads
data  images  index.php    m          plus     special templets
[root@localhost /data/wwwroot/dedecms.com]#

完成以上操作后,同样的配置一下windows上的hosts文件,然后使用浏览器访问,然后就是按部就班地在页面上配置Dedecms了:
搭建一个高可用负载均衡的集群架构(第一部分)

然后可能会因为权限不足出现以下界面的情况:
搭建一个高可用负载均衡的集群架构(第一部分)

出现这种情况就给这些目录赋予权限就好了:

[root@localhost /data/wwwroot/dedecms.com]$ chmod 777 ./plus
[root@localhost /data/wwwroot/dedecms.com]$ chmod 777 ./dede
[root@localhost /data/wwwroot/dedecms.com]$ chmod 777 ./data
[root@localhost /data/wwwroot/dedecms.com]$ chmod 777 ./a
[root@localhost /data/wwwroot/dedecms.com]$ chmod 777 ./install
[root@localhost /data/wwwroot/dedecms.com]$ chmod 777 ./special
[root@localhost /data/wwwroot/dedecms.com]$ chmod 777 ./uploads/
[root@localhost /data/wwwroot/dedecms.com]$ chmod 777 ./

赋予权限后刷新页面就好了:
搭建一个高可用负载均衡的集群架构(第一部分)

设置数据库信息和管理员密码:
搭建一个高可用负载均衡的集群架构(第一部分)

安装完成:
搭建一个高可用负载均衡的集群架构(第一部分)

网站首页:
搭建一个高可用负载均衡的集群架构(第一部分)

访问http://www.dedecms.com/dede/ 可以登录网站后台:
搭建一个高可用负载均衡的集群架构(第一部分)

登录成功:
搭建一个高可用负载均衡的集群架构(第一部分)

3.搭建zrlog博客系统:
1.配置tomcat的虚拟主机,Tomcat在server.xml文件中配置虚拟主机:

[root@localhost ~]$ vim /usr/local/tomcat/conf/server.xml

# 在文件中增加以下内容:
<Host name="www.zrlog.com" appBase=""
        unpackWARs= "true" autoDeploy="true"
        xmlValidation="false" xmlNamespaceAware="false">
        <Context path="" docBase="/data/wwwroot/zrlog.com/" debug="0" reloadable="true" crossContext="true"/>
</Host>

2.创建相应的站点目录:

mkdir /data/wwwroot/zrlog.com

3.下载zrlog,并解压到站点目录下:

[root@localhost ~]$ cd /usr/local/src/
[root@localhost /usr/local/src]$ wget http://dl.zrlog.com/release/zrlog-1.7.1-baaecb9-release.war
[root@localhost /usr/local/src]$ unzip zrlog-1.7.1-baaecb9-release.war
[root@localhost /usr/local/src]$ unzip zrlog-1.7.1-baaecb9-release.war -d /data/wwwroot/zrlog.com
[root@localhost /usr/local/src]$ cd !$
cd /data/wwwroot/zrlog.com
[root@localhost /data/wwwroot/zrlog.com]$ ls
admin  assets  error  favicon.ico  include  install  META-INF  WEB-INF
[root@localhost /data/wwwroot/zrlog.com]$

4.为了共享80端口还需要配置nginx反向代理tomcat,编辑主机配置文件:

[root@localhost ~]$ vim /usr/local/nginx/conf/vhost/zrlog.com.conf
## 文件内容如下
upstream zrlog_com
{
    ip_hash;
    server localhost:8080;
}
server
{
    listen 80;
    server_name www.zrlog.com;
    location /
    {
        proxy_pass      http://zrlog_com;
        proxy_set_header Host   $host;
        proxy_set_header X-Real-IP      $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
[root@localhost ~]$  service nginx restart  # 重启nginx

5.重启tomcat服务:

/usr/local/tomcat/bin/shutdown.sh
/usr/local/tomcat/bin/startup.sh

6.配置好Windows上的hosts文件,然后使用浏览器访问 http://www.zrlog.com
搭建一个高可用负载均衡的集群架构(第一部分)
搭建一个高可用负载均衡的集群架构(第一部分)

安装完成:
搭建一个高可用负载均衡的集群架构(第一部分)

查看主页:
搭建一个高可用负载均衡的集群架构(第一部分)

控制台也没问题:
搭建一个高可用负载均衡的集群架构(第一部分)

6.给站点的后台访问做二次认证


首先安装httpd

yum install -y httpd

然后使用httpd里的htpasswd 命令去生成一个用户密码文件:

[root@localhost ~]$ htpasswd -c /usr/local/nginx/conf/htpasswd admin
New password: 
Re-type new password: 
Adding password for user admin
[root@localhost ~]$ 

生成完成后cat一下htpasswd 文件可以看到如下内容:

[root@localhost ~]$ cat /usr/local/nginx/conf/htpasswd
admin:$apr1$bwCvGuw9$71cc8LnzGEG0AEiSSB1uO.
[root@localhost ~]$

如果还需要再次添加用户的话就不需要加上-c选项了,加上-c选项会覆盖原来的htpasswd 文件。

编辑discuz的主机配置文件:

[root@localhost ~]$ vim /usr/local/nginx/conf/vhost/discuz.com.conf

    ## 添加以下内容,要记得添加在 location ~ \.php$ 上面
    location ~ admin.php
    {
        auth_basic              "Auth";
        auth_basic_user_file    /usr/local/nginx/conf/htpasswd;  # 密码文件路径
    }

重新加载nginx的配置文件:

/usr/local/nginx/sbin/nginx -t
/usr/local/nginx/sbin/nginx -s reload

然后使用curl访问看看是否需要认证,结果如下则没问题:

[root@localhost ~]$ curl -x127.0.0.1:80 http://www.discuz.com/admin.php -I
HTTP/1.1 401 Unauthorized
Server: nginx/1.12.1
date: Fri, 15 Dec 2017 10:33:55 GMT
Content-Type: text/html
Content-Length: 195
Connection: keep-alive
WWW-Authenticate: Basic realm="Auth"

[root@localhost ~]$

最后指定用户名和密码访问看看是否成功,结果如下则没问题:

[root@localhost ~]$ curl -x127.0.0.1:80 -u admin:"123456" http://www.discuz.com/admin.php -I
HTTP/1.1 200 OK
Server: nginx/1.12.1
Date: Fri, 15 Dec 2017 10:35:06 GMT
Content-Type: application/octet-stream
Content-Length: 2739
last-Modified: Fri, 15 Dec 2017 04:09:01 GMT
Connection: keep-alive
ETag: "5a334add-ab3"
accept-Ranges: bytes

[root@localhost ~]$

ok之后接下来配置dedecms,同样的也是需要编辑主机配置文件:

[root@localhost ~]$ vim /usr/local/nginx/conf/vhost/dedecms.com.conf

    ## 配置内容如下:
    location /dede/
    {
        auth_basic              "Auth";
        auth_basic_user_file    /usr/local/nginx/conf/htpasswd;  # 密码文件路径
    }

然后重新加载nginx,同样的使用curl访问看看是否需要认证:

[root@localhost ~]$ curl -x127.0.0.1:80 http://www.dedecms.com/dede/ -I
HTTP/1.1 401 Unauthorized
Server: nginx/1.12.1
Date: Fri, 15 Dec 2017 10:41:28 GMT
Content-Type: text/html
Content-Length: 195
Connection: keep-alive
WWW-Authenticate: Basic realm="Auth"

[root@localhost ~]$

最后是zrlog,编辑nginx的反向代理配置文件:

[root@localhost ~]$ vim /usr/local/nginx/conf/vhost/zrlog.com.conf
    ## 在location / 的上面添加以下这段内容:
    location /admin/
    {
        auth_basic              "Auth";
        auth_basic_user_file    /usr/local/nginx/conf/htpasswd;
        proxy_pass      http://zrlog_com/admin/;
        proxy_set_header Host   $host;
        proxy_set_header X-Real-IP      $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

# 重启
[root@localhost ~]$ service nginx restart

# 测试
[root@localhost ~]$ curl -x127.0.0.1:80  http://www.zrlog.com/admin/ -I
HTTP/1.1 401 Unauthorized
Server: nginx/1.12.1
Date: Fri, 15 Dec 2017 12:20:24 GMT
Content-Type: text/html
Content-Length: 195
Connection: keep-alive
WWW-Authenticate: Basic realm="Auth"

如果出现访问首页正常但是访问管理页面nginx却报404错误的情况,首先确认好配置文件是正确,重启nginx依旧不正常的话,就试一下使用killall命令杀掉nginx进程,能让进程将内存数据都写入到磁盘中,然后再启动nginx。

7.然后将目录、文件的权限分配好


discuz的目录、文件权限之前在安装的时候分配好了,现在把install目录给删除即可:

[root@localhost ~]$ cd /data/wwwroot/discuz.com
[root@localhost /data/wwwroot/discuz.com]$ rm -rf install/

然后设置dedecms的目录、文件权限,下面是dedecms官网的目录安全配置说明:

1、目录权限
我们不建议用户把栏目目录设置在根目录, 原因是这样进行安全设置会十分的麻烦, 在默认的情况下,安装完成后,目录设置如下:
(1) data、templets、uploads、a或5.3的html目录, 设置可读写,不可执行的权限;
(2) 不需要专题的,建议删除 special 目录, 需要可以在生成HTML后,删除 special/index.php 然后把这目录设置为可读写,不可执行的权限;
(3) include、member、plus、后台管理目录 设置为可执行脚本,可读,但不可写入(安装了附加模块的,book、ask、company、group 目录同样如此设置)。

2、其它需注意问题
(1) 虽然对 install 目录已经进行了严格处理, 但为了安全起见,我们依然建议把它删除;
(2) 不要对网站直接使用MySQL root用户的权限,给每个网站设置独立的MySQL用户帐号,许可权限为:

代码如下 复制代码 
SELECT, INSERT , UPDATE , DELETE
CREATE , DROP , INDEX , ALTER , CREATE TEMPORARY TABLES

我尝试按照说明去修改权限结果出现网站无法访问的问题,于是实践过后发现只需要更改以下几个目录的权限即可:

[root@localhost /data/wwwroot]$ cd dedecms.com/
[root@localhost /data/wwwroot/dedecms.com]$ chmod 766 ./uploads
[root@localhost /data/wwwroot/dedecms.com]$ chmod 766 ./a
[root@localhost /data/wwwroot/dedecms.com]$ chmod 755 ./plus
[root@localhost /data/wwwroot/dedecms.com]$ chmod 644 data/common.inc.php
[root@localhost /data/wwwroot/dedecms.com]$ rm -rf install/
[root@localhost /data/wwwroot/dedecms.com]$ mv ./special/ /tmp/

至于数据库的话之前已经设置好了,所以也不用修改了。

zrlog的就默认即可,因为默认都是755、644的权限。

最后将配置文件和站点目录使用之前的脚本都同步到其他web服务器上,同步/data/目录和/usr/local/目录即可。

8.配置机器中web服务器的静态文件共享,这一步我们使用NFS完成


1.服务端需要安装nfs-utils和rpcbind包,安装命令:

yum install -y nfs-utils rpcbind

2.客户端需要安装nfs-utils包,安装命令,使用脚本批量安装:

yum install -y nfs-utils

3.确定需要共享的目录:

discuz需要共享的目录是:/data/wwwroot/discuz.com/data/attachment/
dedecms需要共享的目录是:/data/wwwroot/dedecms.com/uploads/
zrlog需要共享的目录是:/data/wwwroot/zrlog.com/attached/
然后给这些目录777的权限

4.为了安全性需要限定共享的ip,所以需要编写一个简单的循环脚本,批量在服务端的/etc/exports文件中写入配置,脚本内容如下:

file=$1
for i in `seq 3 9`
do
   echo "$file 192.168.200.15$i/24(rw,sync,no_root_squash)" >> /etc/exports
done

echo "$file 192.168.200.160/24(rw,sync,no_root_squash)" >> /etc/exports

# 执行脚本,参数是需要共享的目录路径
[root@localhost ~]$ sh forIP.sh "/data/wwwroot/discuz.com/data/attachment/"
[root@localhost ~]$ sh forIP.sh "/data/wwwroot/dedecms.com/uploads/"
[root@localhost ~]$ sh forIP.sh "/data/wwwroot/zrlog.com/attached/"

执行完脚本之后,/etc/exports文件内容如下:

/data/wwwroot/discuz.com/data/attachment/ 192.168.200.153/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/discuz.com/data/attachment/ 192.168.200.154/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/discuz.com/data/attachment/ 192.168.200.155/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/discuz.com/data/attachment/ 192.168.200.156/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/discuz.com/data/attachment/ 192.168.200.157/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/discuz.com/data/attachment/ 192.168.200.158/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/discuz.com/data/attachment/ 192.168.200.159/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/discuz.com/data/attachment/ 192.168.200.160/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/dedecms.com/uploads/ 192.168.200.153/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/dedecms.com/uploads/ 192.168.200.154/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/dedecms.com/uploads/ 192.168.200.155/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/dedecms.com/uploads/ 192.168.200.156/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/dedecms.com/uploads/ 192.168.200.157/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/dedecms.com/uploads/ 192.168.200.158/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/dedecms.com/uploads/ 192.168.200.159/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/dedecms.com/uploads/ 192.168.200.160/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/zrlog.com/attached/ 192.168.200.153/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/zrlog.com/attached/ 192.168.200.154/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/zrlog.com/attached/ 192.168.200.155/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/zrlog.com/attached/ 192.168.200.156/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/zrlog.com/attached/ 192.168.200.157/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/zrlog.com/attached/ 192.168.200.158/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/zrlog.com/attached/ 192.168.200.159/24(rw,sync,anonuid=1000,anongid=1000)
/data/wwwroot/zrlog.com/attached/ 192.168.200.160/24(rw,sync,anonuid=1000,anongid=1000)

5.使用之前的批量命令脚本查看机器有没有监听111端口,一般来讲安装完nfs之后就会自动启动服务并监听端口的,如果没有启动的话,就手动启动一下,命令如下:

systemctl start rpcbind。

6.启动服务端的nfs服务:

[root@localhost ~]$ systemctl start nfs
[root@localhost ~]$ ps aux |grep nfs
root      5568  0.0  0.0      0     0 ?        S<   10:55   0:00 [nfsd4_callbacks]
root      5584  0.0  0.0      0     0 ?        S    10:55   0:00 [nfsd]
root      5585  0.0  0.0      0     0 ?        S    10:55   0:00 [nfsd]
root      5586  0.0  0.0      0     0 ?        S    10:55   0:00 [nfsd]
root      5587  0.0  0.0      0     0 ?        S    10:55   0:00 [nfsd]
root      5588  0.0  0.0      0     0 ?        S    10:55   0:00 [nfsd]
root      5589  0.0  0.0      0     0 ?        S    10:55   0:00 [nfsd]
root      5590  0.0  0.0      0     0 ?        S    10:55   0:00 [nfsd]
root      5591  0.0  0.0      0     0 ?        S    10:55   0:00 [nfsd]
root      5595  0.0  0.0 112680   972 pts/0    S+   10:55   0:00 grep --color=auto nfs

## 在启动nfs时会自动帮你启动rpc相关的一些服务:
[root@localhost ~]$ ps aux |grep rpc
rpc       3086  0.0  0.1  64964  1416 ?        Ss   00:23   0:00 /sbin/rpcbind -w
rpcuser   5551  0.1  0.1  42380  1748 ?        Ss   10:55   0:00 /usr/sbin/rpc.statd
root      5552  0.0  0.0      0     0 ?        S<   10:55   0:00 [rpciod]
root      5555  0.0  0.0  19324   392 ?        Ss   10:55   0:00 /usr/sbin/rpc.idmapd
root      5558  0.0  0.0  42564   944 ?        Ss   10:55   0:00 /usr/sbin/rpc.mountd
root      5597  0.0  0.0 112680   976 pts/0    R+   10:56   0:00 grep --color=auto rpc
[root@localhost ~]$

以上这些都是与nfs的关联服务,如果没有以上这些服务是无法正常使用nfs的。

7.设置rpcbind和nfs服务开机启动:

systemctl enable rpcbind
systemctl enable nfs

8.查看服务所使用的端口:

[root@localhost ~]$ rpcinfo -p
   program vers proto   port  service
    100000    4   tcp    111  portmapper
    100000    3   tcp    111  portmapper
    100000    2   tcp    111  portmapper
    100000    4   udp    111  portmapper
    100000    3   udp    111  portmapper
    100000    2   udp    111  portmapper
    100024    1   udp  38738  status
    100024    1   tcp  42835  status
    100005    1   udp  20048  mountd
    100005    1   tcp  20048  mountd
    100005    2   udp  20048  mountd
    100005    2   tcp  20048  mountd
    100005    3   udp  20048  mountd
    100005    3   tcp  20048  mountd
    100003    3   tcp   2049  nfs
    100003    4   tcp   2049  nfs
    100227    3   tcp   2049  nfs_acl
    100003    3   udp   2049  nfs
    100003    4   udp   2049  nfs
    100227    3   udp   2049  nfs_acl
    100021    1   udp  41186  nlockmgr
    100021    3   udp  41186  nlockmgr
    100021    4   udp  41186  nlockmgr
    100021    1   tcp  34522  nlockmgr
    100021    3   tcp  34522  nlockmgr
    100021    4   tcp  34522  nlockmgr

其中有几个服务的端口是随机端口,不过我们可以在/etc/services配置文件中固定这些端口:

[root@localhost ~]$ vim /etc/services

## 在文件末尾添加如下内容:
mountd 20048/tcp
mountd 20048/udp
status 42835/tcp
status 38738/udp
lockd 32803/tcp
lockd 32769/udp
rquotad 1001/tcp
rquotad 1001/udp

## 编辑/etc/sysconfig/nfs配置文件
[root@localhost ~]$ vim /etc/sysconfig/nfs
MOUNTD_PORT=20048
RQUOTAD_PORT=1001
LOCKD_TCPPORT=32803
LOCKD_UDPPORT=32769

## 重启nfs和rpcbind,rpcbind要在nfs之前启动,不然端口不会注册
[root@localhost ~]$ systemctl restart rpcbind
[root@localhost ~]$ systemctl restart nfs

9.配置防火墙规则,开启相应的端口:

firewall-cmd --zone=public --add-port=111/tcp --permanent
firewall-cmd --zone=public --add-port=111/udp --permanent
firewall-cmd --zone=public --add-port=2049/tcp --permanent
firewall-cmd --zone=public --add-port=2049/udp --permanent
firewall-cmd --zone=public --add-port=20048/tcp --permanent
firewall-cmd --zone=public --add-port=20048/udp --permanent
firewall-cmd --zone=public --add-port=42835/tcp --permanent
firewall-cmd --zone=public --add-port=38738/udp --permanent
firewall-cmd --zone=public --add-port=32803/tcp --permanent
firewall-cmd --zone=public --add-port=32769/tcp --permanent
firewall-cmd --zone=public --add-port=1001/udp --permanent

如果还是不行的话,就直接清空防火墙规则吧,反正我是没弄成,清空防火墙规则之后就ok了。其实这一步使用rsync搭建文件同步会比较好一些

配置客户端:
1.查看一下可以共享服务端的哪个目录:

[root@localhost ~]$ showmount -e 192.168.200.152
export list for 192.168.200.152:
/data/wwwroot/zrlog.com/attached         192.168.200.160/24,192.168.200.159/24,192.168.200.158/24,192.168.200.157/24,192.168.200.156/24,192.168.200.155/24,192.168.200.154/24,192.168.200.153/24
/data/wwwroot/dedecms.com/uploads        192.168.200.160/24,192.168.200.159/24,192.168.200.158/24,192.168.200.157/24,192.168.200.156/24,192.168.200.155/24,192.168.200.154/24,192.168.200.153/24
/data/wwwroot/discuz.com/data/attachment 192.168.200.160/24,192.168.200.159/24,192.168.200.158/24,192.168.200.157/24,192.168.200.156/24,192.168.200.155/24,192.168.200.154/24,192.168.200.153/24

2.在其中一台机器测试挂载共享目录:

[root@localhost ~]$ mount -t nfs 192.168.200.152:/data/wwwroot/zrlog.com/attached /data/wwwroot/zrlog.com/attached
mount.nfs: mount point /data/wwwroot/zrlog.com/attached does not exist
[root@localhost ~]$ mkdir /data/wwwroot/zrlog.com/attached
[root@localhost ~]$ mount -t nfs 192.168.200.152:/data/wwwroot/zrlog.com/attached /data/wwwroot/zrlog.com/attached
[root@localhost ~]$ mount -t nfs 192.168.200.152:/data/wwwroot/dedecms.com/uploads /data/wwwroot/dedecms.com/uploads
[root@localhost ~]$ mount -t nfs 192.168.200.152:/data/wwwroot/discuz.com/data/attachment /data/wwwroot/discuz.com/data/attachment

## 然后在客户端的挂载目录下创建个文件看看是否同步到服务器上,服务端也需要创建一个文件看看是否能够同步到客户端上:
[root@localhost ~]$ touch /data/wwwroot/zrlog.com/attached/test153.txt
[root@localhost ~]$ touch /data/wwwroot/dedecms.com/uploads/test153.txt
[root@localhost ~]$ touch /data/wwwroot/discuz.com/data/attachment/test153.txt

## 服务端上查看:
[root@localhost ~]$ ls /data/wwwroot/zrlog.com/attached/test153.txt
/data/wwwroot/zrlog.com/attached/test153.txt
[root@localhost ~]$ ls /data/wwwroot/dedecms.com/uploads/test153.txt
/data/wwwroot/dedecms.com/uploads/test153.txt
[root@localhost ~]$ ls /data/wwwroot/discuz.com/data/attachment/test153.txt
/data/wwwroot/discuz.com/data/attachment/test153.txt
[root@localhost ~]$

## 同样的服务端也需要创建测试文件,然后到客户端上查看

测试确定没问题后,使用批量执行命令的脚本挂载目录到其他机器上:

[root@localhost ~]$ sh ./cmd.sh "/root/ip.txt" "root" "lri35krJF;ba" "mkdir /data/wwwroot/zrlog.com/attached"
[root@localhost ~]$ sh ./cmd.sh "/root/ip.txt" "root" "lri35krJF;ba" "mount -t nfs 192.168.200.152:/data/wwwroot/zrlog.com/attached /data/wwwroot/zrlog.com/attached"
[root@localhost ~]$ sh ./cmd.sh "/root/ip.txt" "root" "lri35krJF;ba" "mount -t nfs 192.168.200.152:/data/wwwroot/dedecms.com/uploads /data/wwwroot/dedecms.com/uploads"
[root@localhost ~]$ sh ./cmd.sh "/root/ip.txt" "root" "lri35krJF;ba" "mount -t nfs 192.168.200.152:/data/wwwroot/discuz.com/data/attachment /data/wwwroot/discuz.com/data/attachment"

9.使用Keepalived结合LVS DR搭建高可用负载均衡


LVS层安装LVS和KeepAlived

1.打开DirServer和LoadDirServer,安装lvs和keepalived,安装命令如下:

yum install -y ipvsadm
yum install -y keepalived

2.在DirServer上编辑keepalived的配置文件:

[root@localhost ~]$ mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf_bak
[root@localhost ~]$ vim /etc/keepalived/keepalived.conf
## 配置内容从以下网址获取
https://coding.net/u/aminglinux/p/aminglinux-book/git/blob/master/D21Z/lvs_keepalived.conf

# 其中需要修改的地方:
1.vrrp_instance VI_1里的interface修改为你当前机器的网卡名称
2.virtual_ipaddress 里的vip地址修改为你的vip地址
3.authentication 里的auth_pass可以自定义
4.virtual_server 的ip改为你的vip
5.real_server 的ip改为你的Real Server的ip

3.在LoadDirServer上编辑keepalived的配置文件,通过rsync把DirServer的配置文件同步过去:

[root@localhost ~]$ rsync -av /etc/keepalived/keepalived.conf root@192.168.200.151:/etc/keepalived/keepalived.conf

# 其中需要修改的地方:
1.vrrp_instance VI_1里的interface修改为你当前机器的网卡名称
2.vrrp_instance VI_1里的state修改为BACKUP
3.vrrp_instance VI_1里的priority修改为90

4.两台dir都要打开路由转发:

[root@localhost ~]$ echo 1 > /proc/sys/net/ipv4/ip_forward
[root@localhost ~]$ cat !$
cat /proc/sys/net/ipv4/ip_forward
1
[root@localhost ~]$

5.在其中一台Real Server上编写脚本:

[root@localhost ~]$ vim /usr/local/sbin/lvs_rs.sh
#/bin/bash
# 修改为你的vip地址
vip=192.168.200.179
#把vip绑定在lo上,是为了实现rs直接把结果返回给客户端
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up
route add -host $vip lo:0
#以下操作为更改arp内核参数,目的是为了让rs顺利发送mac地址给客户端
#参考文档www.cnblogs.com/lgfeng/archive/2012/10/16/2726308.html
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

6.执行这个脚本看看有没有问题:

[root@localhost ~]$ sh /usr/local/sbin/lvs_rs.sh
[root@localhost ~]$ 

ok,没有报错就是没问题了

7.然后使用route -n命令查看一下网关:

[root@localhost ~]$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.200.1   0.0.0.0         UG    100    0        0 ens160
192.168.200.0   0.0.0.0         255.255.255.0   U     100    0        0 ens160
192.168.200.179 0.0.0.0         255.255.255.255 UH    0      0        0 lo
## 有上面这一行就没问题了,vip添加到网关了,如果没有这个vip的话,可能是脚本出了问题

8.最后将脚本文件同步到其他Real Server上,并且使用脚本批量执行测试一下:

[root@localhost ~]$ sh ./syncAll.sh "ip.txt" "lri35krJF;ba"
[root@localhost ~]$ sh ./cmd.sh "/root/ip.txt" "root" "lri35krJF;ba" "sh /usr/local/sbin/lvs_rs.sh"
[root@localhost ~]$ sh ./cmd.sh "/root/ip.txt" "root" "lri35krJF;ba" "route -n"

9.回到dir上,启动两台dir机器的keepalived服务:

[root@localhost ~]$ systemctl start keepalived
[root@localhost ~]$ ps aux |grep keepalived
root       909  0.0  0.1 120720  1480 ?        Ss   12月14   1:29 /usr/sbin/keepalived -D
root       910  0.0  0.2 120720  2748 ?        S    12月14   0:08 /usr/sbin/keepalived -D
root     26356  0.0  0.2 124976  2760 ?        S    12月14   1:24 /usr/sbin/keepalived -D
root     31029  0.0  0.0 112684   980 pts/0    S+   17:45   0:00 grep --color=auto keepalived
[root@localhost ~]$

10.启动keepalived后,使用ipvsadm -ln命令,查看一下分发规则:

[root@localhost ~]$ ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.200.179:80 wlc persistent 60
  -> 192.168.200.152:80           Route   100    0          0         
  -> 192.168.200.153:80           Route   100    0          0         
  -> 192.168.200.154:80           Route   100    0          0         
  -> 192.168.200.155:80           Route   100    0          0         
  -> 192.168.200.156:80           Route   100    0          0         
  -> 192.168.200.157:80           Route   100    0          0         
  -> 192.168.200.158:80           Route   100    0          0         
  -> 192.168.200.159:80           Route   100    0          0         
  -> 192.168.200.160:80           Route   100    0          0

10.测试该架构


基本的架构已经搭建完了,现在简单测试一下是否正常。

1.测试keepalived是否能自动把停掉Nginx服务的Real Serve机器给踢出分发规则

把其中一台Real Serve的Nginx给关了:

[root@localhost ~]$ service nginx stop
Stopping nginx (via systemctl):                            [  确定  ]
[root@localhost ~]$

回到分发器上查看一下分发规则:

[root@localhost ~]$ ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.200.179:80 wlc persistent 60
  -> 192.168.200.153:80           Route   100    0          0         
  -> 192.168.200.154:80           Route   100    0          0         
  -> 192.168.200.155:80           Route   100    0          0         
  -> 192.168.200.156:80           Route   100    0          0         
  -> 192.168.200.157:80           Route   100    0          0         
  -> 192.168.200.158:80           Route   100    0          0         
  -> 192.168.200.159:80           Route   100    0          0         
  -> 192.168.200.160:80           Route   100    0          0         
[root@localhost ~]$

可以看到分发规则里少了一台ip为192.168.200.152的Real Serve,keepalived自动把停掉Nginx服务的Real Serve给踢出分发规则了。这一步可能需要多执行几次ipvsadm -ln命令,因为我们在配置文件里设置的是10秒检测一次Real Serve的状态。

接着再把刚刚停掉的那台Real Serve的Nginx启动起来:

[root@localhost ~]$ service nginx start
Starting nginx (via systemctl):                            [  确定  ]
[root@localhost ~]$

这时候再次回到分发器上查看规则:

[root@localhost ~]$ ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.200.179:80 wlc persistent 60
  -> 192.168.200.152:80           Route   100    0          0         
  -> 192.168.200.153:80           Route   100    0          0         
  -> 192.168.200.154:80           Route   100    0          0         
  -> 192.168.200.155:80           Route   100    0          0         
  -> 192.168.200.156:80           Route   100    0          0         
  -> 192.168.200.157:80           Route   100    0          0         
  -> 192.168.200.158:80           Route   100    0          0         
  -> 192.168.200.159:80           Route   100    0          0         
  -> 192.168.200.160:80           Route   100    0          0         
[root@localhost ~]$

可以看到keepalived检测到Real Serve的Nginx启动起来了,就自动添加了分发规则。

2.配置windows的hosts文件,把discuz、zrlog、dedecms域名指向到192.168.200.179这个vip上,然后在浏览器上测试能否正常访问:

访问www.discuz.com:
搭建一个高可用负载均衡的集群架构(第一部分)

登录后台看看是否需要二次认证:
搭建一个高可用负载均衡的集群架构(第一部分)

访问www.dedecms.com:
搭建一个高可用负载均衡的集群架构(第一部分)

登录后台看看是否需要二次认证:
搭建一个高可用负载均衡的集群架构(第一部分)

访问www.zrlog.com:
搭建一个高可用负载均衡的集群架构(第一部分)

登录后台看看是否需要二次认证:
搭建一个高可用负载均衡的集群架构(第一部分)

上传一张图片:
搭建一个高可用负载均衡的集群架构(第一部分)

发布成功后复制图片链接如下:

http://www.zrlog.com/attached/image/20171216/20171216181715_62.jpg

然后通过脚本批量查看rs机器的该目录下是否有此图片文件,有的话代表没问题:

[root@localhost ~]$ sh ./cmd.sh "/root/ip.txt" "root" "lri35krJF;ba" "ls /data/wwwroot/zrlog.com/attached/image/20171216/20171216181715_62.jpg"

查看请求转发情况:

[root@localhost ~]$ ipvsadm -lcn | grep 192.168.200.179
TCP 00:05  NONE        192.168.200.248:0  192.168.200.179:80 192.168.200.152:80
TCP 02:24  ESTABLISHED 192.168.200.248:63659 192.168.200.179:80 192.168.200.152:80
TCP 02:24  ESTABLISHED 192.168.200.248:63657 192.168.200.179:80 192.168.200.152:80
TCP 02:24  ESTABLISHED 192.168.200.248:63660 192.168.200.179:80 192.168.200.152:80
[root@localhost ~]$

3.查看dir机器上是否有vip,有的话就宕掉这台dir,看看loaddir是否会进行切换:
搭建一个高可用负载均衡的集群架构(第一部分)

现在的loaddir是不会有这个vip的:
搭建一个高可用负载均衡的集群架构(第一部分)

停掉dir的keepalived服务:

[root@localhost ~]$ systemctl stop keepalived
[root@localhost ~]$ ps aux |grep keepalived
root     31500  0.0  0.0 112680   980 pts/0    R+   18:39   0:00 grep --color=auto keepalived
[root@localhost ~]$

看看loaddir是否会自动进行切换:
搭建一个高可用负载均衡的集群架构(第一部分)

能自动切换后,使用浏览器进行访问看看是否正常。

访问过后看看请求转发的情况:
搭建一个高可用负载均衡的集群架构(第一部分)

如图,有正常转发的数据代表ok了。

延伸阅读

    评论