在MySQL5.7上面试了很久,但是配置好了之后了多次重启,依旧不见keepalived服务,后来切换到MySQL5.6,安装,配置,运行,测试,完全可用,讲经验分享出来。

keepalived其实就是实现主从备份中,当主节点坏掉后,能够只能切换到从节点的一个高可用软件,实现双主高可用,自然第一步肯定是搭建MySQL的主主复制,安装keepalived软件,配置keepalived的配置文件、配置好了重启后,默认从这个配置文件中加载,写代码通过jdbc测试keepalived的高可用。

软件:两台linux服务器,keepalived。

第一步:在两台linux服务器上安装MySQL服务器、安装keepalived软件:

sudo apt isntall mysql-server-5.6

sudo apt install keepalived

第二步:搭建两台MySQL服务器的主主复制(从主从复制入手,先配置两台MySQL1、2的主从,然后配置MySQL2、1的主从继而实现主主复制):

主: sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf 
mysqld下:bind-address        = 0.0.0.0下添加紧跟添加
 server-id=5
 log-bin=mysql-bin-5
 binlog-format=row  
保存退出,重启MySQL服务:sudo service mysql restart
登录MySQL:查看MySQL主节点状态--show master status \G

*************************** 1. row ***************************
             File: mysql-bin-134.000002
         Position: 154
     Binlog_Do_DB: 
   Binlog_Ignore_DB: 
 Executed_Gtid_Set: 
 1 row in set (0.00 sec)

出现这个则说明配置成功节点配置成功

从: sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf 
#bind-address = 127.0.0.1下添加
server-id=6
relay-log=mysql-relay-6 
  保存退出,重启MySQL服务:sudo service mysql restart
登录MySQL:查看MySQL主节点状态--show slave status \G

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 1.1.1.134
                  Master_User: root
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin-134.000002
          Read_Master_Log_Pos: 154
               Relay_Log_File: mysql-relay-133.000005
                Relay_Log_Pos: 375
        Relay_Master_Log_File: mysql-bin-134.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: 154
              Relay_Log_Space: 752
              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: 134
                  Master_UUID: 6f0d6c84-9e90-11e7-a20a-000c295f8461
              Master_Info_File: /var/lib/mysql/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: 
1 row in set (0.00 sec)

出现这个结果说明配置成功。

然后将主从配置方式换这再配置一次,即上次的主作为从,上次的从作为主在配置一次,即达到了主从的效果。

连接主从节点:

主节点:grant replication slave,replication client on *.* to 'us4'@'%' identified by 'us4'
从节点: change master to 
master_host='1.1.1.134',
master_port=3306,
master_user='root',
master_password='root',
master_log_file='mysql-bin-134.000001',
master_log_pos=1006;

第三步:新建keepalived的配置文件,命名为keepalived.conf,并且将这个配置文件放在/etc/keepalived/下

主节点1的keepalived配置文件如下:

global_defs {                                                                                                                                                      
  2    notification_email {
  3     ********@163.com
  4    }
  5    notification_email_from *******@163.com
  6    smtp_server 127.0.0.1
  7    smtp_connect_timeout 30
  8    router_id mysql_ha01
  9 }
 10 
 11 vrrp_instance VI_1 {
 12     state MASTER
 13     interface ens33
 14     virtual_router_id 51
 15     priority 100
 16     nopreempt #不抢占资源
 17     advert_int 1
 18     authentication {
 19         auth_type PASS
 20         auth_pass 1111
 21 }
 22     
 23     virtual_ipaddress {
 24         1.1.1.110/24
 25     }
 26 }
 28 virtual_server 1.1.1.110 5719 {
 29      delay_loop 2 #每过2秒检查一次real_server状态  
 30      lb_algo wrr #LVS算法
 31      lb_kind DR  #LVS算法
 32      persistence_timeout 60  #会话保持时间  
 33      protocol TCP
 34      real_server 1.1.1.5 5719 {
 35          weight 3
 36          notify_down /home/xuf/MySQL.sh #检测到服务down后执行的脚本  
 37          TCP_CHECK {
 38              connect_timeout 10    #连接超时时间 
 39              nb_get_retry 3       #重连次数 
其中要特别注意一下几点,虚拟IP(vip)地址的填写,代理的IP,网卡的正确填写,以及keepalived监听的数据库的端口号等。

主节点2的keepalived配置文件:和上面1的文件可以相同,只是把几个小地方改改就是了,代理的IP,以及master改为backed就可以了。

使用 ip a命令查看如果某一边有了虚拟ip(vip)的话就说明这个配置是完全正确的。

验证keepalived的高可用性:

在MySQL1,2中分别插入不通的数据,然后分别通过vip查询数据库中的内容,查询过程中打断keepalived的服务,查看后面的查询结果是不是能够显示另外一个数据库中内容,进而证明keepalived的高可用性。代码如下:

public class Keepalived {
    @Test
    public void testKeepalived(){
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;

        int index = 0;
        while (true){
            try {
                conn=DriverManager.getConnection("jdbc:mysql://1.1.1.110:3306/test?user=root&password=root&" +
                        "useSSL=true&autoReconnect=true&failOverReadOnly=false");
                System.out.println(conn);
                stmt = conn.createStatement();
                String sql = "select * from tb_test";
                rs = stmt.executeQuery(sql);
                while (rs.next()){
                    String str = rs.getString(2);
                    System.out.println(str);
                }
                System.out.println(index++);
                DBUtils.close(rs,stmt,conn);
                Thread.sleep(1000);
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                DBUtils.close(rs,stmt,conn);
            }
        }
    }
}

其中DBUtile是一个关闭流的工具类,可以直接使用if判断一个一个关闭。

测试结果如下:

com.mysql.jdbc.JDBC4Connection@357246de
lisi
29
com.mysql.jdbc.JDBC4Connection@d7b1517
zhangsan
30

后面有截图更详细的查看。