MySQL中间件的连接错误问题排查

作者: admin 分类: 公众号存档            2 次浏览 发布时间: 2019-06-25 23:43

公众号:杨建荣的学习笔记 · 作者:杨建荣 · 发布:2019-06-25 23:43:05 · 原文链接

这是学习笔记的第 2020 篇文章

  最近在对一个线上的分布式环境做高可用配置,在流程测试通过后,发现中间件中出现了大量的连接错误。

错误信息如下:

INFO   | jvm 1    | 2019/06/25 08:53:35 | 2019-06-25 08:53:35,484 [ERROR][$_NIOREACTOR-3-RW] register err java.nio.channels.ClosedChannelException
INFO   | jvm 1    | 2019/06/25 08:53:35 |       at sun.nio.ch.SocketChannelImpl.ensureReadOpen(SocketChannelImpl.java:257)
INFO   | jvm 1    | 2019/06/25 08:53:35 |       at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:300)
INFO   | jvm 1    | 2019/06/25 08:53:35 |       at io.mycat.net.NIOSocketWR.asynRead(NIOSocketWR.java:188)
INFO   | jvm 1    | 2019/06/25 08:53:35 |       at io.mycat.net.AbstractConnection.asynRead(AbstractConnection.java:273)
INFO   | jvm 1    | 2019/06/25 08:53:35 |       at io.mycat.net.FrontendConnection.register(FrontendConnection.java:444)
INFO   | jvm 1    | 2019/06/25 08:53:35 |       at io.mycat.net.NIOReactor$RW.register(NIOReactor.java:160)
INFO   | jvm 1    | 2019/06/25 08:53:35 |       at io.mycat.net.NIOReactor$RW.run(NIOReactor.java:92)
INFO   | jvm 1    | 2019/06/25 08:53:35 |       at java.lang.Thread.run(Thread.java:748)
INFO   | jvm 1    | 2019/06/25 08:53:35 |  (io.mycat.net.NIOReactor$RW:NIOReactor.java:163)
INFO   | jvm 1    | 2019/06/25 08:53:38 | 2019-06-25 08:53:38,892 [ERROR][$_NIOREACTOR-4-RW] register err java.nio.channels.ClosedChannelException

目前的技术栈架构是LVS+keepalived+MyCAT+MySQL,如下图所示:

对于这个问题的定位也算是比较曲折,最初是认为防火墙权限的问题,于是我做了如下的几个场景测试,结果大多数场景都失败了。

lvs防火墙 有错误日志
中间件防火墙 有错误日志
中间件到数据节点的防火墙 有错误日志
复制一个新的中间件,不配置lvs 无错误日志
停止中间件节点的VIP配置 有错误日志
jdk安装包不够完整,重新安装 有错误日志
拷贝完整的目录,重新启动 有错误日志

最后得到了一个初步的结论:新配置的节点MyCAT可以正常启动,而已有的集群配置会出现问题,所以这个问题经过这样一系列测试,让人有些无奈。

当然也不是徒劳,经过这样一个过程之后,我和系统部的同事对这些服务器的其他配置做了对比,发现唯一的差别就是是否启用了LVS。

经过进一步的分析和确认,算是基本定位问题的位置了,那就是错误日志的输出格式比较规律,即每10秒钟会输出一批错误。按照这个规律我在lvs中进行检查,发现keepalived的配置确实有一个delay_loop的配置是10秒。顺着这个思路下去,发现对于RS的检测,这里使用的是TCP_CHECK的方式,而这种方式的连接注册对于MyCAT来说是不够友好的。在官网也找到了类似的错误说明,目前还没有很好的解决方式,而要更为优雅的解决,那就是使用TCP_CHECK之外的验证方式,这里推荐的就是MISC_CHECK(自定义脚本)的方式了。

RS的配置信息如下,在此我们定义了一个检查脚本,输出0或者1来进行状态校验。

配置信息如下:

    real_server xx.124.140 8066 {
        weight 1
        inhibit_on_failure
       # TCP_CHECK {
       #     connect_timeout 1
       #     nb_get_retry 3
       #     delay_before_retry 1
       #            connect_port 8066
       # }
        MISC_CHECK {
          misc_path “/etc/keepalived/scripts/mycat_check.sh xx.124.140 8066 tkgrowlog”
          misc_timeout 10
          misc_dynamic
       }
    }

    real_server xx.124.142 8066 {
        weight 1
        inhibit_on_failure
       # TCP_CHECK {
       #     connect_timeout 1
       #     nb_get_retry 3
       #     delay_before_retry 1
       #     connect_port 8066
       # }
        MISC_CHECK {
          misc_path “/etc/keepalived/scripts/mycat_check.sh xx.124.142 8066 tkgrowlog”
          misc_timeout 10
          misc_dynamic
    }

而检测脚本的内容如下,根据轮询的机制,会输出日志到keepalived指定的目录下。

# cat mycat_check.sh
#!/bin/bash
result=`nc -v -z $1 $2`
flag=”succeeded”
time=$(date “+%Y-%m-%d %H:%M:%S”)
if [[ $result =~ $flag ]]
then
    echo “$time “$1:$2:$3″:  mycat is running…” >> /var/log/keepalived_check.log
    exit 0
else
    echo “$time “$1:$2:$3″:  mycat is not running…” >> /var/log/keepalived_check.log
    exit 1
fi

日志的输出如下:

2019-06-25 18:53:11 10.30.124.140:8066:testappdb:  mycat is running…
2019-06-25 18:53:14 10.30.124.135:8064:testappdb:  mycat is running…
2019-06-25 18:53:14 10.30.124.134:8064:testappdb:  mycat is running…
2019-06-25 18:53:15 10.30.124.137:8065:testappdb:  mycat is running…
2019-06-25 18:53:16 10.30.124.138:8065:testappdb:  mycat is running…
2019-06-25 18:53:17 10.30.124.142:8066:testappdb:  mycat is running…

按照目前的状态在下午的高可用测试中,前端业务几乎无感知。

高可用的测试大体包含如下的范围:

  1. 停止一个中间件节点,预期是对于业务无感知

  2. 停止两个中间件节点(一共两个),这时候业务连接失败,会在业务层转储生成日志信息,为后期的数据补录提供基础

  3. 关闭部分应用服务器节点的防火墙权限,短时间内没有变化,是因为这里使用的是长连接,而在一段时间之后,比如5-10分钟左右,会在业务层抛出错误

  4. 关闭MySQL节点,触发MHA切换,对于业务层有一定的影响,但是基于MHA高可用机制,业务会很快恢复。

相关链接:

MySQL分布式高可用的一个补充

admin

杨建荣,《Oracle DBA工作笔记》《MySQL DBA工作笔记》作者,dbaplus社群发起人之一,腾讯云TVP,现任竞技世界系统部经理,拥有十多年数据库开发和运维经验,目前专注于开源技术、运维自动化和性能调优

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注