IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 记一次网站架构的搭建 -> 正文阅读

[系统运维]记一次网站架构的搭建

思路:

  • lvs+keepalived实现四层负载均衡
  • nginx做七层负载均衡和反向代理
  • nfs做静态资源异地容灾
  • tomcat+php做后端动态页面解析
  • mysql主从复制做存储层
  • redis主从复制做session会话共享
  • mha对mysql进行故障自动切换

两台lvs+keepalived服务器,提供VIP,保证高可用并实现四层负载均衡,将请求转发到两台nginx服务器,nginx服务器做七层负载均衡和反向代理并实现动静分离,静态资源存放至NFS服务器做冗余容灾,动态请求转发至后端Tomcat和PHP服务器进行解析,redis一主一从三哨兵+keepalived提供VIP实现会话共享。mysql 数据库服务器做一主两从复制,使用mha提供VIP并实现数据库故障的自动切换,保证数据的安全及稳定性。

节点规划

因为实验资源受限,所以一台主机会充当多个角色

主机名IP角色备注
ds-masterIP:192.168.126.90 VIP:192.168.126.100LVS maste、php服务器、tomcat服务器部署lvs与keepalived,VIP为浮动IP,同时部署php和tomcat
ds-slaveIP:192.168.126.91 VIP:192.168.126.100LVS slave、php服务器、tomcat服务器部署lvs与keepalived,VIP为浮动IP,同时部署php和tomcat
rs1192.168.126.92 VIP:192.168.126.200(mysql) VIP:192.168.126.250(redis)nginx服务器1、mysql主服务器 、redis主+keepalived、redis哨兵1提供WEB静态资源及对动态资源请求转发至后端tomcat服务器、mysql主(mysql主节点,负责写数据)
rs2192.168.126.93nginx服务器2 、mysql服务器、redis从+keepalived、redis哨兵2提供WEB静态资源及对动态资源请求转发至后端tomcat服务器、mysql从1(mysql从节点,负责读数据,备选master)
nfs192.168.126.94数据共享服务器 、mysql服务器、redis哨兵3提供网页共享静态WEB资源、mysql从2(mysql从节点,负责读数据)
mha192.168.126.95MHA mangerMySQL 高可用方案,故障切换

主机名、防火墙、时钟源设置

hostnamectl set-hostname xxxx
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
yum install ntpdate -y
ntpdate ntp1.aliyun.com
hwclock -w

NFS配置

安装服务

[root@nfs ~]# yum -y install nfs-utils rpcbind
[root@nfs ~]# rpm -qa nfs-utils rpcbind
nfs-utils-1.3.0-0.68.el7.1.x86_64
rpcbind-0.2.0-49.el7.x86_64

配置 exports文件

[root@nfs ~]# mkdir -p /data/
[root@nfs ~]# vim /etc/exports
/data/ 192.168.126.0/24(rw,sync)
[root@nfs ~]# chown -R nfsnobody:nfsnobody /data
drwxr-xr-x. 2 nfsnobody nfsnobody 6 Sep 21 19:03 /data
[root@nfs ~]# systemctl start nfs
[root@nfs ~]# systemctl enable nfs
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service.

启动服务

[root@nfs ~]# systemctl start nfs

在rs1,rs2上配置nfs客户端

[root@rs1 ~]# yum install nfs-utils -y
[root@rs1 ~]# showmount -e 192.168.126.94
Export list for 192.168.126.94:
/data 192.168.126.0/24

在rs2上执行相同的操作

配置nginx

rs1:

安装nginx

[root@rs1 ~]# vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[root@rs1 ~]# yum makecache fast

[root@rs1 ~]# yum repolist | grep nginx-stable
nginx-stable/7/x86_64                nginx stable repo                       242

[root@rs1 ~]# yum install nginx -y
[root@rs1 ~]# rpm -qa nginx
nginx-1.20.1-1.el7.ngx.x86_64

[root@rs1 ~]# egrep -v '^$|#' /etc/nginx/conf.d/default.conf
server {
    listen       80;
    server_name  localhost;
    location ^~ /static/ {
        root /usr/share/nginx/html;
        index  index1.html;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
[root@rs1 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

[root@rs1 ~]# mkdir -p /usr/share/nginx/html/static
[root@rs1 ~]# vim /etc/fstab
192.168.126.94:/data /usr/share/nginx/html nfs defaults 0 0
[root@rs1 ~]# mount -a
[root@rs1 ~]# df -h | grep data
192.168.126.94:/data     9.8G  2.8G  7.1G  29% /usr/share/nginx/html

[root@rs1 ~]# echo "It is test from rs1 192.168.126.92" > /usr/share/nginx/html/static/index1.html

[root@rs1 ~]# systemctl start nginx
[root@rs1 ~]# systemctl enable nginx
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.

测试:
在这里插入图片描述

rs2:

[root@rs2 ~]# vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[root@rs2 ~]# yum makecache fast

[root@rs2 ~]# yum repolist | grep nginx-stable
nginx-stable/7/x86_64                nginx stable repo                       242

[root@rs2 ~]# yum install nginx -y
[root@rs2 ~]# rpm -qa nginx
nginx-1.20.1-1.el7.ngx.x86_64

[root@rs2 ~]# egrep -v '^$|#' /etc/nginx/conf.d/default.conf
server {
    listen       80;
    server_name  localhost;
    location ^~ /static/ {
        root /usr/share/nginx/html;
        index  index2.html;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
[root@rs2 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

[root@rs2 ~]# vim /etc/fstab
192.168.126.94:/data /usr/share/nginx/html nfs defaults 0 0
[root@rs2 ~]# mount -a
[root@rs2 ~]# df -h | grep data
192.168.126.94:/data     9.8G  2.8G  7.1G  29% /usr/share/nginx/html

[root@rs2 ~]# echo "It is test from rs2 192.168.126.93" > /usr/share/nginx/html/static/index2.html


[root@rs2 ~]# systemctl start nginx
[root@rs2 ~]# systemctl enable nginx
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.

测试:

在这里插入图片描述

配置LVS

lvs_dr模式dr无法主动识别rs上的web服务器是否停止工作,为解决这一问题,用到keepalived,集成高可用集群和负载均衡为一体(keepalived–>HA+LB)

ds-master配置:

[root@ds-master ~]# yum -y install keepalived ipvsadm

[root@ds-master ~]# vim /etc/keepalived/keepalived.conf 
! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL
}

vrrp_instance VI_1 {
    state MASTER
    interface ens32
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.126.100
    }
}

virtual_server 192.168.126.100 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 50
    protocol TCP

    real_server 192.168.126.92 80 {
        weight 100
        TCP_CHECK {
            connect_timeout 10       # 10秒无反应超时
            nb_get_retry 3
            delay_before_retry 3
            connet_port 80
        }
    }
    real_server 192.168.126.93 80 {
        weight 100
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connet_port 80
        }
    }
}

ds-slave配置:

[root@ds-slave ~]# yum -y install keepalived ipvsadm

[root@ds-slave ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens32
    virtual_router_id 51
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.126.100
    }
}

virtual_server 192.168.126.100 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 50
    protocol TCP

    real_server 192.168.126.92 80 {
        weight 100
        TCP_CHECK {
            connect_timeout 10       # 10秒无反应超时
            nb_get_retry 3
            delay_before_retry 3
            connet_port 80
        }
    }
    real_server 192.168.126.93 80 {
        weight 100
        TCP_CHECK {
            connect_timeout 10 
            nb_get_retry 3
            delay_before_retry 3
            connet_port 80
        }
    }
}

ds-master和ds-slave配置完成后,启动keepalived

[root@ds-master ~]# systemctl start keepalived
[root@ds-master ~]# systemctl enable keepalived
Created symlink from /etc/systemd/system/multi-user.target.wants/keepalived.service to /usr/lib/systemd/system/keepalived.service.

[root@ds-slave ~]# systemctl start keepalived
[root@ds-slave ~]# systemctl enable keepalived
Created symlink from /etc/systemd/system/multi-user.target.wants/keepalived.service to /usr/lib/systemd/system/keepalived.service.

# 查看ds-master的VIP是否生成(slave没有VIP(当主停掉时,备才启动))
[root@ds-master ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:a1:54:3f brd ff:ff:ff:ff:ff:ff
    inet 192.168.126.90/24 brd 192.168.126.255 scope global ens32
       valid_lft forever preferred_lft forever
    inet 192.168.126.100/32 scope global ens32	# 已生成
       valid_lft forever preferred_lft forever

# 分别查看ipvsadm规则
[root@ds-master ~]# 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.126.100:80 rr persistent 50
  -> 192.168.126.92:80            Route   100    0          0         
  -> 192.168.126.93:80            Route   100    0          0  

[root@ds-slave ~]# 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.126.100:80 rr persistent 50
  -> 192.168.126.92:80            Route   100    0          0         
  -> 192.168.126.93:80            Route   100    0          0   

rs1和rs2配置:

# 把vip绑定在lo上,是为了实现rs直接把结果返回给客户端
[root@rs1 ~]# vim /etc/sysconfig/network-scripts/ifcfg-lo:0
DEVICE=lo:0
IPADDR=192.168.126.100
NETMASK=255.255.255.255
ONBOOT=yes

[root@rs1 ~]# systemctl restart network
[root@rs1 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet 192.168.126.100/32 brd 192.168.126.100 scope global lo:0
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:2b:48:05 brd ff:ff:ff:ff:ff:ff
    inet 192.168.126.92/24 brd 192.168.126.255 scope global ens32
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe2b:4805/64 scope link 
       valid_lft forever preferred_lft forever

# 以下操作为更改arp内核参数,目的是为了让rs顺利发送mac地址给客户端
[root@rs1 ~]# vim /etc/sysctl.conf
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
[root@rs1 ~]# sysctl -p

测试

为了便于短时间内观察效果,需要关闭长链接,禁用浏览器缓存等操作:
(1)在windows浏览器中选择禁用缓存
在这里插入图片描述

(2)将ipvs会话保持时间设置小点

[root@ds-master ~]# ipvsadm --set 1 1 1
[root@ds-master ~]# ipvsadm -L --timeout
Timeout (tcp tcpfin udp): 1 1 1
[root@ds-master ~]# vim /etc/keepalived/keepalived.conf
persistence_timeout 3
[root@ds-master ~]# systemctl restart keepalived

[root@ds-slave ~]# ipvsadm --set 1 1 1
[root@ds-slave ~]# vim /etc/keepalived/keepalived.conf
persistence_timeout 3
[root@ds-slave ~]# systemctl restart keepalived

(3)将nginx中的长连接设置小点

[root@rs1 ~]# vim /etc/nginx/nginx.conf 
…………
    keepalive_timeout  3;
…………
[root@rs1 ~]# nginx -s reload

[root@rs2 ~]# vim /etc/nginx/nginx.conf 
…………
    keepalive_timeout  3;
…………
[root@rs2 ~]# nginx -s reload

在这里插入图片描述
在这里插入图片描述通过以上设置会话保持时间大约在3秒并且因为使用rr轮询算法,所以每次间隔3秒访问 192.168.126.100/static/ 时,client每次访问VIP,那么DS会按照依次循环的方式将请求调度到后端的RS服务器上

lvs+keepalived 主要作用:

  • 应对高并发连接做负载均衡。将客户端请求按照设定的策略分发到后端服务器上

  • 保证业务的高可用。

    停止rs1的nginx服务,客户机访问虚拟IP。结果:成功跳过不能访问的rs1,rs1的转发规则也被清掉(重启nginx,又会加回来)

    停掉ds-master上的主keepalived,查看主备状态。结果:备用keepalived接管,重新启动主keepalived时,主重启接管

配置php

nfs服务器:

配置nfs服务器上的php网页资源

[root@nfs ~]# mkdir -p /data/php
[root@nfs ~]# vim /data/php/index.php
<?php
system("/var/www/html/ip.sh");	# 为了后面便于观察最后到底是将请求分发到具体的哪个php服务器上,所以该php网页测试页面的作用是:通过php页面来调用shell脚本显示当前执行请求的php服务器IP地址
?>
[root@nfs ~]# vim /data/php/ip.sh	# shell脚本
#!/bin/bash
/usr/sbin/ifconfig ens32 | awk 'NR==2 {print $2}'
[root@nfs ~]# chmod 755 /data/php/ip.sh

ds-master:

????下载安装

# 安装jdk
[root@ds-master ~]# ls
jdk-8u112-linux-x64.rpm
[root@ds-master ~]# yum localinstall jdk-8u112-linux-x64.rpm -y
[root@ds-master ~]# java -version
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)

# 下载安装php
[root@ds-master ~]# yum -y install php-fpm php-mbstring.x86_64 php-gd.x86_64 php-mysql.x86_64 php

????配置php

[root@ds-master ~]# vim /etc/php-fpm.d/www.conf 
listen = 0.0.0.0:9000 		开监听地址为任意。
;listen.allowed_clients = 127.0.0.1 	把这一行注释

# 网页文件可直接挂载至nfs服务器上
[root@ds-master ~]# yum install nfs-utils -y
[root@ds-master ~]# showmount -e 192.168.126.94
Export list for 192.168.126.94:
/data 192.168.126.0/24 

[root@ds-master ~]# vim /etc/fstab
192.168.126.94:/data/php /var/www/html nfs defaults 0 0
[root@ds-master ~]# mount -a
[root@ds-master ~]# df -h | grep /data/php
192.168.126.94:/data/php  9.8G  2.8G  7.1G  29% /var/www/html

[root@ds-master ~]# systemctl start php-fpm
[root@ds-master ~]# systemctl enable php-fpm
Created symlink from /etc/systemd/system/multi-user.target.wants/php-fpm.service to /usr/lib/systemd/system/php-fpm.service.


ds-slave:

????下载安装

# 安装jdk
[root@ds-slave ~]# ls
jdk-8u112-linux-x64.rpm
[root@ds-slave ~]# yum localinstall jdk-8u112-linux-x64.rpm -y
[root@ds-slave ~]# java -version
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)

# 下载安装php
[root@ds-slave ~]# yum -y install php-fpm php-mbstring.x86_64 php-gd.x86_64 php-mysql.x86_64 php

????配置php

[root@ds-slave ~]# vim /etc/php-fpm.d/www.conf 
listen = 0.0.0.0:9000 		开监听地址为任意。
;listen.allowed_clients = 127.0.0.1 	把这一行注释

[root@ds-slave ~]# yum install nfs-utils -y
[root@ds-slave ~]# showmount -e 192.168.126.94
Export list for 192.168.126.94:
/data 192.168.126.0/24 

[root@ds-salve ~]# vim /etc/fstab
192.168.126.94:/data/php /var/www/html nfs defaults 0 0
[root@ds-salve ~]# mount -a
[root@ds-salve ~]# df -h | grep /data/php
192.168.126.94:/data/php  9.8G  2.8G  7.1G  29% /var/www/html

[root@ds-slave ~]# systemctl start php-fpm
[root@ds-slave ~]# systemctl enable php-fpm
Created symlink from /etc/systemd/system/multi-user.target.wants/php-fpm.service to /usr/lib/systemd/system/php-fpm.service.

在nginx配置文件中写入php的location匹配规则

????rs1:

[root@rs1 ~]# egrep -v '^$|#' /etc/nginx/conf.d/default.conf 
upstream php {
    server 192.168.126.90:9000;
    server 192.168.126.91:9000;
}
server {
    listen       80;
    server_name  localhost;
    
    location ~* \.php$ {
	fastcgi_pass php;
	fastcgi_index index.php;
	fastcgi_param  SCRIPT_FILENAME        /var/www/html/$fastcgi_script_name;
	include fastcgi_params;
    }
    
    location ^~ /static/ {
        root /usr/share/nginx/html;
        index  index1.html;
    }
}
[root@rs1 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@rs1 ~]# nginx -s reload

????rs2:

[root@rs2 ~]# egrep -v '^$|#' /etc/nginx/conf.d/default.conf 
upstream php {
    server 192.168.126.90:9000;
    server 192.168.126.91:9000;
}
server {
    listen       80;
    server_name  localhost;
    
    location ~* \.php$ {
        fastcgi_pass php;
        fastcgi_index index.php;
        fastcgi_param  SCRIPT_FILENAME        /var/www/html/$fastcgi_script_name;
        include fastcgi_params;
    }
    
    location ^~ /static/ {
        root /usr/share/nginx/html;
        index  index2.html;
    }
}
[root@rs2 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@rs2 ~]# nginx -s reload

测试在这里插入图片描述
在这里插入图片描述

结果:以轮询的方式将请求发送到后端php服务器群

数据流: client发送对LVS的VIP请求关于index.php页面—> LVS将请求按照rr算法(keepalived中配置为rr)转发到后端nginx服务器—>nginx服务器根据location匹配规则再将请求通过fastcgi_pass指令转发到定义好的php负载均衡服务器集群(上面定义为php),根据upstream中的算法(上面设定为rr)将请求调度到指定的php服务器上进行解析并将结果进行原路返回

配置tomcat

ds-master:

????安装tomcat

[root@ds-master ~]# ls
apache-tomcat-8.0.36.tar.gz
[root@ds-master ~]# mkdir /usr/local/tomcat
[root@ds-master ~]# tar -xf apache-tomcat-8.0.36.tar.gz -C /usr/local/tomcat

????创建网页

[root@ds-master ~]# vim /usr/local/tomcat/apache-tomcat-8.0.36/webapps/ROOT/test.jsp 
<html>
    <body bgcolor="green">
    <center>
    <h1>192.168.126.90</h1>
    <h1>port:8080</h1>
    <h1>this is ds-master! </h1>
    </center>
    </body>
</html>

ds-slave:
????安装tomcat

[root@ds-slave ~]# ls
apache-tomcat-8.0.36.tar.gz
[root@ds-slave ~]# mkdir /usr/local/tomcat
[root@ds-slave ~]# tar -xf apache-tomcat-8.0.36.tar.gz -C /usr/local/tomcat

????创建网页

[root@ds-slave ~]# vim /usr/local/tomcat/apache-tomcat-8.0.36/webapps/ROOT/test.jsp 
<html>
    <body bgcolor="blue">
    <center>
    <h1>192.168.126.91</h1>
    <h1>port:8080</h1>
    <h1>this is ds-slave! </h1>
    </center>
    </body>
</html>

在nginx配置文件中写入js的location匹配规则

rs1:

[root@rs1 ~]# egrep -v '#|^$' /etc/nginx/conf.d/default.conf 
upstream php {
    server 192.168.126.90:9000;
    server 192.168.126.91:9000;
}
upstream js {
    server 192.168.126.90:8080;
    server 192.168.126.91:8080;
}
server {
    listen       80;
    server_name  localhost;
    
    location ~* \.php$ {
	fastcgi_pass php;
	fastcgi_index index.php;
	fastcgi_param  SCRIPT_FILENAME        /var/www/html/$fastcgi_script_name;
	include fastcgi_params;
    }
    
    location ~ \.jsp$ {
	proxy_pass http://js;
    }   
     
    location ^~ /static/ {
        root /usr/share/nginx/html;
        index  index1.html;
    }
}
[root@rs1 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@rs1 ~]# nginx -s reload

rs2:

[root@rs2 ~]# egrep -v '#|^$' /etc/nginx/conf.d/default.conf 
upstream php {
    server 192.168.126.90:9000;
    server 192.168.126.91:9000;
}
upstream js {
    server 192.168.126.90:8080;
    server 192.168.126.91:8080;
}
server {
    listen       80;
    server_name  localhost;
    location ~* \.php$ {
        fastcgi_pass php;
        fastcgi_index index.php;
        fastcgi_param  SCRIPT_FILENAME        /var/www/html/$fastcgi_script_name;
        include fastcgi_params;
    }
    location ~ \.jsp$ {
	proxy_pass http://js;
    }   
    location ^~ /static/ {
        root /usr/share/nginx/html;
        index  index2.html;
    }
}
[root@rs2 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@rs2 ~]# nginx -s reload

启动tomcat

# 为了便于观察效果,将tomcat会话保持时间尽可能缩小
[root@ds-slave ~]# vim /usr/local/tomcat/apache-tomcat-8.0.36/conf/web.xml
    <session-config>
        <session-timeout>3</session-timeout>
    </session-config>
[root@ds-master ~]# vim /usr/local/tomcat/apache-tomcat-8.0.36/conf/web.xml
    <session-config>
        <session-timeout>3</session-timeout>
    </session-config

# 启动tomcat
# ds-master
[root@ds-master ~]# /usr/local/tomcat/apache-tomcat-8.0.36/bin/startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat/apache-tomcat-8.0.36
Using CATALINA_HOME:   /usr/local/tomcat/apache-tomcat-8.0.36
Using CATALINA_TMPDIR: /usr/local/tomcat/apache-tomcat-8.0.36/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /usr/local/tomcat/apache-tomcat-8.0.36/bin/bootstrap.jar:/usr/local/tomcat/apache-tomcat-8.0.36/bin/tomcat-juli.jar
Tomcat started.
[root@ds-master ~]# jps
3814 Jps
3791 Bootstrap

# ds-slave
[root@ds-slave ~]# /usr/local/tomcat/apache-tomcat-8.0.36/bin/startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat/apache-tomcat-8.0.36
Using CATALINA_HOME:   /usr/local/tomcat/apache-tomcat-8.0.36
Using CATALINA_TMPDIR: /usr/local/tomcat/apache-tomcat-8.0.36/temp
Using JRE_HOME:        /usr/java/jdk1.8.0_161
Using CLASSPATH:       /usr/local/tomcat/apache-tomcat-8.0.36/bin/bootstrap.jar:/usr/local/tomcat/apache-tomcat-8.0.36/bin/tomcat-juli.jar
Tomcat started.
[root@ds-slave ~]# jps
51704 Jps
51673 Bootstrap

测试

在这里插入图片描述
在这里插入图片描述
结果:以轮询的方式将请求发送到后端tomcat服务器群

数据流: client发送对LVS的VIP请求关于test.jsp页面—> LVS将请求按照指定算法(keepalived中配置为rr)转发到后端nginx服务器—>nginx服务器根据location匹配规则再将请求通过proxy_pass指令转发到定义好的tomcat负载均衡服务器集群(上面定义为js),根据upstream中的算法(上面设定为rr)将请求调度到指定的tomcat服务器上进行解析并将结果进行原路返回

数据库配置

主机名IP角色备注
rs1192.168.126.92nginx服务器1、mysql主服务器提供WEB静态资源及对动态资源请求转发至后端tomcat服务器、mysql主(mysql主节点,负责写数据)
rs2192.168.126.93nginx服务器2 、mysql从1(备选master)服务器提供WEB静态资源及对动态资源请求转发至后端tomcat服务器、mysql从1(mysql从节点,负责读数据,备选master)
nfs192.168.126.94数据共享服务器 、mysql从2服务器提供网页共享静态WEB资源、mysql从2(mysql从节点,负责读数据)
mha-manager192.168.126.95MHA mangerMySQL 高可用方案,故障切换

????卸载mariadb

[root@rs1 ~]# rpm -qa mariadb*
mariadb-libs-5.5.56-2.el7.x86_64
[root@rs1 ~]# rpm -e mariadb-libs-5.5.56-2.el7.x86_64 --nodeps

[root@rs2 ~]# rpm -qa mariadb*
mariadb-libs-5.5.56-2.el7.x86_64
[root@rs2 ~]# rpm -e mariadb-libs-5.5.56-2.el7.x86_64 --nodeps
[root@nfs ~]# rpm -qa mariadb*
mariadb-libs-5.5.56-2.el7.x86_64
[root@nfs ~]# rpm -e mariadb-libs-5.5.56-2.el7.x86_64 --nodeps

????配置hosts

[root@rs1 ~]# vim /etc/hosts
192.168.126.92 rs1
192.168.126.93 rs2
192.168.126.94 nfs
192.168.126.95 mha-manager
[root@rs1 ~]# scp /etc/hosts rs2:/etc/hosts
[root@rs1 ~]# scp /etc/hosts nfs:/etc/hosts
[root@rs1 ~]# scp /etc/hosts mha-manager:/etc/hosts

????初始化mysql并修改密码

[root@rs1 mysql-package]# ls
mysql-8.0.16-2.el7.x86_64.rpm-bundle.tar
[root@rs1 mysql-package]# tar -xf mysql-8.0.16-2.el7.x86_64.rpm-bundle.tar 
[root@rs1 mysql-package]# ls
mysql-8.0.16-2.el7.x86_64.rpm-bundle.tar                 mysql-community-libs-8.0.16-2.el7.x86_64.rpm
mysql-community-client-8.0.16-2.el7.x86_64.rpm           mysql-community-libs-compat-8.0.16-2.el7.x86_64.rpm
mysql-community-common-8.0.16-2.el7.x86_64.rpm           mysql-community-server-8.0.16-2.el7.x86_64.rpm
mysql-community-devel-8.0.16-2.el7.x86_64.rpm            mysql-community-test-8.0.16-2.el7.x86_64.rpm
mysql-community-embedded-compat-8.0.16-2.el7.x86_64.rpm
[root@rs1 mysql-package]# yum localinstall *.rpm -y

[root@rs1 ~]# mysqld --initialize
[root@rs1 ~]# chown -R mysql:mysql /var/lib/mysql/
[root@rs1 ~]# systemctl start mysqld
[root@rs1 ~]# systemctl enable mysqld

# mysql初始化密码 
[root@rs1 ~]# sed -n '/password/ p' /var/log/mysqld.log 
2021-09-24T13:05:29.872624Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: d,.A/xTkq1-n	# 初始化密码

[root@rs1 ~]# mysql -uroot -p
# 或 mysql -uroot -p‘d,.A/xTkq1-n’
Enter password: 	# 输入初始化密码
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.16

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> alter user 'root'@'localhost' identified by 'mysql123.COM';	# 修改密码
Query OK, 0 rows affected (0.00 sec)

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

mysql> exit
Bye
[root@rs1 ~]# systemctl stop mysqld

rs2,nfs节点的mysql初始化并修改密码步骤同上(方便起见所有节点mysql密码设置为同一个)

????修改mysql配置文件

rs1为主库可以实现读写

[root@rs1 ~]# egrep -v '^$|^#' /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
server_id=1 # 必须指定,且各实例均不相同
log_bin=mysql1-bin # 开启二进制日志功能,可以自定义设置二进制文件名前缀,格式为: log_bin=binlog,如果不设置则是以主机名为前缀
log_bin_index=mysql1-bin.index # 二进制日志索引文件
relay_log=relay1-log # 开启中继日志功能并指定日志名称
relay_log_index=relay1-log.index # 中继日志文件的索引文件
sync-binlog=1 # 数据刷盘参数,=1时,只要有1个事务提交就会触发写盘的操作,安全性最高,并发性最差; 数据刷盘参数=0时由文件系统控制写盘的频率,并发性能最好,但是意外丢失数据的风险最大,这里根据实际需求配置,不建议乱配。
log-slave-updates=true # 允许从服务器进行复制更新二进制文件

# 排除掉不需要同步的数据库列表
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=performance_schema
binlog-ignore-db=sys

[root@rs1 ~]# systemctl start mysqld

# 查看是否开启binlog
mysql> show variables like '%log_bin%';
+---------------------------------+---------------------------------+
| Variable_name                   | Value                           |
+---------------------------------+---------------------------------+
| log_bin                         | ON                              |
| log_bin_basename                | /var/lib/mysql/mysql1-bin       |
| log_bin_index                   | /var/lib/mysql/mysql1-bin.index |
| log_bin_trust_function_creators | OFF                             |
| log_bin_use_v1_row_events       | OFF                             |
| sql_log_bin                     | ON                              |
+---------------------------------+---------------------------------+
6 rows in set (0.01 sec)

rs2为从库

[root@rs2 ~]# egrep -v '^$|^#' /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
server_id=2
log_bin=mysql2-bin	# 从库也要开启二进制日志相关功能,因为从服务器可能成为主服务器
log_bin_index=mysql2-bin.index
relay_log=relay2-log
relay_log_index=relay2-log.index
sync-binlog=1 
log-slave-updates=true
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=performance_schema
binlog-ignore-db=sys

[root@rs2 ~]# systemctl start mysqld

# 查看是否开启binlog
[root@rs2 ~]# mysql -uroot -p'mysql123.COM'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.16 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like '%log_bin%';
+---------------------------------+---------------------------------+
| Variable_name                   | Value                           |
+---------------------------------+---------------------------------+
| log_bin                         | ON                              |
| log_bin_basename                | /var/lib/mysql/mysql2-bin       |
| log_bin_index                   | /var/lib/mysql/mysql2-bin.index |
| log_bin_trust_function_creators | OFF                             |
| log_bin_use_v1_row_events       | OFF                             |
| sql_log_bin                     | ON                              |
+---------------------------------+---------------------------------+
6 rows in set (0.01 sec)

nfs作为从库

[root@nfs ~]# egrep -v '^$|^#' /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
server_id=3
log_bin=mysql3-bin
log_bin_index=mysql3-bin.index
relay_log=relay3-log
relay_log_index=relay3-log.index
log-slave-updates=true
sync-binlog=1
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=performance_schema
binlog-ignore-db=sys

[root@nfs ~]# systemctl start mysqld

# 查看是否开启binlog
[root@nfs ~]# mysql -uroot -p'mysql123.COM'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.16 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like '%log_bin%';
+---------------------------------+---------------------------------+
| Variable_name                   | Value                           |
+---------------------------------+---------------------------------+
| log_bin                         | ON                              |
| log_bin_basename                | /var/lib/mysql/mysql3-bin       |
| log_bin_index                   | /var/lib/mysql/mysql3-bin.index |
| log_bin_trust_function_creators | OFF                             |
| log_bin_use_v1_row_events       | OFF                             |
| sql_log_bin                     | ON                              |
+---------------------------------+---------------------------------+
6 rows in set (0.01 sec)

????创建用于在主从之间复制日志的用户并授权

rs1:

[root@rs1 ~]# mysql -uroot -p'mysql123.COM'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 20
Server version: 8.0.16 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create user 'copy'@'192.168.126.%' identified by "linux123.COM";
Query OK, 0 rows affected (0.01 sec)

mysql> grant replication slave on *.* to 'copy'@'192.168.126.%';
Query OK, 0 rows affected (0.01 sec)

mysql> alter user 'copy'@'192.168.126.%' identified with mysql_native_password by 'linux123.COM';
Query OK, 0 rows affected (0.01 sec)

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

mysql> exit
Bye

rs2:

[root@rs2 ~]# mysql -uroot -p'mysql123.COM'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.16 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create user 'copy'@'192.168.126.%' identified by "linux123.COM";
Query OK, 0 rows affected (0.01 sec)

mysql> grant replication slave on *.* to 'copy'@'192.168.126.%';
Query OK, 0 rows affected (0.00 sec)

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

mysql> exit
Bye

nfs:

[root@nfs ~]# mysql -uroot -p'mysql123.COM'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 8.0.16 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create user 'copy'@'192.168.126.%' identified by "linux123.COM";
Query OK, 0 rows affected (0.00 sec)

mysql> grant replication slave on *.* to 'copy'@'192.168.126.%';
Query OK, 0 rows affected (0.01 sec)

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

mysql> exit
Bye

????配置一主两从

查看主库(rs1)binlog文件名及位置

[root@rs1 ~]# mysql -uroot -p'mysql123.COM'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 21
Server version: 8.0.16 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show master status;
+-------------------+----------+--------------+-------------------------------------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB                                | Executed_Gtid_Set |
+-------------------+----------+--------------+-------------------------------------------------+-------------------+
| mysql1-bin.000001 |      878 |              | information_schema,mysql,performance_schema,sys |                   |
+-------------------+----------+--------------+-------------------------------------------------+-------------------+
1 row in set (0.00 sec)

rs2从库连接主库rs1

[root@rs2 ~]# mysql -uroot -p'mysql123.COM'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 8.0.16 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> change master to
    -> master_host='rs1',	# 主库的地址(也可以是IP)
    -> master_user='copy',	# 在主库上创建的复制账号
    -> master_password='linux123.COM',	# 在主库上创建的复制账号密码
    -> master_log_file='mysql1-bin.000001',	# 开始复制的主库上的二进制文件名(上面在rs1主机上通过show master status;语句获取到的)
    -> master_log_pos=878;	 # 开始复制的二进制文件具体位置(同样是上面在rs1主机上通过show master status;语句获取到的)
Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> start slave;		# 开启从库
Query OK, 0 rows affected (0.00 sec)

# 过段时间查看状态(通过pos的方式定位日志数据进行同步会比较慢,如果是主库数据比较多的情况可以使用mysqldump进行备份然后到从库执行,最后再使用pos方式会比较快)
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: rs1
                  Master_User: copy
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql1-bin.000001
          Read_Master_Log_Pos: 878
               Relay_Log_File: relay2-log.000002
                Relay_Log_Pos: 323
        Relay_Master_Log_File: mysql1-bin.000001
             Slave_IO_Running: Yes	# I/O线程是否启动并连接服务器,一般I/O线程出现no,可能是my.cnf配置有误,出现connecting一般是指定服务器有误或用于复制的用户有误
            Slave_SQL_Running: Yes	# SQL线程是否启动
        	# 当Slave_IO_Running和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: 878
              Relay_Log_Space: 526
              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: 1
                  Master_UUID: 17d5bab6-1d38-11ec-a801-000c292b4805
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           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
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set (0.00 sec)

# 限制从库只读((一是鉴于当前数据库架构,如果在从库上写数据,那么无法同步到其他节点;二是如果在主库和从库同时对同一数据的修改,有可能造成数据不一致等问题)
mysql> set global read_only=1;
Query OK, 0 rows affected (0.00 sec)

nfs从库连接主库rs1

[root@nfs ~]# mysql -uroot -p'mysql123.COM'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 8.0.16 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> change master to
    -> master_host='rs1',
    -> master_user='copy',
    -> master_password='linux123.COM',
    -> master_log_file='mysql1-bin.000001',
    -> master_log_pos=878;
Query OK, 0 rows affected, 2 warnings (0.02 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: rs1
                  Master_User: copy
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql1-bin.000001
          Read_Master_Log_Pos: 878
               Relay_Log_File: relay3-log.000002
                Relay_Log_Pos: 323
        Relay_Master_Log_File: mysql1-bin.000001
             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: 878
              Relay_Log_Space: 526
              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: 1
                  Master_UUID: 17d5bab6-1d38-11ec-a801-000c292b4805
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           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
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set (0.00 sec)

# 限制从库只读

主从复制验证

# rs主库上创建库和表并插入数据
[root@rs1 ~]# mysql -uroot -p'mysql123.COM'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 34
Server version: 8.0.16 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database test;
Query OK, 1 row affected (0.00 sec)

mysql> use test;
Database changed
mysql> create table test.student(id int,
    -> name varchar(10),
    -> age int);
Query OK, 0 rows affected (0.02 sec)

mysql> insert test.student values (1,"zhangsan",18);
Query OK, 1 row affected (0.01 sec)
mysql> select * from test.student;
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | zhangsan |   18 |
+------+----------+------+
1 row in set (0.00 sec)

# rs2从库查询验证
[root@rs2 ~]# mysql -uroot -p'mysql123.COM' -e 'select * from test.student'
mysql: [Warning] Using a password on the command line interface can be insecure.
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | zhangsan |   18 |
+------+----------+------+

# nfs从库查询验证
[root@nfs ~]# mysql -uroot -p'mysql123.COM' -e 'select * from test.student'
mysql: [Warning] Using a password on the command line interface can be insecure.
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | zhangsan |   18 |
+------+----------+------+
# 主从复制搭建成功

开启主从之间半同步复制

主库rs1:

#查看是否支持动态安装插件
mysql> select @@have_dynamic_loading;
+------------------------+
| @@have_dynamic_loading |
+------------------------+
| YES                    |
+------------------------+
1 row in set (0.00 sec)
# show plugins; 查看是否安装semic插件
# 主库安装半同步semi插件,soname重命名
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected (0.01 sec)
# 查看配置参数(未启用)
mysql> show variables like '%semi%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | OFF        |
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.00 sec)
# 开启半同步复制
mysql> set global rpl_semi_sync_master_enabled=1;
Query OK, 0 rows affected (0.01 sec)
#设置超时时间
mysql> set global rpl_semi_sync_master_timeout=1000;
Query OK, 0 rows affected (0.00 sec)
# 再次查看是否配置成功
mysql> show variables like '%semi%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | ON         |
| rpl_semi_sync_master_timeout              | 1000       |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.00 sec)

从库rs2:

# 查看是否支持动态安装插件
mysql> select @@have_dynamic_loading;
+------------------------+
| @@have_dynamic_loading |
+------------------------+
| YES                    |
+------------------------+
1 row in set (0.00 sec)
# 从库安装semi插件(注意,主库和从库的插件不一样,看清楚。)
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected (0.01 sec)
# 开启半同步
mysql> set global rpl_semi_sync_slave_enabled=1;
Query OK, 0 rows affected (0.00 sec)
# 查看是否配置成功
mysql> show variables like '%semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.01 sec)
# 重启slave
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: rs1
                  Master_User: copy
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql1-bin.000002
          Read_Master_Log_Pos: 155
               Relay_Log_File: relay2-log.000006
                Relay_Log_Pos: 323
        Relay_Master_Log_File: mysql1-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: 155
              Relay_Log_Space: 742
              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: 1
                  Master_UUID: 17d5bab6-1d38-11ec-a801-000c292b4805
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           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
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set (0.00 sec)

nfs从库:

mysql> select @@have_dynamic_loading;
+------------------------+
| @@have_dynamic_loading |
+------------------------+
| YES                    |
+------------------------+
1 row in set (0.00 sec)

mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected (0.01 sec)

mysql> set global rpl_semi_sync_slave_enabled=1;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.01 sec)

mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: rs1
                  Master_User: copy
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql1-bin.000002
          Read_Master_Log_Pos: 155
               Relay_Log_File: relay3-log.000006
                Relay_Log_Pos: 323
        Relay_Master_Log_File: mysql1-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: 155
              Relay_Log_Space: 742
              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: 1
                  Master_UUID: 17d5bab6-1d38-11ec-a801-000c292b4805
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           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
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set (0.00 sec)

配置MHA

????配置公钥免密登录

[root@rs1 ~]# ssh-keygen -t dsa -f ~/.ssh/id_dsa -P ""
[root@rs1 ~]# sshpass -p 123 ssh-copy-id -o StrictHostKeyChecking=no root@rs2
[root@rs1 ~]# sshpass -p 123 ssh-copy-id -o StrictHostKeyChecking=no root@nfs
[root@rs1 ~]# sshpass -p 123 ssh-copy-id -o StrictHostKeyChecking=no root@mha-manager

[root@rs2 ~]# ssh-keygen -t dsa -f ~/.ssh/id_dsa -P ""
[root@rs2 ~]# sshpass -p 123 ssh-copy-id -o StrictHostKeyChecking=no root@rs1
[root@rs2 ~]# sshpass -p 123 ssh-copy-id -o StrictHostKeyChecking=no root@nfs
[root@rs2 ~]# sshpass -p 123 ssh-copy-id -o StrictHostKeyChecking=no root@mha-manager

[root@nfs ~]# ssh-keygen -t dsa -f ~/.ssh/id_dsa -P ""
[root@nfs ~]# sshpass -p 123 ssh-copy-id -o StrictHostKeyChecking=no root@rs1
[root@nfs ~]# sshpass -p 123 ssh-copy-id -o StrictHostKeyChecking=no root@rs2
[root@nfs ~]# sshpass -p 123 ssh-copy-id -o StrictHostKeyChecking=no root@mha-manager

[root@mha-manager ~]# ssh-keygen -t dsa -f ~/.ssh/id_dsa -P ""
[root@mha-manager ~]# sshpass -p 123 ssh-copy-id -o StrictHostKeyChecking=no root@rs1
[root@mha-manager ~]# sshpass -p 123 ssh-copy-id -o StrictHostKeyChecking=no root@rs2
[root@mha-manager ~]# sshpass -p 123 ssh-copy-id -o StrictHostKeyChecking=no root@nfs

在所有mysql服务器上创建MHA管理账号“mha”并授权

rs1:

[root@rs1 ~]# mysql -uroot -p'mysql123.COM'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 20
Server version: 8.0.16 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create user 'mha'@'192.168.126.%' identified by "linux123.COM";
Query OK, 0 rows affected (0.01 sec)

mysql> alter user 'mha'@'192.168.126.%' identified with mysql_native_password by 'linux123.COM';
Query OK, 0 rows affected (0.00 sec)

mysql> grant all on *.* to 'mha'@'192.168.126.%';
Query OK, 0 rows affected (0.00 sec)

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

mysql> exit
Bye

rs2和nfs节点由于是rs1的从库,那么mha用户也就同时在两个从库上创建了

四台服务器同时安装node节点

rs1:

[root@rs1 ~]# ls
mha4mysql-node-0.57.tar.gz
[root@rs1 ~]# mkdir /usr/local/mha-node
# 解压
[root@rs1 ~]# tar -xf mha4mysql-node-0.57.tar.gz -C /usr/local/mha-node
# 安装所需依赖包
[root@rs1 ~]# yum install -y perl-DBD-MySQL \
> perl-Config-Tiny \
> perl-Log-Dispatch \
> perl-Parallel-ForkManager \
> perl-ExtUtils-CBuilder \
> perl-ExtUtils-MakeMaker \
> perl-CPAN
# 安装mha-node
[root@rs1 ~]# cd /usr/local/mha-node/mha4mysql-node-0.57/
[root@rs1 mha4mysql-node-0.57]# perl Makefile.PL
*** Module::AutoInstall version 1.06
*** Checking for Perl dependencies...
[Core Features]
- DBI        ...loaded. (1.627)
- DBD::mysql ...loaded. (4.023)
*** Module::AutoInstall configuration finished.
Checking if your kit is complete...
Looks good
Writing Makefile for mha4mysql::node

[root@rs1 mha4mysql-node-0.57]# make 
cp lib/MHA/BinlogManager.pm blib/lib/MHA/BinlogManager.pm
cp lib/MHA/BinlogPosFindManager.pm blib/lib/MHA/BinlogPosFindManager.pm
cp lib/MHA/BinlogPosFinderXid.pm blib/lib/MHA/BinlogPosFinderXid.pm
cp lib/MHA/BinlogHeaderParser.pm blib/lib/MHA/BinlogHeaderParser.pm
cp lib/MHA/BinlogPosFinder.pm blib/lib/MHA/BinlogPosFinder.pm
cp lib/MHA/NodeUtil.pm blib/lib/MHA/NodeUtil.pm
cp lib/MHA/BinlogPosFinderElp.pm blib/lib/MHA/BinlogPosFinderElp.pm
cp lib/MHA/SlaveUtil.pm blib/lib/MHA/SlaveUtil.pm
cp lib/MHA/NodeConst.pm blib/lib/MHA/NodeConst.pm
cp bin/filter_mysqlbinlog blib/script/filter_mysqlbinlog
/usr/bin/perl "-Iinc" -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/filter_mysqlbinlog
cp bin/apply_diff_relay_logs blib/script/apply_diff_relay_logs
/usr/bin/perl "-Iinc" -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/apply_diff_relay_logs
cp bin/purge_relay_logs blib/script/purge_relay_logs
/usr/bin/perl "-Iinc" -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/purge_relay_logs
cp bin/save_binary_logs blib/script/save_binary_logs
/usr/bin/perl "-Iinc" -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/save_binary_logs
Manifying blib/man1/filter_mysqlbinlog.1
Manifying blib/man1/apply_diff_relay_logs.1
Manifying blib/man1/purge_relay_logs.1
Manifying blib/man1/save_binary_logs.1

[root@rs1 mha4mysql-node-0.57]# make install
Installing /usr/local/share/perl5/MHA/BinlogManager.pm
Installing /usr/local/share/perl5/MHA/BinlogPosFindManager.pm
Installing /usr/local/share/perl5/MHA/BinlogPosFinderXid.pm
Installing /usr/local/share/perl5/MHA/BinlogHeaderParser.pm
Installing /usr/local/share/perl5/MHA/BinlogPosFinder.pm
Installing /usr/local/share/perl5/MHA/NodeUtil.pm
Installing /usr/local/share/perl5/MHA/BinlogPosFinderElp.pm
Installing /usr/local/share/perl5/MHA/SlaveUtil.pm
Installing /usr/local/share/perl5/MHA/NodeConst.pm
Installing /usr/local/share/man/man1/filter_mysqlbinlog.1
Installing /usr/local/share/man/man1/apply_diff_relay_logs.1
Installing /usr/local/share/man/man1/purge_relay_logs.1
Installing /usr/local/share/man/man1/save_binary_logs.1
Installing /usr/local/bin/filter_mysqlbinlog
Installing /usr/local/bin/apply_diff_relay_logs
Installing /usr/local/bin/purge_relay_logs
Installing /usr/local/bin/save_binary_logs

# node组件安装后在bin下面会生成几个工具(这些工具通常由 MHAManager 的脚本触发,无需人为操作)
[root@rs1 mha4mysql-node-0.57]# ll bin
total 44
-rwxr-xr-x. 1 1001 1001 16381 May 31  2015 apply_diff_relay_logs
-rwxr-xr-x. 1 1001 1001  4807 May 31  2015 filter_mysqlbinlog
-rwxr-xr-x. 1 1001 1001  8261 May 31  2015 purge_relay_logs
-rwxr-xr-x. 1 1001 1001  7525 May 31  2015 save_binary_logs
# 同时会复制到 /usr/local/bin下
[root@rs1 mha4mysql-node-0.57]# ls /usr/local/bin
apply_diff_relay_logs  filter_mysqlbinlog  purge_relay_logs  save_binary_logs

rs2:

[root@rs2 ~]# mkdir /usr/local/mha-node
[root@rs2 ~]# tar -xf mha4mysql-node-0.57.tar.gz -C /usr/local/mha-node
[root@rs2 ~]# yum install -y perl-DBD-MySQL \
> perl-Config-Tiny \
> perl-Log-Dispatch \
> perl-Parallel-ForkManager \
> perl-ExtUtils-CBuilder \
> perl-ExtUtils-MakeMaker \
> perl-CPAN
[root@rs2 ~]# cd /usr/local/mha-node/mha4mysql-node-0.57/
[root@rs2 mha4mysql-node-0.57]# perl Makefile.PL
[root@rs2 mha4mysql-node-0.57]# make && make install

nfs:

[root@nfs ~]# mkdir /usr/local/mha-node
[root@nfs ~]# tar -xf mha4mysql-node-0.57.tar.gz -C /usr/local/mha-node
[root@nfs ~]# yum install -y perl-DBD-MySQL \
> perl-Config-Tiny \
> perl-Log-Dispatch \
> perl-Parallel-ForkManager \
> perl-ExtUtils-CBuilder \
> perl-ExtUtils-MakeMaker \
> perl-CPAN
[root@nfs ~]# cd /usr/local/mha-node/mha4mysql-node-0.57/
[root@nfs mha4mysql-node-0.57]# perl Makefile.PL
[root@nfs mha4mysql-node-0.57]# make && make install

mha-manager:

[root@mha-manager ~]# ls
mha4mysql-node-0.57.tar.gz
[root@mha-manager mha]# mkdir /usr/local/mha-node
[root@mha-manager mha]# tar -xf mha4mysql-node-0.57.tar.gz -C /usr/local/mha-node
[root@mha-manager ~]# yum install -y perl-DBD-MySQL \	# 需要epel源
> perl-Config-Tiny \
> perl-ExtUtils-CBuilder \
> perl-Log-Dispatch \
> perl-Parallel-ForkManager \
> perl-ExtUtils-MakeMaker \
> perl-CPAN
[root@mha-manager ~]# cd /usr/local/mha-node/mha4mysql-node-0.57/
[root@mha-manager mha4mysql-node-0.57]# perl Makefile.PL
[root@mha-manager mha4mysql-node-0.57]# make
[root@mha-manager mha4mysql-node-0.57]# make install

mha-manager节点同时安装并配置MHA

[root@mha-manager ~]# ls
mha4mysql-manager-0.57.tar.gz
[root@mha-manager ~]# mkdir /usr/local/mha-manager
[root@mha-manager ~]# tar xf mha4mysql-manager-0.57.tar.gz -C /usr/local/mha-manager
[root@mha-manager ~]# cd /usr/local/mha-manager/mha4mysql-manager-0.57/
[root@mha-manager mha4mysql-manager-0.57]# perl Makefile.PL
*** Module::AutoInstall version 1.06
*** Checking for Perl dependencies...
[Core Features]
- DBI                   ...loaded. (1.627)
- DBD::mysql            ...loaded. (4.023)
- Time::HiRes           ...loaded. (1.9725)
- Config::Tiny          ...loaded. (2.14)
- Log::Dispatch         ...missing.
- Parallel::ForkManager ...missing.
- MHA::NodeConst        ...loaded. (0.57)
==> Auto-install the 2 mandatory module(s) from CPAN? [y] y
*** Dependencies will be installed the next time you type 'make'.
*** Module::AutoInstall configuration finished.
Checking if your kit is complete...
Looks good
Warning: prerequisite Log::Dispatch 0 not found.
Warning: prerequisite Parallel::ForkManager 0 not found.
Writing Makefile for mha4mysql::manager

[root@mha-manager mha4mysql-manager-0.57]# make && make install
# 时间比较长

# manager组件安装后在/usr/local/bin下面会生成几个工具
[root@mha-manager mha4mysql-manager-0.57]# ll bin
total 40
-rwxr-xr-x. 1 1001 1001 1995 May 31  2015 masterha_check_repl	# 检查 MySQL 复制状况
-rwxr-xr-x. 1 1001 1001 1779 May 31  2015 masterha_check_ssh	# 检查 MHA 的 SSH 配置状况
-rwxr-xr-x. 1 1001 1001 1865 May 31  2015 masterha_check_status	# 检测当前 MHA 运行状态
-rwxr-xr-x. 1 1001 1001 3201 May 31  2015 masterha_conf_host	# 添加或删除配置的 server 信息
-rwxr-xr-x. 1 1001 1001 2517 May 31  2015 masterha_manager		# 启动 manager的脚本
-rwxr-xr-x. 1 1001 1001 2165 May 31  2015 masterha_master_monitor	# 检测 master 是否宕机
-rwxr-xr-x. 1 1001 1001 2373 May 31  2015 masterha_master_switch	# 控制故障转移(自动或者手动)
-rwxr-xr-x. 1 1001 1001 5171 May 31  2015 masterha_secondary_check	# 当MHA manager检测到master不可用时,通过masterha_secondary_check脚本来进一步确认,减低误切的风险。
-rwxr-xr-x. 1 1001 1001 1739 May 31  2015 masterha_stop		# 关闭manager
# 复制上述所有脚本到/usr/local/bin 目录下
[root@mha-manager ~]# cp /usr/local/mha-manager/mha4mysql-manager-0.57/bin/* /usr/local/bin/



# 另有如下几个需自定义的脚本:
[root@mha-manager mha4mysql-manager-0.57]# ll samples/scripts/
total 32
-rwxr-xr-x. 1 1001 1001  3648 May 31  2015 master_ip_failover	# 自动切换时 VIP 管理的脚本
-rwxr-xr-x. 1 1001 1001  9870 May 31  2015 master_ip_online_change		# 在线切换时 vip 的管理
-rwxr-xr-x. 1 1001 1001 11867 May 31  2015 power_manager		# 故障发生后关闭主机的脚本
-rwxr-xr-x. 1 1001 1001  1360 May 31  2015 send_report		# 因故障切换后发送报警的脚本

# 复制上述所有脚本到/usr/local/bin 目录下
[root@mha-manager mha4mysql-manager-0.57]# cp samples/scripts/* /usr/local/bin/


# VIP配置可以采用两种方式,一是通过引入Keepalived来管理VIP,另一种是在上面脚本中手动配置管理。
# 对于keepalived管理VIP,存在脑裂情况,即当主从网络出现问题时,slave会抢占VIP,这样会导致主从数据库都持有VIP,造成IP冲突,所以在网络不是很好的情况下,不建议采用keepalived服务。
# 在实际生产中使用较多的也是第二种,即在脚本中手动管理VIP,所以,对keepalived不感兴趣的童鞋可直接跳过第一种方式。
# 官方对于master_ip_failover,master_ip_online_change,send_report脚本,给出的只是sample,切换的逻辑需要自己定义。
# 修改master_ip_failover脚本,该脚本主要作用是用于自动主从故障切换和VIP的漂移(没有使用 keepalived ,通过脚本的方式管理vip。)
[root@mha-manager mha4mysql-manager-0.57]# vim /usr/local/bin/master_ip_failover 
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';

use Getopt::Long;

my (
$command, $ssh_user, $orig_master_host, $orig_master_ip,
$orig_master_port, $new_master_host, $new_master_ip, $new_master_port
);

my $vip = '192.168.126.200/24';	#指定vip的地址
my $ifdev = 'ens32';			#指定vip绑定的网卡
my $key = '1';					#指定vip绑定的虚拟网卡序列号
my $ssh_start_vip = "/sbin/ifconfig $ifdev:$key $vip";	#代表此变量值为ifconfig ens32:1 192.168.126.200
my $ssh_stop_vip = "/sbin/ifconfig $ifdev:$key down";	#代表此变量值为ifconfig ens32:1 192.168.126.200 down
my $exit_code = 0;

GetOptions(
'command=s' => \$command,
'ssh_user=s' => \$ssh_user,
'orig_master_host=s' => \$orig_master_host,
'orig_master_ip=s' => \$orig_master_ip,
'orig_master_port=i' => \$orig_master_port,
'new_master_host=s' => \$new_master_host,
'new_master_ip=s' => \$new_master_ip,
'new_master_port=i' => \$new_master_port,
);

exit &main();

sub main {

print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";

if ( $command eq "stop" || $command eq "stopssh" ) {

my $exit_code = 1;
eval {
print "Disabling the VIP on old master: $orig_master_host \n";
&stop_vip();
$exit_code = 0;
};
if ($@) {
warn "Got Error: $@\n";
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "start" ) {

my $exit_code = 10;
eval {
print "Enabling the VIP - $vip on the new master - $new_master_host \n";
&start_vip();
$exit_code = 0;
};
if ($@) {
warn $@;
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "status" ) {
print "Checking the Status of the script.. OK \n";
exit 0;
}
else {
&usage();
exit 1;
}
}
sub start_vip() {
`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
## A simple system call that disable the VIP on the old_master
sub stop_vip() {
`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}

sub usage {
print
"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}


# 修改master_ip_online_change脚本,该脚本主要作用是用于在线手动主从切换和VIP的漂移(多用于诸如硬件升级,MySQL数据库迁移等等)

[root@mha-manager ~]# vim /usr/local/bin/master_ip_online_change
#!/usr/bin/env perl

use strict;
use warnings FATAL => 'all';

use Getopt::Long;
use MHA::DBHelper;
use MHA::NodeUtil;
use Time::HiRes qw( sleep gettimeofday tv_interval );
use Data::Dumper;

my $vip = '192.168.126.200/24';  # Virtual IP
my $ifdev = 'ens32';  
my $key = "1";  
my $ssh_start_vip = "/usr/sbin/ifconfig $ifdev:$key $vip";  
my $ssh_stop_vip = "/usr/sbin/ifconfig $ifdev:$key down";  
my $exit_code = 0;  
my $_tstart;
my $_running_interval = 0.1;
my (
  $command,              $orig_master_is_new_slave, $orig_master_host,
  $orig_master_ip,       $orig_master_port,         $orig_master_user,
  $orig_master_password, $orig_master_ssh_user,     $new_master_host,
  $new_master_ip,        $new_master_port,          $new_master_user,
  $new_master_password,  $new_master_ssh_user,
);
GetOptions(
  'command=s'                => \$command,
  'orig_master_is_new_slave' => \$orig_master_is_new_slave,
  'orig_master_host=s'       => \$orig_master_host,
  'orig_master_ip=s'         => \$orig_master_ip,
  'orig_master_port=i'       => \$orig_master_port,
  'orig_master_user=s'       => \$orig_master_user,
  'orig_master_password=s'   => \$orig_master_password,
  'orig_master_ssh_user=s'   => \$orig_master_ssh_user,
  'new_master_host=s'        => \$new_master_host,
  'new_master_ip=s'          => \$new_master_ip,
  'new_master_port=i'        => \$new_master_port,
  'new_master_user=s'        => \$new_master_user,
  'new_master_password=s'    => \$new_master_password,
  'new_master_ssh_user=s'    => \$new_master_ssh_user,
);

exit &main();

sub current_time_us {
  my ( $sec, $microsec ) = gettimeofday();
  my $curdate = localtime($sec);
  return $curdate . " " . sprintf( "%06d", $microsec );
}

sub sleep_until {
  my $elapsed = tv_interval($_tstart);
  if ( $_running_interval > $elapsed ) {
    sleep( $_running_interval - $elapsed );
  }
}

sub get_threads_util {
  my $dbh                    = shift;
  my $my_connection_id       = shift;
  my $running_time_threshold = shift;
  my $type                   = shift;
  $running_time_threshold = 0 unless ($running_time_threshold);
  $type                   = 0 unless ($type);
  my @threads;

  my $sth = $dbh->prepare("SHOW PROCESSLIST");
  $sth->execute();

  while ( my $ref = $sth->fetchrow_hashref() ) {
    my $id         = $ref->{Id};
    my $user       = $ref->{User};
    my $host       = $ref->{Host};
    my $command    = $ref->{Command};
    my $state      = $ref->{State};
    my $query_time = $ref->{Time};
    my $info       = $ref->{Info};
    $info =~ s/^\s*(.*?)\s*$/$1/ if defined($info);
    next if ( $my_connection_id == $id );
    next if ( defined($query_time) && $query_time < $running_time_threshold );
    next if ( defined($command)    && $command eq "Binlog Dump" );
    next if ( defined($user)       && $user eq "system user" );
    next
      if ( defined($command)
      && $command eq "Sleep"
      && defined($query_time)
      && $query_time >= 1 );

    if ( $type >= 1 ) {
      next if ( defined($command) && $command eq "Sleep" );
      next if ( defined($command) && $command eq "Connect" );
    }

    if ( $type >= 2 ) {
      next if ( defined($info) && $info =~ m/^select/i );
      next if ( defined($info) && $info =~ m/^show/i );
    }

    push @threads, $ref;
  }
  return @threads;
}

sub main {
  if ( $command eq "stop" ) {
    ## Gracefully killing connections on the current master
    # 1. Set read_only= 1 on the new master
    # 2. DROP USER so that no app user can establish new connections
    # 3. Set read_only= 1 on the current master
    # 4. Kill current queries
    # * Any database access failure will result in script die.
    my $exit_code = 1;
    eval {
      ## Setting read_only=1 on the new master (to avoid accident)
      my $new_master_handler = new MHA::DBHelper();

      # args: hostname, port, user, password, raise_error(die_on_error)_or_not
      $new_master_handler->connect( $new_master_ip, $new_master_port,
        $new_master_user, $new_master_password, 1 );
      print current_time_us() . " Set read_only on the new master.. ";
      $new_master_handler->enable_read_only();
      if ( $new_master_handler->is_read_only() ) {
        print "ok.\n";
      }
      else {
        die "Failed!\n";
      }
      $new_master_handler->disconnect();

      # Connecting to the orig master, die if any database error happens
      my $orig_master_handler = new MHA::DBHelper();
      $orig_master_handler->connect( $orig_master_ip, $orig_master_port,
        $orig_master_user, $orig_master_password, 1 );

      ## Drop application user so that nobody can connect. Disabling per-session binlog beforehand
      $orig_master_handler->disable_log_bin_local();
      print current_time_us() . " Drpping app user on the orig master..\n";
      FIXME_xxx_drop_app_user($orig_master_handler);

      ## Waiting for N * 100 milliseconds so that current connections can exit
      my $time_until_read_only = 15;
      $_tstart = [gettimeofday];
      my @threads = get_threads_util( $orig_master_handler->{dbh},
        $orig_master_handler->{connection_id} );
      while ( $time_until_read_only > 0 && $#threads >= 0 ) {
        if ( $time_until_read_only % 5 == 0 ) {
          printf
"%s Waiting all running %d threads are disconnected.. (max %d milliseconds)\n",
            current_time_us(), $#threads + 1, $time_until_read_only * 100;
          if ( $#threads < 5 ) {
            print Data::Dumper->new( [$_] )->Indent(0)->Terse(1)->Dump . "\n"
              foreach (@threads);
          }
        }
        sleep_until();
        $_tstart = [gettimeofday];
        $time_until_read_only--;
        @threads = get_threads_util( $orig_master_handler->{dbh},
          $orig_master_handler->{connection_id} );
      }

      ## Setting read_only=1 on the current master so that nobody(except SUPER) can write
      print current_time_us() . " Set read_only=1 on the orig master.. ";
      $orig_master_handler->enable_read_only();
      if ( $orig_master_handler->is_read_only() ) {
        print "ok.\n";
      }
      else {
        die "Failed!\n";
      }

      ## Waiting for M * 100 milliseconds so that current update queries can complete
      my $time_until_kill_threads = 5;
      @threads = get_threads_util( $orig_master_handler->{dbh},
        $orig_master_handler->{connection_id} );
      while ( $time_until_kill_threads > 0 && $#threads >= 0 ) {
        if ( $time_until_kill_threads % 5 == 0 ) {
          printf
"%s Waiting all running %d queries are disconnected.. (max %d milliseconds)\n",
            current_time_us(), $#threads + 1, $time_until_kill_threads * 100;
          if ( $#threads < 5 ) {
            print Data::Dumper->new( [$_] )->Indent(0)->Terse(1)->Dump . "\n"
              foreach (@threads);
          }
        }
        sleep_until();
        $_tstart = [gettimeofday];
        $time_until_kill_threads--;
        @threads = get_threads_util( $orig_master_handler->{dbh},
          $orig_master_handler->{connection_id} );
      }

      ## Terminating all threads
      print current_time_us() . " Killing all application threads..\n";
      $orig_master_handler->kill_threads(@threads) if ( $#threads >= 0 );
      print current_time_us() . " done.\n";
      $orig_master_handler->enable_log_bin_local();
      $orig_master_handler->disconnect();

      ## After finishing the script, MHA executes FLUSH TABLES WITH READ LOCK
      $exit_code = 0;
    };
    if ($@) {
      warn "Got Error: $@\n";
      exit $exit_code;
    }
    exit $exit_code;
  }
  elsif ( $command eq "start" ) {
    ## Activating master ip on the new master
    # 1. Create app user with write privileges
    # 2. Moving backup script if needed
    # 3. Register new master's ip to the catalog database

# We don't return error even though activating updatable accounts/ip failed so that we don't interrupt slaves' recovery.
# If exit code is 0 or 10, MHA does not abort
    my $exit_code = 10;
    eval {
      my $new_master_handler = new MHA::DBHelper();

      # args: hostname, port, user, password, raise_error_or_not
      $new_master_handler->connect( $new_master_ip, $new_master_port,
        $new_master_user, $new_master_password, 1 );

      ## Set read_only=0 on the new master
      $new_master_handler->disable_log_bin_local();
      print current_time_us() . " Set read_only=0 on the new master.\n";
      $new_master_handler->disable_read_only();

      ## Creating an app user on the new master
      print current_time_us() . " Creating app user on the new master..\n";
      FIXME_xxx_create_app_user($new_master_handler);
      $new_master_handler->enable_log_bin_local();
      $new_master_handler->disconnect();

      ## Update master ip on the catalog database, etc
      $exit_code = 0;
    };
    if ($@) {
      warn "Got Error: $@\n";
      exit $exit_code;
    }
    exit $exit_code;
  }
  elsif ( $command eq "status" ) {

    # do nothing
    exit 0;
  }
  else {
    &usage();
    exit 1;
  }
}

sub usage {
  print
"Usage: master_ip_online_change --command=start|stop|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
  die;
}
# master_ip_online_change_script 指的是手动执行mysql master switchover时执行的切换脚本
# 一般用法: masterha_master_switch --conf=/etc/masterha/app1.cnf --master_state=alive --new_master_host=192.168.8.57 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=10000





# 创建 MHA 工作目录并复制配置文件,使用app1.cnf配置文件来管理 mysql 节点服务器,配置文件一般放在/etc/目录下
[root@mha-manager mha4mysql-manager-0.57]# mkdir /etc/masterha
[root@mha-manager mha4mysql-manager-0.57]# cp samples/conf/app1.cnf /etc/masterha/
# 删除原有内容,直接复制并修改节点服务器的IP地址
[root@mha-manager mha4mysql-manager-0.57]# vim /etc/masterha/app1.cnf 
[server default]
manager_log=/var/log/masterha/app1/manager.log    #manager日志
manager_workdir=/var/log/masterha/app1.log      #manager工作目录
master_binlog_dir=/var/lib/mysql/	         #master保存binlog的位置,这里的路径要与master里配置的binlog的路径一致,以便MHA能找到
master_ip_failover_script=/usr/local/bin/master_ip_failover            #设置自动failover时候的切换脚本,也就是上面的那个脚本
master_ip_online_change_script=/usr/local/bin/master_ip_online_change  #设置手动在线切换的脚本
user=mha                                #设置监控用户名
password=linux123.COM                   #设置mysql中用于监控mha用户的那个密码
ping_interval=1                         #设置监控主库,发送ping包的时间间隔1秒,默认是3秒,尝试三次没有回应的时候自动进行failover
remote_workdir=/tmp/        #设置远端mysql在发生切换时binlog的保存位置
repl_user=copy                          #设置mysql中用于主从复制的用户名
repl_password=linux123.COM              #设置mysql中用于主从复制的用户的密码
report_script=/usr/local/bin/send_report     #设置发生切换后发送的报警的脚本
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.126.93 -s 192.168.126.94      #指定检查的从服务器IP地址
shutdown_script=""                      #设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机防止发生脑裂,这里没有使用)
ssh_user=root                           #设置ssh的登录用户名


[server1]
hostname=rs1
port=3306

[server2]
hostname=rs2
port=3306
candidate_master=1
#设置为候选master,设置该参数以后,发生主从切换以后将会将此从库提升为主库,即使这个主库不是集群中最新的slave

check_repl_delay=0
#默认情况下如果一个slave落后master 超过100M的relay logs的话,MHA将不会选择该slave作为一个新的master, 因为对于这个slave的恢复需要花费很长时间;通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将
会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master

[server3]
hostname=nfs
port=3306


# 在主库rs服务器上手动开启vip
[root@rs1 mha4mysql-node-0.57]# ifconfig ens32:1 192.168.126.200/24

# 在 mha-manager 节点上测试 ssh 无密码认证,如果正常最后会输出 successfully。
[root@mha-manager mha4mysql-manager-0.57]# masterha_check_ssh -conf=/etc/masterha/app1.cnf
Sat Sep 25 15:47:10 2021 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Sat Sep 25 15:47:10 2021 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
Sat Sep 25 15:47:10 2021 - [info] Reading server configuration from /etc/masterha/app1.cnf..
Sat Sep 25 15:47:10 2021 - [info] Starting SSH connection tests..
Sat Sep 25 15:47:12 2021 - [debug] 
Sat Sep 25 15:47:10 2021 - [debug]  Connecting via SSH from root@192.168.126.92(192.168.126.92:22) to root@192.168.126.93(192.168.126.93:22)..
Sat Sep 25 15:47:11 2021 - [debug]   ok.
Sat Sep 25 15:47:11 2021 - [debug]  Connecting via SSH from root@192.168.126.92(192.168.126.92:22) to root@192.168.126.94(192.168.126.94:22)..
Sat Sep 25 15:47:11 2021 - [debug]   ok.
Sat Sep 25 15:47:13 2021 - [debug] 
Sat Sep 25 15:47:11 2021 - [debug]  Connecting via SSH from root@192.168.126.93(192.168.126.93:22) to root@192.168.126.92(192.168.126.92:22)..
Sat Sep 25 15:47:11 2021 - [debug]   ok.
Sat Sep 25 15:47:11 2021 - [debug]  Connecting via SSH from root@192.168.126.93(192.168.126.93:22) to root@192.168.126.94(192.168.126.94:22)..
Sat Sep 25 15:47:12 2021 - [debug]   ok.
Sat Sep 25 15:47:13 2021 - [debug] 
Sat Sep 25 15:47:11 2021 - [debug]  Connecting via SSH from root@192.168.126.94(192.168.126.94:22) to root@192.168.126.92(192.168.126.92:22)..
Sat Sep 25 15:47:12 2021 - [debug]   ok.
Sat Sep 25 15:47:12 2021 - [debug]  Connecting via SSH from root@192.168.126.94(192.168.126.94:22) to root@192.168.126.93(192.168.126.93:22)..
Sat Sep 25 15:47:12 2021 - [debug]   ok.
Sat Sep 25 15:47:13 2021 - [info] All SSH connection tests passed successfully.
# 如果上面出现Can't locate MHA/SSHCheck.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at bin/masterha_check_ssh line 25.
# BEGIN failed--compilation aborted at bin/masterha_check_ssh line 25.问题,则解决方法为:
#[root@mha-manager mha4mysql-manager-0.57]# find / -name SSHCheck.pm
#/usr/local/mha-manager/mha4mysql-manager-0.57/lib/MHA/SSHCheck.pm
#/usr/local/mha-manager/mha4mysql-manager-0.57/blib/lib/MHA/SSHCheck.pm
#[root@mha-manager mha4mysql-manager-0.57]# export PERL5LIB=$PERL5LIB:/usr/local/mha-manager#/mha4mysql-manager-0.57/lib/
#[root@mha-manager mha4mysql-manager-0.57]# export PERL5LIB=$PERL5LIB:/usr/local/mha-manager#/mha4mysql-manager-0.57/blib/lib/
# 或者写入/etc/profile文件中


# 在 manager 节点上测试 mysql 主从连接情况,最后出现 MySQL Replication Health is OK 字样说明正常。
[root@mha-manager mha4mysql-manager-0.57]# masterha_check_repl -conf=/etc/masterha/app1.cnf
Sat Sep 25 16:06:34 2021 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Sat Sep 25 16:06:34 2021 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
Sat Sep 25 16:06:34 2021 - [info] Reading server configuration from /etc/masterha/app1.cnf..
Sat Sep 25 16:06:34 2021 - [info] MHA::MasterMonitor version 0.57.
Sat Sep 25 16:06:35 2021 - [info] GTID failover mode = 0
Sat Sep 25 16:06:35 2021 - [info] Dead Servers:
Sat Sep 25 16:06:35 2021 - [info] Alive Servers:
Sat Sep 25 16:06:35 2021 - [info]   rs1(192.168.126.92:3306)
Sat Sep 25 16:06:35 2021 - [info]   rs2(192.168.126.93:3306)
Sat Sep 25 16:06:35 2021 - [info]   nfs(192.168.126.94:3306)
Sat Sep 25 16:06:35 2021 - [info] Alive Slaves:
Sat Sep 25 16:06:35 2021 - [info]   rs2(192.168.126.93:3306)  Version=8.0.16 (oldest major version between slaves) log-bin:enabled
Sat Sep 25 16:06:35 2021 - [info]     Replicating from rs1(192.168.126.92:3306)
Sat Sep 25 16:06:35 2021 - [info]     Primary candidate for the new Master (candidate_master is set)
Sat Sep 25 16:06:35 2021 - [info]   nfs(192.168.126.94:3306)  Version=8.0.16 (oldest major version between slaves) log-bin:enabled
Sat Sep 25 16:06:35 2021 - [info]     Replicating from rs1(192.168.126.92:3306)
Sat Sep 25 16:06:35 2021 - [info] Current Alive Master: rs1(192.168.126.92:3306)
Sat Sep 25 16:06:35 2021 - [info] Checking slave configurations..
Sat Sep 25 16:06:35 2021 - [info]  read_only=1 is not set on slave rs2(192.168.126.93:3306).
Sat Sep 25 16:06:35 2021 - [warning]  relay_log_purge=0 is not set on slave rs2(192.168.126.93:3306).
Sat Sep 25 16:06:35 2021 - [info]  read_only=1 is not set on slave nfs(192.168.126.94:3306).
Sat Sep 25 16:06:35 2021 - [warning]  relay_log_purge=0 is not set on slave nfs(192.168.126.94:3306).
Sat Sep 25 16:06:35 2021 - [info] Checking replication filtering settings..
Sat Sep 25 16:06:35 2021 - [info]  binlog_do_db= , binlog_ignore_db= information_schema,mysql,performance_schema,sys
Sat Sep 25 16:06:35 2021 - [info]  Replication filtering check ok.
Sat Sep 25 16:06:35 2021 - [info] GTID (with auto-pos) is not supported
Sat Sep 25 16:06:35 2021 - [info] Starting SSH connection tests..
Sat Sep 25 16:06:38 2021 - [info] All SSH connection tests passed successfully.
Sat Sep 25 16:06:38 2021 - [info] Checking MHA Node version..
Sat Sep 25 16:06:38 2021 - [info]  Version check ok.
Sat Sep 25 16:06:38 2021 - [info] Checking SSH publickey authentication settings on the current master..
Sat Sep 25 16:06:38 2021 - [info] HealthCheck: SSH to rs1 is reachable.
Sat Sep 25 16:06:39 2021 - [info] Master MHA Node version is 0.57.
Sat Sep 25 16:06:39 2021 - [info] Checking recovery script configurations on rs1(192.168.126.92:3306)..
Sat Sep 25 16:06:39 2021 - [info]   Executing command: save_binary_logs --command=test --start_pos=4 --binlog_dir=/var/lib/mysql/ --output_file=/tmp/save_binary_logs_test --manager_version=0.57 --start_file=mysql1-bin.000002 
Sat Sep 25 16:06:39 2021 - [info]   Connecting to root@192.168.126.92(rs1:22).. 
  Creating /tmp if not exists..    ok.
  Checking output directory is accessible or not..
   ok.
  Binlog found at /var/lib/mysql/, up to mysql1-bin.000002
Sat Sep 25 16:06:39 2021 - [info] Binlog setting check done.
Sat Sep 25 16:06:39 2021 - [info] Checking SSH publickey authentication and checking recovery script configurations on all alive slave servers..
Sat Sep 25 16:06:39 2021 - [info]   Executing command : apply_diff_relay_logs --command=test --slave_user='mha' --slave_host=rs2 --slave_ip=192.168.126.93 --slave_port=3306 --workdir=/tmp --target_version=8.0.16 --manager_version=0.57 --relay_dir=/var/lib/mysql --current_relay_log=relay2-log.000006  --slave_pass=xxx
Sat Sep 25 16:06:39 2021 - [info]   Connecting to root@192.168.126.93(rs2:22).. 
  Checking slave recovery environment settings..
    Relay log found at /var/lib/mysql, up to relay2-log.000006
    Temporary relay log file is /var/lib/mysql/relay2-log.000006
    Testing mysql connection and privileges..mysql: [Warning] Using a password on the command line interface can be insecure.
 done.
    Testing mysqlbinlog output.. done.
    Cleaning up test file(s).. done.
Sat Sep 25 16:06:39 2021 - [info]   Executing command : apply_diff_relay_logs --command=test --slave_user='mha' --slave_host=nfs --slave_ip=192.168.126.94 --slave_port=3306 --workdir=/tmp --target_version=8.0.16 --manager_version=0.57 --relay_dir=/var/lib/mysql --current_relay_log=relay3-log.000006  --slave_pass=xxx
Sat Sep 25 16:06:39 2021 - [info]   Connecting to root@192.168.126.94(nfs:22).. 
  Checking slave recovery environment settings..
    Relay log found at /var/lib/mysql, up to relay3-log.000006
    Temporary relay log file is /var/lib/mysql/relay3-log.000006
    Testing mysql connection and privileges..mysql: [Warning] Using a password on the command line interface can be insecure.
 done.
    Testing mysqlbinlog output.. done.
    Cleaning up test file(s).. done.
Sat Sep 25 16:06:40 2021 - [info] Slaves settings check done.
Sat Sep 25 16:06:40 2021 - [info] 
rs1(192.168.126.92:3306) (current master)
 +--rs2(192.168.126.93:3306)
 +--nfs(192.168.126.94:3306)

Sat Sep 25 16:06:40 2021 - [info] Checking replication health on rs2..
Sat Sep 25 16:06:40 2021 - [info]  ok.
Sat Sep 25 16:06:40 2021 - [info] Checking replication health on nfs..
Sat Sep 25 16:06:40 2021 - [info]  ok.
Sat Sep 25 16:06:40 2021 - [info] Checking master_ip_failover_script status:
Sat Sep 25 16:06:40 2021 - [info]   /usr/local/bin/master_ip_failover --command=status --ssh_user=root --orig_master_host=rs1 --orig_master_ip=192.168.126.92 --orig_master_port=3306 


IN SCRIPT TEST====/sbin/ifconfig ens32:1 down==/sbin/ifconfig ens32:1 192.168.126.200===

Checking the Status of the script.. OK 
Sat Sep 25 16:06:40 2021 - [info]  OK.
Sat Sep 25 16:06:40 2021 - [warning] shutdown_script is not defined.
Sat Sep 25 16:06:40 2021 - [info] Got exit code 0 (Not master dead).

MySQL Replication Health is OK.	


# 在 mha-manager 节点上启动 MHA
[root@mha-manager masterha]# nohup masterha_manager --conf=/etc/masterha/app1.cnf > /etc/masterha/mha.log  < /dev/null 2>&1 &
[1] 16524

# --remove_dead_master_conf	该参数代表当发生主从切换后,老的主库的 ip 将会从配置文件中移除。
# --ignore_last_failover:在缺省情况下,如果 MHA 检测到连续发生宕机,且两次宕机间隔不足 8 小时的话,则不会进行 Failover, 之所以这样限制是为了避免 ping-pong 效应。该参数代表忽略上次 MHA 触发切换产生的文件,默认情况下,MHA 发生切换后会在日志记目录,也就是上面设置的日志app1.failover.complete文件,下次再次切换的时候如果发现该目录下存在该文件将不允许触发切换,除非在第一次切换后收到删除该文件,为了方便,这里设置为–ignore_last_failover。
# 关闭 manager 服务: bin/masterha_stop --conf=/etc/masterha/app1.cnf

# 查看 MHA 状态,可以看到当前的 master 是 rs1 节点。
[root@mha-manager masterha]# masterha_check_status --conf=/etc/masterha/app1.cnf
app1 (pid:16524) is running(0:PING_OK), master:rs1
# 查看 MHA 日志,也以看到当前的 master 是 rs1(192.168.168.92)
[root@mha-manager masterha]# cat /etc/masterha/mha.log | grep "current master"
Sun Sep 26 13:04:53 2021 - [info] Checking SSH publickey authentication settings on the current master..
rs1(192.168.126.92:3306) (current master)

# 查看 rs1 的 VIP 地址 192.168.126.200 是否存在,这个 VIP 地址不会因为 manager 节点停止 MHA 服务而消失。
[root@rs1 mha4mysql-node-0.57]# ip a | grep 192.168.126.200
    inet 192.168.126.200/24 brd 192.168.126.255 scope global secondary ens32:1

故障模拟

# 在 mha-manager 节点上监控观察日志记录
[root@mha-manager mha4mysql-manager-0.57]# tailf /etc/masterha/mha.log 

# 在 rs1 节点停止mysql服务
[root@rs1 ~]# systemctl stop mysqld

[root@mha-manager mha4mysql-manager-0.57]# tailf /etc/masterha/mha.log 

# 查看日志信息
[root@mha-manager mha4mysql-manager-0.57]# tailf /etc/masterha/mha.log 

IN SCRIPT TEST====/usr/sbin/ifconfig ens32:1 down==/usr/sbin/ifconfig ens32:1 192.168.126.200/24===

Checking the Status of the script.. OK 
Sun Sep 26 13:04:54 2021 - [info]  OK.
Sun Sep 26 13:04:54 2021 - [warning] shutdown_script is not defined.
Sun Sep 26 13:04:54 2021 - [info] Set master ping interval 1 seconds.
Sun Sep 26 13:04:54 2021 - [info] Set secondary check script: /usr/local/bin/masterha_secondary_check -s 192.168.126.93 -s 192.168.126.94
Sun Sep 26 13:04:54 2021 - [info] Starting ping health check on rs1(192.168.126.92:3306)..
Sun Sep 26 13:04:54 2021 - [info] Ping(SELECT) succeeded, waiting until MySQL doesn't respond..


Sun Sep 26 13:06:14 2021 - [warning] Got error on MySQL select ping: 2006 (MySQL server has gone away)
Sun Sep 26 13:06:14 2021 - [info] Executing SSH check script: save_binary_logs --command=test --start_pos=4 --binlog_dir=/var/lib/mysql/ --output_file=/tmp/save_binary_logs_test --manager_version=0.57 --binlog_prefix=mysql1-bin
Sun Sep 26 13:06:14 2021 - [info] Executing secondary network check script: /usr/local/bin/masterha_secondary_check -s 192.168.126.93 -s 192.168.126.94  --user=root  --master_host=rs1  --master_ip=192.168.126.92  --master_port=3306 --master_user=mha --master_password=linux123.COM --ping_type=SELECT
Sun Sep 26 13:06:15 2021 - [info] HealthCheck: SSH to rs1 is reachable.
Monitoring server 192.168.126.93 is reachable, Master is not reachable from 192.168.126.93. OK.
Monitoring server 192.168.126.94 is reachable, Master is not reachable from 192.168.126.94. OK.
Sun Sep 26 13:06:15 2021 - [info] Master is not reachable from all other monitoring servers. Failover should start.
Sun Sep 26 13:06:15 2021 - [warning] Got error on MySQL connect: 2003 (Can't connect to MySQL server on '192.168.126.92' (111))
Sun Sep 26 13:06:15 2021 - [warning] Connection failed 2 time(s)..
Sun Sep 26 13:06:16 2021 - [warning] Got error on MySQL connect: 2003 (Can't connect to MySQL server on '192.168.126.92' (111))
Sun Sep 26 13:06:16 2021 - [warning] Connection failed 3 time(s)..
Sun Sep 26 13:06:17 2021 - [warning] Got error on MySQL connect: 2003 (Can't connect to MySQL server on '192.168.126.92' (111))
Sun Sep 26 13:06:17 2021 - [warning] Connection failed 4 time(s)..
Sun Sep 26 13:06:17 2021 - [warning] Master is not reachable from health checker!
Sun Sep 26 13:06:17 2021 - [warning] Master rs1(192.168.126.92:3306) is not reachable!
Sun Sep 26 13:06:17 2021 - [warning] SSH is reachable.
Sun Sep 26 13:06:17 2021 - [info] Connecting to a master server failed. Reading configuration file /etc/masterha_default.cnf and /etc/masterha/app1.cnf again, and trying to connect to all servers to check server status..
Sun Sep 26 13:06:17 2021 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Sun Sep 26 13:06:17 2021 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
Sun Sep 26 13:06:17 2021 - [info] Reading server configuration from /etc/masterha/app1.cnf..
Sun Sep 26 13:06:18 2021 - [info] GTID failover mode = 0
Sun Sep 26 13:06:18 2021 - [info] Dead Servers:
Sun Sep 26 13:06:18 2021 - [info]   rs1(192.168.126.92:3306)
Sun Sep 26 13:06:18 2021 - [info] Alive Servers:
Sun Sep 26 13:06:18 2021 - [info]   rs2(192.168.126.93:3306)
Sun Sep 26 13:06:18 2021 - [info]   nfs(192.168.126.94:3306)
Sun Sep 26 13:06:18 2021 - [info] Alive Slaves:
Sun Sep 26 13:06:18 2021 - [info]   rs2(192.168.126.93:3306)  Version=8.0.16 (oldest major version between slaves) log-bin:enabled
Sun Sep 26 13:06:18 2021 - [info]     Replicating from rs1(192.168.126.92:3306)
Sun Sep 26 13:06:18 2021 - [info]     Primary candidate for the new Master (candidate_master is set)
Sun Sep 26 13:06:18 2021 - [info]   nfs(192.168.126.94:3306)  Version=8.0.16 (oldest major version between slaves) log-bin:enabled
Sun Sep 26 13:06:18 2021 - [info]     Replicating from rs1(192.168.126.92:3306)
Sun Sep 26 13:06:18 2021 - [info] Checking slave configurations..
Sun Sep 26 13:06:18 2021 - [info]  read_only=1 is not set on slave rs2(192.168.126.93:3306).
Sun Sep 26 13:06:18 2021 - [warning]  relay_log_purge=0 is not set on slave rs2(192.168.126.93:3306).
Sun Sep 26 13:06:18 2021 - [info]  read_only=1 is not set on slave nfs(192.168.126.94:3306).
Sun Sep 26 13:06:18 2021 - [warning]  relay_log_purge=0 is not set on slave nfs(192.168.126.94:3306).
Sun Sep 26 13:06:18 2021 - [info] Checking replication filtering settings..
Sun Sep 26 13:06:18 2021 - [info]  Replication filtering check ok.
Sun Sep 26 13:06:18 2021 - [info] Master is down!
Sun Sep 26 13:06:18 2021 - [info] Terminating monitoring script.
Sun Sep 26 13:06:18 2021 - [info] Got exit code 20 (Master dead).
Sun Sep 26 13:06:18 2021 - [info] MHA::MasterFailover version 0.57.
Sun Sep 26 13:06:18 2021 - [info] Starting master failover.
Sun Sep 26 13:06:18 2021 - [info] 
Sun Sep 26 13:06:18 2021 - [info] * Phase 1: Configuration Check Phase..
Sun Sep 26 13:06:18 2021 - [info] 
Sun Sep 26 13:06:19 2021 - [info] GTID failover mode = 0
Sun Sep 26 13:06:19 2021 - [info] Dead Servers:
Sun Sep 26 13:06:19 2021 - [info]   rs1(192.168.126.92:3306)
Sun Sep 26 13:06:19 2021 - [info] Checking master reachability via MySQL(double check)...
Sun Sep 26 13:06:19 2021 - [info]  ok.
Sun Sep 26 13:06:19 2021 - [info] Alive Servers:
Sun Sep 26 13:06:19 2021 - [info]   rs2(192.168.126.93:3306)
Sun Sep 26 13:06:19 2021 - [info]   nfs(192.168.126.94:3306)
Sun Sep 26 13:06:19 2021 - [info] Alive Slaves:
Sun Sep 26 13:06:19 2021 - [info]   rs2(192.168.126.93:3306)  Version=8.0.16 (oldest major version between slaves) log-bin:enabled
Sun Sep 26 13:06:19 2021 - [info]     Replicating from rs1(192.168.126.92:3306)
Sun Sep 26 13:06:19 2021 - [info]     Primary candidate for the new Master (candidate_master is set)
Sun Sep 26 13:06:19 2021 - [info]   nfs(192.168.126.94:3306)  Version=8.0.16 (oldest major version between slaves) log-bin:enabled
Sun Sep 26 13:06:19 2021 - [info]     Replicating from rs1(192.168.126.92:3306)
Sun Sep 26 13:06:19 2021 - [info] Starting Non-GTID based failover.
Sun Sep 26 13:06:19 2021 - [info] 
Sun Sep 26 13:06:19 2021 - [info] ** Phase 1: Configuration Check Phase completed.
Sun Sep 26 13:06:19 2021 - [info] 
Sun Sep 26 13:06:19 2021 - [info] * Phase 2: Dead Master Shutdown Phase..
Sun Sep 26 13:06:19 2021 - [info] 
Sun Sep 26 13:06:19 2021 - [info] Forcing shutdown so that applications never connect to the current master..
Sun Sep 26 13:06:19 2021 - [info] Executing master IP deactivation script:
Sun Sep 26 13:06:19 2021 - [info]   /usr/local/bin/master_ip_failover --orig_master_host=rs1 --orig_master_ip=192.168.126.92 --orig_master_port=3306 --command=stopssh --ssh_user=root  


IN SCRIPT TEST====/usr/sbin/ifconfig ens32:1 down==/usr/sbin/ifconfig ens32:1 192.168.126.200/24===

Disabling the VIP on old master: rs1 
Sun Sep 26 13:06:20 2021 - [info]  done.
Sun Sep 26 13:06:20 2021 - [warning] shutdown_script is not set. Skipping explicit shutting down of the dead master.
Sun Sep 26 13:06:20 2021 - [info] * Phase 2: Dead Master Shutdown Phase completed.
Sun Sep 26 13:06:20 2021 - [info] 
Sun Sep 26 13:06:20 2021 - [info] * Phase 3: Master Recovery Phase..
Sun Sep 26 13:06:20 2021 - [info] 
Sun Sep 26 13:06:20 2021 - [info] * Phase 3.1: Getting Latest Slaves Phase..
Sun Sep 26 13:06:20 2021 - [info] 
Sun Sep 26 13:06:20 2021 - [info] The latest binary log file/position on all slaves is mysql1-bin.000008:155
Sun Sep 26 13:06:20 2021 - [info] Latest slaves (Slaves that received relay log files to the latest):
Sun Sep 26 13:06:20 2021 - [info]   rs2(192.168.126.93:3306)  Version=8.0.16 (oldest major version between slaves) log-bin:enabled
Sun Sep 26 13:06:20 2021 - [info]     Replicating from rs1(192.168.126.92:3306)
Sun Sep 26 13:06:20 2021 - [info]     Primary candidate for the new Master (candidate_master is set)
Sun Sep 26 13:06:20 2021 - [info]   nfs(192.168.126.94:3306)  Version=8.0.16 (oldest major version between slaves) log-bin:enabled
Sun Sep 26 13:06:20 2021 - [info]     Replicating from rs1(192.168.126.92:3306)
Sun Sep 26 13:06:20 2021 - [info] The oldest binary log file/position on all slaves is mysql1-bin.000008:155
Sun Sep 26 13:06:20 2021 - [info] Oldest slaves:
Sun Sep 26 13:06:20 2021 - [info]   rs2(192.168.126.93:3306)  Version=8.0.16 (oldest major version between slaves) log-bin:enabled
Sun Sep 26 13:06:20 2021 - [info]     Replicating from rs1(192.168.126.92:3306)
Sun Sep 26 13:06:20 2021 - [info]     Primary candidate for the new Master (candidate_master is set)
Sun Sep 26 13:06:20 2021 - [info]   nfs(192.168.126.94:3306)  Version=8.0.16 (oldest major version between slaves) log-bin:enabled
Sun Sep 26 13:06:20 2021 - [info]     Replicating from rs1(192.168.126.92:3306)
Sun Sep 26 13:06:20 2021 - [info] 
Sun Sep 26 13:06:20 2021 - [info] * Phase 3.2: Saving Dead Master's Binlog Phase..
Sun Sep 26 13:06:20 2021 - [info] 
Sun Sep 26 13:06:20 2021 - [info] Fetching dead master's binary logs..
Sun Sep 26 13:06:20 2021 - [info] Executing command on the dead master rs1(192.168.126.92:3306): save_binary_logs --command=save --start_file=mysql1-bin.000008  --start_pos=155 --binlog_dir=/var/lib/mysql/ --output_file=/tmp/saved_master_binlog_from_rs1_3306_20210926130618.binlog --handle_raw_binlog=1 --disable_log_bin=0 --manager_version=0.57
  Creating /tmp if not exists..    ok.
 Concat binary/relay logs from mysql1-bin.000008 pos 155 to mysql1-bin.000008 EOF into /tmp/saved_master_binlog_from_rs1_3306_20210926130618.binlog ..
 Binlog Checksum enabled
  Dumping binlog format description event, from position 0 to 155.. ok.
  No need to dump effective binlog data from /var/lib/mysql//mysql1-bin.000008 (pos starts 155, filesize 155). Skipping.
 Binlog Checksum enabled
 /tmp/saved_master_binlog_from_rs1_3306_20210926130618.binlog has no effective data events.
Event not exists.
Sun Sep 26 13:06:20 2021 - [info] Additional events were not found from the orig master. No need to save.
Sun Sep 26 13:06:20 2021 - [info] 
Sun Sep 26 13:06:20 2021 - [info] * Phase 3.3: Determining New Master Phase..
Sun Sep 26 13:06:20 2021 - [info] 
Sun Sep 26 13:06:20 2021 - [info] Finding the latest slave that has all relay logs for recovering other slaves..
Sun Sep 26 13:06:20 2021 - [info] All slaves received relay logs to the same position. No need to resync each other.
Sun Sep 26 13:06:20 2021 - [info] Searching new master from slaves..
Sun Sep 26 13:06:20 2021 - [info]  Candidate masters from the configuration file:
Sun Sep 26 13:06:20 2021 - [info]   rs2(192.168.126.93:3306)  Version=8.0.16 (oldest major version between slaves) log-bin:enabled
Sun Sep 26 13:06:20 2021 - [info]     Replicating from rs1(192.168.126.92:3306)
Sun Sep 26 13:06:20 2021 - [info]     Primary candidate for the new Master (candidate_master is set)
Sun Sep 26 13:06:20 2021 - [info]  Non-candidate masters:
Sun Sep 26 13:06:20 2021 - [info]  Searching from candidate_master slaves which have received the latest relay log events..
Sun Sep 26 13:06:20 2021 - [info] New master is rs2(192.168.126.93:3306)
Sun Sep 26 13:06:20 2021 - [info] Starting master failover..
Sun Sep 26 13:06:20 2021 - [info] 
From:
rs1(192.168.126.92:3306) (current master)
 +--rs2(192.168.126.93:3306)
 +--nfs(192.168.126.94:3306)

To:
rs2(192.168.126.93:3306) (new master)
 +--nfs(192.168.126.94:3306)
Sun Sep 26 13:06:20 2021 - [info] 
Sun Sep 26 13:06:20 2021 - [info] * Phase 3.3: New Master Diff Log Generation Phase..
Sun Sep 26 13:06:20 2021 - [info] 
Sun Sep 26 13:06:20 2021 - [info]  This server has all relay logs. No need to generate diff files from the latest slave.
Sun Sep 26 13:06:20 2021 - [info] 
Sun Sep 26 13:06:20 2021 - [info] * Phase 3.4: Master Log Apply Phase..
Sun Sep 26 13:06:20 2021 - [info] 
Sun Sep 26 13:06:20 2021 - [info] *NOTICE: If any error happens from this phase, manual recovery is needed.
Sun Sep 26 13:06:20 2021 - [info] Starting recovery on rs2(192.168.126.93:3306)..
Sun Sep 26 13:06:20 2021 - [info]  This server has all relay logs. Waiting all logs to be applied.. 
Sun Sep 26 13:06:20 2021 - [info]   done.
Sun Sep 26 13:06:20 2021 - [info]  All relay logs were successfully applied.
Sun Sep 26 13:06:20 2021 - [info] Getting new master's binlog name and position..
Sun Sep 26 13:06:20 2021 - [info]  mysql2-bin.000004:155
Sun Sep 26 13:06:20 2021 - [info]  All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='rs2 or 192.168.126.93', MASTER_PORT=3306, MASTER_LOG_FILE='mysql2-bin.000004', MASTER_LOG_POS=155, MASTER_USER='copy', MASTER_PASSWORD='xxx';
Sun Sep 26 13:06:20 2021 - [info] Executing master IP activate script:
Sun Sep 26 13:06:20 2021 - [info]   /usr/local/bin/master_ip_failover --command=start --ssh_user=root --orig_master_host=rs1 --orig_master_ip=192.168.126.92 --orig_master_port=3306 --new_master_host=rs2 --new_master_ip=192.168.126.93 --new_master_port=3306 --new_master_user='mha'   --new_master_password=xxx
Unknown option: new_master_user
Unknown option: new_master_password


IN SCRIPT TEST====/usr/sbin/ifconfig ens32:1 down==/usr/sbin/ifconfig ens32:1 192.168.126.200/24===

Enabling the VIP - 192.168.126.200/24 on the new master - rs2 
Sun Sep 26 13:06:20 2021 - [info]  OK.
Sun Sep 26 13:06:20 2021 - [info] ** Finished master recovery successfully.
Sun Sep 26 13:06:20 2021 - [info] * Phase 3: Master Recovery Phase completed.
Sun Sep 26 13:06:20 2021 - [info] 
Sun Sep 26 13:06:20 2021 - [info] * Phase 4: Slaves Recovery Phase..
Sun Sep 26 13:06:20 2021 - [info] 
Sun Sep 26 13:06:20 2021 - [info] * Phase 4.1: Starting Parallel Slave Diff Log Generation Phase..
Sun Sep 26 13:06:20 2021 - [info] 
Sun Sep 26 13:06:20 2021 - [info] -- Slave diff file generation on host nfs(192.168.126.94:3306) started, pid: 16751. Check tmp log /etc/masterha//nfs_3306_20210926130618.log if it takes time..
Sun Sep 26 13:06:21 2021 - [info] 
Sun Sep 26 13:06:21 2021 - [info] Log messages from nfs ...
Sun Sep 26 13:06:21 2021 - [info] 
Sun Sep 26 13:06:20 2021 - [info]  This server has all relay logs. No need to generate diff files from the latest slave.
Sun Sep 26 13:06:21 2021 - [info] End of log messages from nfs.
Sun Sep 26 13:06:21 2021 - [info] -- nfs(192.168.126.94:3306) has the latest relay log events.
Sun Sep 26 13:06:21 2021 - [info] Generating relay diff files from the latest slave succeeded.
Sun Sep 26 13:06:21 2021 - [info] 
Sun Sep 26 13:06:21 2021 - [info] * Phase 4.2: Starting Parallel Slave Log Apply Phase..
Sun Sep 26 13:06:21 2021 - [info] 
Sun Sep 26 13:06:21 2021 - [info] -- Slave recovery on host nfs(192.168.126.94:3306) started, pid: 16754. Check tmp log /etc/masterha//nfs_3306_20210926130618.log if it takes time..
Sun Sep 26 13:06:22 2021 - [info] 
Sun Sep 26 13:06:22 2021 - [info] Log messages from nfs ...
Sun Sep 26 13:06:22 2021 - [info] 
Sun Sep 26 13:06:21 2021 - [info] Starting recovery on nfs(192.168.126.94:3306)..
Sun Sep 26 13:06:21 2021 - [info]  This server has all relay logs. Waiting all logs to be applied.. 
Sun Sep 26 13:06:21 2021 - [info]   done.
Sun Sep 26 13:06:21 2021 - [info]  All relay logs were successfully applied.
Sun Sep 26 13:06:21 2021 - [info]  Resetting slave nfs(192.168.126.94:3306) and starting replication from the new master rs2(192.168.126.93:3306)..
Sun Sep 26 13:06:21 2021 - [info]  Executed CHANGE MASTER.
Sun Sep 26 13:06:22 2021 - [info]  Slave started.
Sun Sep 26 13:06:22 2021 - [info] End of log messages from nfs.
Sun Sep 26 13:06:22 2021 - [info] -- Slave recovery on host nfs(192.168.126.94:3306) succeeded.
Sun Sep 26 13:06:22 2021 - [info] All new slave servers recovered successfully.
Sun Sep 26 13:06:22 2021 - [info] 
Sun Sep 26 13:06:22 2021 - [info] * Phase 5: New master cleanup phase..
Sun Sep 26 13:06:22 2021 - [info] 
Sun Sep 26 13:06:22 2021 - [info] Resetting slave info on the new master..
Sun Sep 26 13:06:22 2021 - [info]  rs2: Resetting slave info succeeded.
Sun Sep 26 13:06:22 2021 - [info] Master failover to rs2(192.168.126.93:3306) completed successfully.
Sun Sep 26 13:06:22 2021 - [info] 

----- Failover Report -----

app1: MySQL Master failover rs1(192.168.126.92:3306) to rs2(192.168.126.93:3306) succeeded

Master rs1(192.168.126.92:3306) is down!

Check MHA Manager logs at mha-manager:/etc/masterha/mha.log for details.

Started automated(non-interactive) failover.
Invalidated master IP address on rs1(192.168.126.92:3306)
The latest slave rs2(192.168.126.93:3306) has all relay logs for recovery.
Selected rs2(192.168.126.93:3306) as a new master.
rs2(192.168.126.93:3306): OK: Applying all logs succeeded.
rs2(192.168.126.93:3306): OK: Activated master IP address.
nfs(192.168.126.94:3306): This host has the latest relay log events.
Generating relay diff files from the latest slave succeeded.
nfs(192.168.126.94:3306): OK: Applying all logs succeeded. Slave started, replicating from rs2(192.168.126.93:3306)
rs2(192.168.126.93:3306): Resetting slave info succeeded.
Master failover to rs2(192.168.126.93:3306) completed successfully.	# 主切换为rs2

# 同时查看rs1的VIP消失
[root@rs1 ~]# ip a | grep 192.168.126.200

# 查看新的主rs2是否接管vip
[root@rs2 ~]# ip a | grep 192.168.126.200
    inet 192.168.126.200/24 brd 192.168.126.255 scope global secondary ens32:1
# 验证rs2是否为主库
[root@rs2 ~]# mysql -uroot -p'mysql123.COM'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 37
Server version: 8.0.16 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show master status;
+-------------------+----------+--------------+-------------------------------------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB                                | Executed_Gtid_Set |
+-------------------+----------+--------------+-------------------------------------------------+-------------------+
| mysql2-bin.000004 |      155 |              | information_schema,mysql,performance_schema,sys |                   |
+-------------------+----------+--------------+-------------------------------------------------+-------------------+
1 row in set (0.00 sec)

mysql> show slave status;
Empty set (0.00 sec)

# 注意:正常自动切换一次后,MHA 进程会退出。
# 切换过程中需要关注的几个问题:
# 1.切换过程会自动把数据库只读read_only关闭
# 2.切换之后需要删除手工删除/etc/masterha/app1.failover.complete,才能进行第二次测试
# 3.一旦发生切换管理进程将会退出,无法进行再次测试,需将故障数据库加入到MHA环境中来

故障切换备选主库的算法(根据app1.cnf配置文件中的设置):
1、一般判断从库的是从(position/GTID)判断优劣,数据有差异,最接近于master的slave,成为备选主。
2、数据一致的情况下,按照配置文件顺序,选择备选主库。
3、设定有权重(candidate_master=1),按照权重强制指定备选主。

默认情况下如果一个slave落后master 100M的relay logs的话,即使有权重,也会失效。如果check_repl_delay=0的话,即使落后很多日志,也强制选择其为备选主。

4、二级从数据库服务器需要在my.cnf数据可配置文件中将log_slave_updates打开
5、手工切换需要先定义好master_ip_online_change_script脚本,不然只会切换mysql,Ip地址不会绑定上去,可以根据模板来配置该脚本
6、通过设置no_master=1可以让某一个节点永远不成为新的主节点


# 故障修复
# 启动rs1主机的数据库
[root@rs1 ~]# systemctl start mysqld

# 在现主库服务器 rs2 查看二进制文件和同步点
[root@rs2 ~]# mysql -uroot -p'mysql123.COM' -e "show master status;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+-------------------+----------+--------------+-------------------------------------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB                                | Executed_Gtid_Set |
+-------------------+----------+--------------+-------------------------------------------------+-------------------+
| mysql2-bin.000004 |      155 |              | information_schema,mysql,performance_schema,sys |                   |
+-------------------+----------+--------------+-------------------------------------------------+-------------------+

# 配置原主库服务器 rs1为新主库rs2的从库
[root@rs1 ~]# mysql -uroot -p'mysql123.COM'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.16 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> change master to
    -> master_host='rs2',
    -> master_user='copy',
    -> master_password='linux123.COM',
    -> master_log_file='mysql2-bin.000004',
    -> master_log_pos=155;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: rs2
                  Master_User: copy
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql2-bin.000004
          Read_Master_Log_Pos: 155
               Relay_Log_File: relay1-log.000002
                Relay_Log_Pos: 323
        Relay_Master_Log_File: mysql2-bin.000004
             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: 155
              Relay_Log_Space: 526
              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: 2
                  Master_UUID: 9bc02a48-1d3a-11ec-a4b6-000c292bea5a
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           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
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set (0.00 sec)


# 删除mha-manager节点的mha工作目录下的文件
[root@mha-manager masterha]# ls
app1.cnf  app1.failover.complete  mha.log
[root@mha-manager masterha]# rm -rf app1.failover.complete  mha.log

# 修改配置文件app1.cnf
[root@mha-manager masterha]# vim app1.cnf 
master_ip_online_change_script=/usr/local/bin/master_ip_online_change
ping_interval=1
remote_workdir=/tmp
repl_user=copy
repl_password=linux123.COM
report_script=/usr/local/bin/send_report
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.126.92 -s 192.168.126.94
shutdown_script=""
ssh_user=root
user=mha
password=linux123.COM

[server1]
hostname=rs1
port=3306
candidate_master=1
check_repl_delay=0

[server2]
hostname=rs2
port=3306

[server3]
hostname=nfs
port=3306

# 主从检测
[root@mha-manager mha4mysql-manager-0.57]# masterha_check_repl -conf=/etc/masterha/app1.cnf
Sun Sep 26 13:30:39 2021 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Sun Sep 26 13:30:39 2021 - [info] Reading application default configuration from /etc/masterha/app1.cnf..
Sun Sep 26 13:30:39 2021 - [info] Reading server configuration from /etc/masterha/app1.cnf..
Sun Sep 26 13:30:39 2021 - [info] MHA::MasterMonitor version 0.57.
Sun Sep 26 13:30:40 2021 - [info] GTID failover mode = 0
Sun Sep 26 13:30:40 2021 - [info] Dead Servers:
Sun Sep 26 13:30:40 2021 - [info] Alive Servers:
Sun Sep 26 13:30:40 2021 - [info]   rs1(192.168.126.92:3306)
Sun Sep 26 13:30:40 2021 - [info]   rs2(192.168.126.93:3306)
Sun Sep 26 13:30:40 2021 - [info]   nfs(192.168.126.94:3306)
Sun Sep 26 13:30:40 2021 - [info] Alive Slaves:
Sun Sep 26 13:30:40 2021 - [info]   rs1(192.168.126.92:3306)  Version=8.0.16 (oldest major version between slaves) log-bin:enabled
Sun Sep 26 13:30:40 2021 - [info]     Replicating from rs2(192.168.126.93:3306)
Sun Sep 26 13:30:40 2021 - [info]     Primary candidate for the new Master (candidate_master is set)
Sun Sep 26 13:30:40 2021 - [info]   nfs(192.168.126.94:3306)  Version=8.0.16 (oldest major version between slaves) log-bin:enabled
Sun Sep 26 13:30:40 2021 - [info]     Replicating from rs2(192.168.126.93:3306)
Sun Sep 26 13:30:40 2021 - [info] Current Alive Master: rs2(192.168.126.93:3306)
Sun Sep 26 13:30:40 2021 - [info] Checking slave configurations..
Sun Sep 26 13:30:40 2021 - [info]  read_only=1 is not set on slave rs1(192.168.126.92:3306).
Sun Sep 26 13:30:40 2021 - [warning]  relay_log_purge=0 is not set on slave rs1(192.168.126.92:3306).
Sun Sep 26 13:30:40 2021 - [info]  read_only=1 is not set on slave nfs(192.168.126.94:3306).
Sun Sep 26 13:30:40 2021 - [warning]  relay_log_purge=0 is not set on slave nfs(192.168.126.94:3306).
Sun Sep 26 13:30:40 2021 - [info] Checking replication filtering settings..
Sun Sep 26 13:30:40 2021 - [info]  binlog_do_db= , binlog_ignore_db= information_schema,mysql,performance_schema,sys
Sun Sep 26 13:30:40 2021 - [info]  Replication filtering check ok.
Sun Sep 26 13:30:40 2021 - [info] GTID (with auto-pos) is not supported
Sun Sep 26 13:30:40 2021 - [info] Starting SSH connection tests..
Sun Sep 26 13:30:42 2021 - [info] All SSH connection tests passed successfully.
Sun Sep 26 13:30:42 2021 - [info] Checking MHA Node version..
Sun Sep 26 13:30:43 2021 - [info]  Version check ok.
Sun Sep 26 13:30:43 2021 - [info] Checking SSH publickey authentication settings on the current master..
Sun Sep 26 13:30:43 2021 - [info] HealthCheck: SSH to rs2 is reachable.
Sun Sep 26 13:30:43 2021 - [info] Master MHA Node version is 0.57.
Sun Sep 26 13:30:43 2021 - [info] Checking recovery script configurations on rs2(192.168.126.93:3306)..
Sun Sep 26 13:30:43 2021 - [info]   Executing command: save_binary_logs --command=test --start_pos=4 --binlog_dir=/var/lib/mysql/ --output_file=/tmp/save_binary_logs_test --manager_version=0.57 --start_file=mysql2-bin.000004 
Sun Sep 26 13:30:43 2021 - [info]   Connecting to root@192.168.126.93(rs2:22).. 
  Creating /tmp if not exists..    ok.
  Checking output directory is accessible or not..
   ok.
  Binlog found at /var/lib/mysql/, up to mysql2-bin.000004
Sun Sep 26 13:30:44 2021 - [info] Binlog setting check done.
Sun Sep 26 13:30:44 2021 - [info] Checking SSH publickey authentication and checking recovery script configurations on all alive slave servers..
Sun Sep 26 13:30:44 2021 - [info]   Executing command : apply_diff_relay_logs --command=test --slave_user='mha' --slave_host=rs1 --slave_ip=192.168.126.92 --slave_port=3306 --workdir=/tmp --target_version=8.0.16 --manager_version=0.57 --relay_dir=/var/lib/mysql --current_relay_log=relay1-log.000002  --slave_pass=xxx
Sun Sep 26 13:30:44 2021 - [info]   Connecting to root@192.168.126.92(rs1:22).. 
  Checking slave recovery environment settings..
    Relay log found at /var/lib/mysql, up to relay1-log.000002
    Temporary relay log file is /var/lib/mysql/relay1-log.000002
    Testing mysql connection and privileges..mysql: [Warning] Using a password on the command line interface can be insecure.
 done.
    Testing mysqlbinlog output.. done.
    Cleaning up test file(s).. done.
Sun Sep 26 13:30:44 2021 - [info]   Executing command : apply_diff_relay_logs --command=test --slave_user='mha' --slave_host=nfs --slave_ip=192.168.126.94 --slave_port=3306 --workdir=/tmp --target_version=8.0.16 --manager_version=0.57 --relay_dir=/var/lib/mysql --current_relay_log=relay3-log.000002  --slave_pass=xxx
Sun Sep 26 13:30:44 2021 - [info]   Connecting to root@192.168.126.94(nfs:22).. 
  Checking slave recovery environment settings..
    Relay log found at /var/lib/mysql, up to relay3-log.000002
    Temporary relay log file is /var/lib/mysql/relay3-log.000002
    Testing mysql connection and privileges..mysql: [Warning] Using a password on the command line interface can be insecure.
 done.
    Testing mysqlbinlog output.. done.
    Cleaning up test file(s).. done.
Sun Sep 26 13:30:44 2021 - [info] Slaves settings check done.
Sun Sep 26 13:30:44 2021 - [info] 
rs2(192.168.126.93:3306) (current master)
 +--rs1(192.168.126.92:3306)
 +--nfs(192.168.126.94:3306)

Sun Sep 26 13:30:44 2021 - [info] Checking replication health on rs1..
Sun Sep 26 13:30:44 2021 - [info]  ok.
Sun Sep 26 13:30:44 2021 - [info] Checking replication health on nfs..
Sun Sep 26 13:30:44 2021 - [info]  ok.
Sun Sep 26 13:30:44 2021 - [info] Checking master_ip_failover_script status:
Sun Sep 26 13:30:44 2021 - [info]   /usr/local/bin/master_ip_failover --command=status --ssh_user=root --orig_master_host=rs2 --orig_master_ip=192.168.126.93 --orig_master_port=3306 


IN SCRIPT TEST====/usr/sbin/ifconfig ens32:1 down==/usr/sbin/ifconfig ens32:1 192.168.126.200/24===

Checking the Status of the script.. OK 
Sun Sep 26 13:30:44 2021 - [info]  OK.
Sun Sep 26 13:30:44 2021 - [warning] shutdown_script is not defined.
Sun Sep 26 13:30:44 2021 - [info] Got exit code 0 (Not master dead).

MySQL Replication Health is OK.

# 启动 MHA
[root@mha-manager mha4mysql-manager-0.57]# nohup masterha_manager --conf=/etc/masterha/app1.cnf > /etc/masterha/mha.log  < /dev/null 2>&1 &
[1] 18046
[root@mha-manager mha4mysql-manager-0.57]# 
[root@mha-manager mha4mysql-manager-0.57]# masterha_check_status --conf=/etc/masterha/app1.cnf
app1 (pid:18046) is running(0:PING_OK), master:rs2

redis配置

redis一主一从三哨兵+keepalived

主机名IP角色备注
rs1192.168.126.92nginx服务器1、mysql服务器 、redis主+keepalived、redis哨兵1提供WEB静态资源及对动态资源请求转发至后端tomcat服务器、mysql主(mysql主节点,负责写数据)
rs2192.168.126.93nginx服务器2 、mysql服务器、redis从+keepalived、redis哨兵2提供WEB静态资源及对动态资源请求转发至后端tomcat服务器、mysql从1(mysql从节点,负责读数据,备选master)
nfs192.168.126.94数据共享服务器 、mysql服务器、redis哨兵3提供网页共享静态WEB资源、mysql从2(mysql从节点,负责读数据)

安装redis

rs1、rs2、nfs节点均按如下步骤进行安装

说明:nfs不作为redis从,但要作为哨兵(所以还是得安装redis)

[root@rs1 ~]# wget http://download.redis.io/releases/redis-4.0.0.tar.gz
[root@rs1 ~]# ls
redis-4.0.0.tar.gz
[root@rs1 ~]# mkdir -p /usr/local/redis
[root@rs1 ~]# tar -xf redis-4.0.0.tar.gz -C /usr/local/redis
# 下载编译时所需依赖包
[root@rs1 ~]# yum -y install gcc gcc-c++
[root@rs1 ~]# cd /usr/local/redis/redis-4.0.0/
[root@rs1 redis-4.0.0]# ls
00-RELEASENOTES  CONTRIBUTING  deps     Makefile   README.md   runtest          runtest-sentinel  src    utils
BUGS             COPYING       INSTALL  MANIFESTO  redis.conf  runtest-cluster  sentinel.conf     tests
[root@rs1 redis-4.0.0]# make MALLOC=libc
[root@rs1 redis-4.0.0]# make install

配置一主一从

rs1作为redis主:

[root@rs1 ~]# mkdir /usr/local/redis/redis-4.0.0/data
[root@rs1 ~]# vim /usr/local/redis/redis-4.0.0/redis.conf
port 6379
daemonize no
dir /usr/local/redis/redis-4.0.0/data
protected-mode no

rs2作为redis从:

[root@rs2 ~]# mkdir /usr/local/redis/redis-4.0.0/data
[root@rs2 ~]# vim /usr/local/redis/redis-4.0.0/redis.conf
port 6379
daemonize no
protected-mode no
dir /usr/local/redis/redis-4.0.0/data
slaveof 192.168.126.92 6379

同时启动主从:

# 启动redis主rs1
[root@rs1 ~]# redis-server /usr/local/redis/redis-4.0.0/redis.conf
5613:C 26 Sep 16:26:39.897 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
5613:C 26 Sep 16:26:39.897 # Redis version=4.0.0, bits=64, commit=00000000, modified=0, pid=5613, just started
5613:C 26 Sep 16:26:39.897 # Configuration loaded
5613:M 26 Sep 16:26:39.898 * Increased maximum number of open files to 10032 (it was originally set to 1024).
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 4.0.0 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 5613
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

5613:M 26 Sep 16:26:39.899 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
5613:M 26 Sep 16:26:39.899 # Server initialized
5613:M 26 Sep 16:26:39.899 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
5613:M 26 Sep 16:26:39.900 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
5613:M 26 Sep 16:26:39.900 * Ready to accept connections
5613:M 26 Sep 16:26:55.259 * Slave 192.168.126.93:6379 asks for synchronization
5613:M 26 Sep 16:26:55.259 * Full resync requested by slave 192.168.126.93:6379
5613:M 26 Sep 16:26:55.259 * Starting BGSAVE for SYNC with target: disk
5613:M 26 Sep 16:26:55.260 * Background saving started by pid 5617
5617:C 26 Sep 16:26:55.260 * DB saved on disk
5617:C 26 Sep 16:26:55.261 * RDB: 0 MB of memory used by copy-on-write
5613:M 26 Sep 16:26:55.284 * Background saving terminated with success
5613:M 26 Sep 16:26:55.284 * Synchronization with slave 192.168.126.93:6379 succeeded	# 主从同步成功

# 启动redis从rs2
[root@rs2 ~]# redis-server /usr/local/redis/redis-4.0.0/redis.conf 
62918:C 26 Sep 16:26:55.253 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
62918:C 26 Sep 16:26:55.253 # Redis version=4.0.0, bits=64, commit=00000000, modified=0, pid=62918, just started
62918:C 26 Sep 16:26:55.253 # Configuration loaded
62918:S 26 Sep 16:26:55.254 * Increased maximum number of open files to 10032 (it was originally set to 1024).
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 4.0.0 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 62918
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

62918:S 26 Sep 16:26:55.256 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
62918:S 26 Sep 16:26:55.256 # Server initialized
62918:S 26 Sep 16:26:55.256 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
62918:S 26 Sep 16:26:55.256 * Ready to accept connections
62918:S 26 Sep 16:26:55.257 * Connecting to MASTER 192.168.126.92:6379
62918:S 26 Sep 16:26:55.257 * MASTER <-> SLAVE sync started
62918:S 26 Sep 16:26:55.258 * Non blocking connect for SYNC fired the event.
62918:S 26 Sep 16:26:55.258 * Master replied to PING, replication can continue...
62918:S 26 Sep 16:26:55.259 * Partial resynchronization not possible (no cached master)
62918:S 26 Sep 16:26:55.259 * Full resync from master: 80a249e16ade10c26fa40b9efceccaca10468d7c:0
62918:S 26 Sep 16:26:55.284 * MASTER <-> SLAVE sync: receiving 175 bytes from master
62918:S 26 Sep 16:26:55.284 * MASTER <-> SLAVE sync: Flushing old data
62918:S 26 Sep 16:26:55.284 * MASTER <-> SLAVE sync: Loading DB in memory
62918:S 26 Sep 16:26:55.284 * MASTER <-> SLAVE sync: Finished with success	# 主从同步成功

测试主从同步数据:

# 主
[root@rs1 ~]# redis-cli
127.0.0.1:6379> set name zhangsan
OK
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> get name
"zhangsan"
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.126.93,port=6379,state=online,offset=382,lag=0
master_replid:80a249e16ade10c26fa40b9efceccaca10468d7c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:382
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:382

# 从
[root@rs2 ~]# redis-cli
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> get name
"zhangsan"
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.126.92
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:396
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:80a249e16ade10c26fa40b9efceccaca10468d7c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:396
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:396

# 主从正常 

配置哨兵

[root@rs1 ~]# vim /usr/local/redis/redis-4.0.0/sentinel.conf
port 26379
dir /usr/local/redis/redis-4.0.0/data
sentinel monitor mymaster 192.168.126.92 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
protected-mode no


[root@rs2 ~]# vim /usr/local/redis/redis-4.0.0/sentinel.conf
port 26379
dir /usr/local/redis/redis-4.0.0/data
sentinel monitor mymaster 192.168.126.92 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
protected-mode no


[root@nfs ~]# vim /usr/local/redis/redis-4.0.0/sentinel.conf
port 26379
dir /usr/local/redis/redis-4.0.0/data
sentinel monitor mymaster 192.168.126.92 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
protected-mode no

启动哨兵

# rs1哨兵:
[root@rs1 ~]# redis-sentinel /usr/local/redis/redis-4.0.0/sentinel.conf
5648:X 26 Sep 16:39:07.008 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
5648:X 26 Sep 16:39:07.008 # Redis version=4.0.0, bits=64, commit=00000000, modified=0, pid=5648, just started
5648:X 26 Sep 16:39:07.008 # Configuration loaded
5648:X 26 Sep 16:39:07.009 * Increased maximum number of open files to 10032 (it was originally set to 1024).
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 4.0.0 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379
 |    `-._   `._    /     _.-'    |     PID: 5648
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

5648:X 26 Sep 16:39:07.010 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
5648:X 26 Sep 16:39:07.011 # Sentinel ID is b52bd0f340f84ee933fb0314143105bdaa91f608
5648:X 26 Sep 16:39:07.011 # +monitor master mymaster 192.168.126.92 6379 quorum 2
5648:X 26 Sep 16:39:07.011 * +slave slave 192.168.126.93:6379 192.168.126.93 6379 @ mymaster 192.168.126.92 6379
5648:X 26 Sep 16:39:07.616 * +sentinel sentinel 68cd3bb1de8d21777f81a838050541dec642577a 192.168.126.93 26379 @ mymaster 192.168.126.92 6379
5648:X 26 Sep 16:39:26.224 * +sentinel sentinel f8598202868d2cf721df04f4f5da4c1bb70ec09f 192.168.126.94 26379 @ mymaster 192.168.126.92 6379
[root@rs1 ~]# redis-cli -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.126.92:6379,slaves=1,sentinels=3

# rs2哨兵:
[root@rs2 ~]# redis-sentinel /usr/local/redis/redis-4.0.0/sentinel.conf
65211:X 26 Sep 16:39:03.526 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
65211:X 26 Sep 16:39:03.526 # Redis version=4.0.0, bits=64, commit=00000000, modified=0, pid=65211, just started
65211:X 26 Sep 16:39:03.526 # Configuration loaded
65211:X 26 Sep 16:39:03.527 * Increased maximum number of open files to 10032 (it was originally set to 1024).
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 4.0.0 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379
 |    `-._   `._    /     _.-'    |     PID: 65211
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

65211:X 26 Sep 16:39:03.528 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
65211:X 26 Sep 16:39:03.529 # Sentinel ID is 68cd3bb1de8d21777f81a838050541dec642577a
65211:X 26 Sep 16:39:03.529 # +monitor master mymaster 192.168.126.92 6379 quorum 2
65211:X 26 Sep 16:39:03.530 * +slave slave 192.168.126.93:6379 192.168.126.93 6379 @ mymaster 192.168.126.92 6379
65211:X 26 Sep 16:39:09.078 * +sentinel sentinel b52bd0f340f84ee933fb0314143105bdaa91f608 192.168.126.92 26379 @ mymaster 192.168.126.92 6379
65211:X 26 Sep 16:39:26.224 * +sentinel sentinel f8598202868d2cf721df04f4f5da4c1bb70ec09f 192.168.126.94 26379 @ mymaster 192.168.126.92 6379
[root@rs2 ~]# redis-cli -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.126.92:6379,slaves=1,sentinels=3

# nfs哨兵
[root@nfs ~]# redis-sentinel /usr/local/redis/redis-4.0.0/sentinel.conf
4893:X 26 Sep 16:39:24.153 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
4893:X 26 Sep 16:39:24.153 # Redis version=4.0.0, bits=64, commit=00000000, modified=0, pid=4893, just started
4893:X 26 Sep 16:39:24.153 # Configuration loaded
4893:X 26 Sep 16:39:24.154 * Increased maximum number of open files to 10032 (it was originally set to 1024).
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 4.0.0 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379
 |    `-._   `._    /     _.-'    |     PID: 4893
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

4893:X 26 Sep 16:39:24.156 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
4893:X 26 Sep 16:39:24.157 # Sentinel ID is f8598202868d2cf721df04f4f5da4c1bb70ec09f
4893:X 26 Sep 16:39:24.157 # +monitor master mymaster 192.168.126.92 6379 quorum 2
4893:X 26 Sep 16:39:24.160 * +slave slave 192.168.126.93:6379 192.168.126.93 6379 @ mymaster 192.168.126.92 6379
4893:X 26 Sep 16:39:25.402 * +sentinel sentinel b52bd0f340f84ee933fb0314143105bdaa91f608 192.168.126.92 26379 @ mymaster 192.168.126.92 6379
4893:X 26 Sep 16:39:26.051 * +sentinel sentinel 68cd3bb1de8d21777f81a838050541dec642577a 192.168.126.93 26379 @ mymaster 192.168.126.92 6379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.126.92:6379,slaves=1,sentinels=3

验证redis故障自动主从切换

# 此时停掉rs1主的redis服务(模拟master节点redis故障)
# 因为redis在前台启动,直接 ctrl + c 即可停止

# 查看三个哨兵的主从选举和切换日志输出信息
# rs1哨兵
5648:X 26 Sep 16:47:48.678 # +sdown master mymaster 192.168.126.92 6379
5648:X 26 Sep 16:47:48.778 # +new-epoch 1
5648:X 26 Sep 16:47:48.779 # +vote-for-leader 68cd3bb1de8d21777f81a838050541dec642577a 1
5648:X 26 Sep 16:47:49.392 # +config-update-from sentinel 68cd3bb1de8d21777f81a838050541dec642577a 192.168.126.93 26379 @ mymaster 192.168.126.92 6379
5648:X 26 Sep 16:47:49.392 # +switch-master mymaster 192.168.126.92 6379 192.168.126.93 6379
5648:X 26 Sep 16:47:49.392 * +slave slave 192.168.126.92:6379 192.168.126.92 6379 @ mymaster 192.168.126.93 6379
5648:X 26 Sep 16:48:19.396 # +sdown slave 192.168.126.92:6379 192.168.126.92 6379 @ mymaster 192.168.126.93 6379

# rs2哨兵
65211:X 26 Sep 16:47:48.722 # +sdown master mymaster 192.168.126.92 6379
65211:X 26 Sep 16:47:48.774 # +odown master mymaster 192.168.126.92 6379 #quorum 3/2
65211:X 26 Sep 16:47:48.774 # +new-epoch 1
65211:X 26 Sep 16:47:48.774 # +try-failover master mymaster 192.168.126.92 6379
65211:X 26 Sep 16:47:48.776 # +vote-for-leader 68cd3bb1de8d21777f81a838050541dec642577a 1
65211:X 26 Sep 16:47:48.779 # f8598202868d2cf721df04f4f5da4c1bb70ec09f voted for 68cd3bb1de8d21777f81a838050541dec642577a 1
65211:X 26 Sep 16:47:48.779 # b52bd0f340f84ee933fb0314143105bdaa91f608 voted for 68cd3bb1de8d21777f81a838050541dec642577a 1
65211:X 26 Sep 16:47:48.848 # +elected-leader master mymaster 192.168.126.92 6379
65211:X 26 Sep 16:47:48.848 # +failover-state-select-slave master mymaster 192.168.126.92 6379
65211:X 26 Sep 16:47:48.925 # +selected-slave slave 192.168.126.93:6379 192.168.126.93 6379 @ mymaster 192.168.126.92 6379
65211:X 26 Sep 16:47:48.925 * +failover-state-send-slaveof-noone slave 192.168.126.93:6379 192.168.126.93 6379 @ mymaster 192.168.126.92 6379
65211:X 26 Sep 16:47:48.981 * +failover-state-wait-promotion slave 192.168.126.93:6379 192.168.126.93 6379 @ mymaster 192.168.126.92 6379
65211:X 26 Sep 16:47:49.290 # +promoted-slave slave 192.168.126.93:6379 192.168.126.93 6379 @ mymaster 192.168.126.92 6379
65211:X 26 Sep 16:47:49.290 # +failover-state-reconf-slaves master mymaster 192.168.126.92 6379
65211:X 26 Sep 16:47:49.390 # +failover-end master mymaster 192.168.126.92 6379
65211:X 26 Sep 16:47:49.390 # +switch-master mymaster 192.168.126.92 6379 192.168.126.93 6379
65211:X 26 Sep 16:47:49.390 * +slave slave 192.168.126.92:6379 192.168.126.92 6379 @ mymaster 192.168.126.93 6379
65211:X 26 Sep 16:48:19.402 # +sdown slave 192.168.126.92:6379 192.168.126.92 6379 @ mymaster 192.168.126.93 6379

# rs3哨兵
4893:X 26 Sep 16:47:48.697 # +sdown master mymaster 192.168.126.92 6379
4893:X 26 Sep 16:47:48.779 # +new-epoch 1
4893:X 26 Sep 16:47:48.780 # +vote-for-leader 68cd3bb1de8d21777f81a838050541dec642577a 1
4893:X 26 Sep 16:47:48.789 # +odown master mymaster 192.168.126.92 6379 #quorum 2/2
4893:X 26 Sep 16:47:48.789 # Next failover delay: I will not start a failover before Sun Sep 26 16:53:49 2021
4893:X 26 Sep 16:47:49.393 # +config-update-from sentinel 68cd3bb1de8d21777f81a838050541dec642577a 192.168.126.93 26379 @ mymaster 192.168.126.92 6379
4893:X 26 Sep 16:47:49.393 # +switch-master mymaster 192.168.126.92 6379 192.168.126.93 6379
4893:X 26 Sep 16:47:49.393 * +slave slave 192.168.126.92:6379 192.168.126.92 6379 @ mymaster 192.168.126.93 6379
4893:X 26 Sep 16:48:19.473 # +sdown slave 192.168.126.92:6379 192.168.126.92 6379 @ mymaster 192.168.126.93 6379
# 三个哨兵输出信息基本相同,发现rs1的redis无法连接最后选举192.168.126.93即rs2为主

# 查看rs2的redis是否为主
[root@rs2 ~]# redis-cli
127.0.0.1:6379> info replication
# Replication
role:master		# 主
connected_slaves:0
master_replid:8e7da4b9c5b36e33f14996827b69b581eac8033f
master_replid2:80a249e16ade10c26fa40b9efceccaca10468d7c
master_repl_offset:162366
second_repl_offset:102856
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:162366
[root@rs2 ~]# redis-cli -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.126.93:6379,slaves=1,sentinels=3	# 是自己

# 此时手动启动rs1的redis服务,便会将其自动加入到以rs2为主的从,并同步主的数据
[root@rs1 ~]# redis-server /usr/local/redis/redis-4.0.0/redis.conf

# 查看任意哨兵的信息
65211:X 26 Sep 16:54:41.927 * +convert-to-slave slave 192.168.126.92:6379 192.168.126.92 6379 @ mymaster 192.168.126.93 6379	# 意思是作为rs2的主

# 查看任一redis日志信息
62918:M 26 Sep 16:54:42.671 * Slave 192.168.126.92:6379 asks for synchronization
62918:M 26 Sep 16:54:42.672 * Partial resynchronization request from 192.168.126.92:6379 accepted. Sending 188964 bytes of backlog starting from offset 1.	# 将主rs2的数据同步到现在作为从的rs1上

# 查看rs1的状态
[root@rs1 ~]# redis-cli
127.0.0.1:6379> info replication
# Replication
role:slave		# 从
master_host:192.168.126.93
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:226968
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:8e7da4b9c5b36e33f14996827b69b581eac8033f
master_replid2:80a249e16ade10c26fa40b9efceccaca10468d7c
master_repl_offset:0
second_repl_offset:1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

[root@rs1 ~]# redis-cli -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.126.93:6379,slaves=1,sentinels=3

# 一主一从三哨兵模式就搭建成功了
# 停止rs2上的redis服务,待rs1成为主后,再启动rs2上的redis,恢复成rs1为主,rs2为从

keepalived安装及配置

[root@rs1 ~]# yum install keepalived -y
[root@rs1 ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL
}

vrrp_script check_redis {
   script "/etc/keepalived/check_redis.sh"   #要执行的脚本
   interval 1      # 执行脚本间隔时间
}

vrrp_instance VI_1 {
    state MASTER
    interface ens32
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.126.250
    }
     track_script {
      check_redis
    }
}
[root@rs1 ~]# vim /etc/keepalived/check_redis.sh
#!/bin/bash
ALIVE=`/usr/local/bin/redis-cli  PING`
if [ "$ALIVE" == "PONG" ]; then
  echo $ALIVE
  exit 0
else
  echo $ALIVE
  exit 1
fi
[root@rs1 ~]# systemctl start keepalived



[root@rs2 ~]# yum install keepalived -y
[root@rs2 ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL
}

vrrp_script check_redis {
   script "/etc/keepalived/check_redis.sh"
   interval 1
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens32
    virtual_router_id 51
    priority 99
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.126.250
    }
    track_script {
      check_redis
    }
}

[root@rs2 ~]# vim /etc/keepalived/check_redis.sh
#!/bin/bash
ALIVE=`/usr/local/bin/redis-cli  PING`
if [ "$ALIVE" == "PONG" ]; then
  echo $ALIVE
  exit 0
else
  echo $ALIVE
  exit 1
fi
[root@rs2 ~]# systemctl start keepalived

# 查看rs1上的VIP是否已生成
[root@rs1 ~]# ip a | grep 192.168.126.250
    inet 192.168.126.250/32 scope global ens32

# 使用一台装有redis的主机测试能否使用上面的VIP进行连接
[root@test ~]# ifconfig ens32 | awk 'NR==2 {print $2}'
192.168.126.120
[root@test ~]# redis-cli -h 192.168.126.250
192.168.126.250:6379> keys *
1) "name"
192.168.126.250:6379> get name
"zhangsan"
192.168.126.250:6379> exit

session会话共享配置

两台tomcat服务器的session配置

jar包获取:https://search.maven.org/

[root@ds-master ~]# ls
commons-pool2-2.2.jar    jedis-2.5.2.jar    tomcat-redis-session-manager-2.0.0.jar
[root@ds-master ~]# cp commons-pool2-2.2.jar jedis-2.5.2.jar tomcat-redis-session-manager-2.0.0.jar /usr/local/tomcat/apache-tomcat-8.0.36/lib/
[root@ds-master ~]# vim /usr/local/tomcat/apache-tomcat-8.0.36/conf/context.xml
<?xml version='1.0' encoding='utf-8'?>
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
    <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
         host="192.168.126.250"	# redis的vip
         port="6379"			# redis端口
         database="0"			# redis数据库
         maxInactiveInterval="60"/>	# 会话缓存到redis有效时长
     />
</Context>


# 启动
[root@ds-master ~]# /usr/local/tomcat/apache-tomcat-8.0.36/bin/startup.sh 

另一台tomcat同上配置

测试

在这里插入图片描述在这里插入图片描述

# 上面的session已写入redis服务器中
[root@test ~]# redis-cli -h 192.168.126.250
192.168.126.250:6379> keys *
1) "29C6A13CD627A5E9890BA2498C40A0D2"
2) "name"

两台php服务器的session配置

# 下载php-redis扩展插件包
[root@ds-master ~]# wget https://pecl.php.net/get/redis-4.3.0.tgz
[root@ds-master ~]# ls
redis-4.3.0.tgz
[root@ds-master ~]# mkdir /usr/local/php-redis
[root@ds-master ~]# tar -xf redis-4.3.0.tgz -C /usr/local/php-redis
# 下载编译安装所需依赖
[root@ds-master ~]# yum install php-devel gcc gcc-c++ -y 
[root@ds-master ~]# cd /usr/local/php-redis/redis-4.3.0/
# 安装php-redis。使用phpize(由php软件包提供,如果没有请安装php)工具生成configure文件,编译并编译安装(安装完成模块在/usr/lib64/php/modules目录下)
[root@ds-master redis-4.3.0]# phpize 
Configuring for:
PHP Api Version:         20100412
Zend Module Api No:      20100525
Zend Extension Api No:   220100525

[root@ds-master redis-4.3.0]# ./configure
[root@ds-master redis-4.3.0]# make && make install
[root@ds-master redis-4.3.0]# ls /usr/lib64/php/modules/
curl.so  fileinfo.so  gd.so  json.so  mbstring.so  mysqli.so  mysql.so  pdo_mysql.so  pdo.so  pdo_sqlite.so  phar.so  redis.so  sqlite3.so  zip.so

# 修改php-fpm和PHP的配置信息,使其支持redis模块,并指定session到redis服务的地址
[root@ds-master redis-4.3.0]# vim /etc/php.ini
session.save_handler = redis	# 默认有,需更改
extension_dir="/usr/lib64/php/modules/"		# 默认没有,需添加
extension=redis.so			# 默认有,被注释,直接添加
session.save_path = "tcp://192.168.126.250:6379"	# 默认有,被注释,直接添加
session.auto_start = 1	# 默认有需更改

[root@ds-master redis-4.3.0]# vim /etc/php-fpm.d/www.conf
# 文件最后两行进行修改
php_value[session.save_handler] = redis
php_value[session.save_path] = tcp://192.168.126.250:6379

# 重启php
[root@ds-master redis-4.3.0]# systemctl restart php-fpm

另一台php服务器同上面步骤

测试

在这里插入图片描述在这里插入图片描述

[root@test ~]# redis-cli -h 192.168.126.250
192.168.126.250:6379> keys *
1) "name"
2) "PHPREDIS_SESSION:u4al5f23a2hvhav1ipi3j7fpk7"
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-09-30 12:19:58  更:2021-09-30 12:20:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 16:54:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码