searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Nginx代理主备Mysql实践

2023-08-31 06:05:31
97
0

Nginx代理主备Mysql的目的

  在需要Mysql高可用的场景下,可以通过使用Nginx代理主备Mysql的方式,使业务组件优先访问主Mysql,在主Mysql宕机后,使用备Mysql。当主Mysql恢复后,业务组件转为访问主Mysql。

Nginx代理主备Mysql实践

实验拓扑图如下,通过java进程模拟mysql client。

准备工作:java程序(数据库连接池设置连接数为50),在mysql1、2进行sql建库建表;

1、mysql1 insert 数据value=1;

2、mysql2 insert 数据value=2;

3、nginx配置主备mysql1(主)mysql2(备);

4、java进程,get value 10000次并打印get结果。

4.1在get期间关闭主mysql1,(/etc/init.d/mysqld stop)

4.2等待10s,

4.3再启动主,( /etc/init.d/mysqld start)

4.4再reload(不修改配置文件),( ./nginx -s reload)

观察日志打印;

观察1:关闭主,日志是否异常,(预测日志由打印1变为打印2)

验证结果:预期正确

观察2:启动主,观察打印是1还是2,(预测打印2,因为2的连接还没断)、

验证结果:预期正确

观察3:reload,观察是否打印1,(预测打印1,reload会将之前的连接断开,之后新建的连接按配置文件连接到mysql主)

验证结果:预期错误,还是打印2

nginx的work没有立即退出,而是一直显示: nginx: worker process is shutting down(ps查看的结果)

分析:对于tcp连接,ngxin的旧work进程会等待没有数据传输之后才会断开连接,而实验中由于是每隔0.1s就会查询数据,导致nginx的旧work一直不能退出。

改进:配合worker_shutdown_timeout使用(配置文件增加worker_shutdown_timeout 60s;)

  • 实验核心代码:

@RequestMapping(value = "/get-for-test-mysql", method = RequestMethod.POST)
public void get(@RequestBody LockInput lockInput) throws InterruptedException {
    for(int i =0;i<10000;i++) {
        List<TestMysqlEntity> entities = testMysqlDao.getTestMysql(null);
        //0.1秒
        if(entities == null){
            log.info("get from mysql, value is null");
        } else {
            if(entities.isEmpty()){
                log.info("get from mysql, list is empty");
            } else {
                log.info("get from mysql, value is {} ", entities.get(0).getId());
            }
        }
        Thread.sleep(100);
    }
}

实验截图

Nginx配置文件

#user  nobody;
worker_processes  4;
worker_shutdown_timeout 60s;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

pid        /usr/local/nginx/logs/nginx.pid;


events {
    worker_connections  1024;
}


stream {
    upstream mysql-test{
        server 55.241.105.109:3306 weight=1 max_fails=3 fail_timeout=1s;
        server 55.241.105.119:3306 weight=1 max_fails=3 fail_timeout=1s backup;
    }
  server {
      listen 3307 so_keepalive=on;
      proxy_connect_timeout 3s;
      proxy_timeout 3s;
      proxy_pass mysql-test;
    }
}

小节

nginx可以优雅实现代理mysql主备;当mysql主挂掉后,nginx会将请求导向mysql备,并在mysql主恢复后,通过监控平台或脚本执行reload,nginx可以在指定时间后将连接切回到mysql主,并且在该时间内mysql主可以完成与备的数据同步,保证切回主后的数据一致性;备注:需要nginx配置文件增加worker_shutdown_timeout 60s;(此处为60s,可依据实际情况修改)

0条评论
0 / 1000
d****n
2文章数
0粉丝数
d****n
2 文章 | 0 粉丝
d****n
2文章数
0粉丝数
d****n
2 文章 | 0 粉丝
原创

Nginx代理主备Mysql实践

2023-08-31 06:05:31
97
0

Nginx代理主备Mysql的目的

  在需要Mysql高可用的场景下,可以通过使用Nginx代理主备Mysql的方式,使业务组件优先访问主Mysql,在主Mysql宕机后,使用备Mysql。当主Mysql恢复后,业务组件转为访问主Mysql。

Nginx代理主备Mysql实践

实验拓扑图如下,通过java进程模拟mysql client。

准备工作:java程序(数据库连接池设置连接数为50),在mysql1、2进行sql建库建表;

1、mysql1 insert 数据value=1;

2、mysql2 insert 数据value=2;

3、nginx配置主备mysql1(主)mysql2(备);

4、java进程,get value 10000次并打印get结果。

4.1在get期间关闭主mysql1,(/etc/init.d/mysqld stop)

4.2等待10s,

4.3再启动主,( /etc/init.d/mysqld start)

4.4再reload(不修改配置文件),( ./nginx -s reload)

观察日志打印;

观察1:关闭主,日志是否异常,(预测日志由打印1变为打印2)

验证结果:预期正确

观察2:启动主,观察打印是1还是2,(预测打印2,因为2的连接还没断)、

验证结果:预期正确

观察3:reload,观察是否打印1,(预测打印1,reload会将之前的连接断开,之后新建的连接按配置文件连接到mysql主)

验证结果:预期错误,还是打印2

nginx的work没有立即退出,而是一直显示: nginx: worker process is shutting down(ps查看的结果)

分析:对于tcp连接,ngxin的旧work进程会等待没有数据传输之后才会断开连接,而实验中由于是每隔0.1s就会查询数据,导致nginx的旧work一直不能退出。

改进:配合worker_shutdown_timeout使用(配置文件增加worker_shutdown_timeout 60s;)

  • 实验核心代码:

@RequestMapping(value = "/get-for-test-mysql", method = RequestMethod.POST)
public void get(@RequestBody LockInput lockInput) throws InterruptedException {
    for(int i =0;i<10000;i++) {
        List<TestMysqlEntity> entities = testMysqlDao.getTestMysql(null);
        //0.1秒
        if(entities == null){
            log.info("get from mysql, value is null");
        } else {
            if(entities.isEmpty()){
                log.info("get from mysql, list is empty");
            } else {
                log.info("get from mysql, value is {} ", entities.get(0).getId());
            }
        }
        Thread.sleep(100);
    }
}

实验截图

Nginx配置文件

#user  nobody;
worker_processes  4;
worker_shutdown_timeout 60s;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

pid        /usr/local/nginx/logs/nginx.pid;


events {
    worker_connections  1024;
}


stream {
    upstream mysql-test{
        server 55.241.105.109:3306 weight=1 max_fails=3 fail_timeout=1s;
        server 55.241.105.119:3306 weight=1 max_fails=3 fail_timeout=1s backup;
    }
  server {
      listen 3307 so_keepalive=on;
      proxy_connect_timeout 3s;
      proxy_timeout 3s;
      proxy_pass mysql-test;
    }
}

小节

nginx可以优雅实现代理mysql主备;当mysql主挂掉后,nginx会将请求导向mysql备,并在mysql主恢复后,通过监控平台或脚本执行reload,nginx可以在指定时间后将连接切回到mysql主,并且在该时间内mysql主可以完成与备的数据同步,保证切回主后的数据一致性;备注:需要nginx配置文件增加worker_shutdown_timeout 60s;(此处为60s,可依据实际情况修改)

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0