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

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

业务需求


用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了。



本文转自 ZeroOne01 51CTO博客,原文链接:http://blog.51cto.com/zero01/2052407,如需转载请自行联系原作者

相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
2月前
|
负载均衡 关系型数据库 应用服务中间件
高可用系列文章之二 - 传统分层架构技术方案
高可用系列文章之二 - 传统分层架构技术方案
|
3月前
|
机器学习/深度学习 NoSQL Redis
Redis高可用之集群架构(第三部分)
Redis高可用之集群架构(第三部分)
|
3天前
|
负载均衡 监控 网络协议
使用haproxy实现负载均衡集群
【4月更文挑战第14天】HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,快速并且可靠的一种解决方案。
8 1
|
23天前
|
负载均衡 网络协议 Java
构建高效可扩展的微服务架构:利用Spring Cloud实现服务发现与负载均衡
本文将探讨如何利用Spring Cloud技术实现微服务架构中的服务发现与负载均衡,通过注册中心来管理服务的注册与发现,并通过负载均衡策略实现请求的分发,从而构建高效可扩展的微服务系统。
|
1月前
|
存储 监控 NoSQL
Redis 架构深入:主从复制、哨兵到集群
大家好,我是小康,今天我们来聊下 Redis 的几种架构模式,包括主从复制、哨兵和集群模式。
Redis 架构深入:主从复制、哨兵到集群
|
1月前
|
分布式计算 API 数据处理
Flink【基础知识 01】(简介+核心架构+分层API+集群架构+应用场景+特点优势)(一篇即可大概了解flink)
【2月更文挑战第15天】Flink【基础知识 01】(简介+核心架构+分层API+集群架构+应用场景+特点优势)(一篇即可大概了解flink)
60 1
|
2月前
|
缓存 负载均衡 监控
从零开始搭建一个高可用的后端架构
【2月更文挑战第6天】本文将介绍如何从零开始搭建一个高可用的后端架构,包括架构设计、技术选型、部署和监控等方面。通过对各种技术的分析和实践,帮助读者深入理解高可用架构的实现和优化。
|
2月前
|
存储 缓存 运维
解密一致性哈希算法:实现高可用和负载均衡的秘诀
解密一致性哈希算法:实现高可用和负载均衡的秘诀
157 0
|
2月前
|
网络协议 中间件 数据库
Zookeeper学习系列【三】Zookeeper 集群架构、读写机制以及一致性原理(ZAB协议)
Zookeeper学习系列【三】Zookeeper 集群架构、读写机制以及一致性原理(ZAB协议)
95 0
|
3月前
|
存储 负载均衡 NoSQL
Redis 高可用篇:你管这叫主从架构数据同步原理?
Redis 高可用篇:你管这叫主从架构数据同步原理?
241 5