com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

项目运行许久,突然经常性的提示这个异常,过一段时间就会自己恢复,记录一下排查的过程

Communications link failure:通信链路故障,就是数据库连接异常。

所以排查思路大致如下:

1、检查数据库是否能正常登录使用

2、数据库是否有过升级?可能是连接驱动的问题?参考:

[已解决]踩过的坑之mysql连接报“Communications link failure”错误-腾讯云开发者社区-腾讯云

3、可能是代码中连接数过多,频繁请求(多线程)导致数据库拒绝连接?

在当前项目部署环境下查看特定数据库地址的网络连接情况:

netstat - anop | grep ip:port

查看后发现大量的数据库TIMA_WAIT,这个属于频繁的短连接,一般情况下是正常的,但这里如果在多线程使用连接,需要注意可能会耗尽资源,导致数据库拒接连接,同时也伴随着出现如下问题

'ip' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'"

这个异常是只当前ip因为多次连接错误,被mysql拒绝访问,可以通过 mysqladmin flush-hosts 的命令刷新,解除该ip的的限制,但这只是一个暂时性的解决方法,除此之外如果在检查过代码没问题外,还有几种解决方式:

        ①、调整 MySQL 的 max_connect_errors 参数(暂时)

SHOW VARIABLES LIKE 'max_connect_errors'; //查看当前的 max_connect_errors

SET GLOBAL max_connect_errors = 1000; //修改 max_connect_errors 的值

        ②、编辑 MySQL 的配置文件/etc/mysql/my.cnf(永久)

在my.cnf中的[mysqld]下添加配置,然后重启 systemctl restart mysqld

max_connect_errors = 1000;

        ③、调整数据库连接池的大小

        ④、数据库增加定时器,定期刷新hosts;
        参考:Mysql使用定时器自动执行FLUSH HOSTS处理_flush hosts;-CSDN博客

    但以上的解决方式只是暂时的,并没有找到问题的根源        


4、可能是数据库数据量过大,或者sql语句引起的问题

        ①、查询慢sql日志

        ②、explain sql 分析查询范围

        ③、数据量大进行迁移或者分库分表

5、网络波动导致连接不稳定

        ①、通过一个简单的脚本检测tcp的连接,检测结果记录在日志中

#!/bin/bash

IPS=(
  "ip:port"
  "ip:port"
)

LOG_FILE="/home/tcp_check.log"

while true;do
  CURRENT_TIME=$(date +"%Y-%m-%d %H:%M:%S")
  for IP_PORT in "${IPS[@]}";do
   IP=$(echo "$IP_PORT" | cut -d':' -f1)
   PORT=$(echo "$IP_PORT" | cut -d':' -f2)
   if timeout 3 bash -c "cat < /dev/null> /dev/tcp/$IP/$PORT" 2>/dev/null; then
    STATUS="成功"
   else
    STATUS="失败"
   fi
   echo "[$CURRENT_TIME] 检测 $IP:$PORT 的状态:$STATUS" >> "$LOG_FILE"
  done
  sleep 1
done

经过记录后发现,在代码报错的时候,此记录均为成功状态,ping也是成功的,但用telnet时发现连接是不成功的,所以这个脚本只检查tcp连接,无法判断服务器是否有响应。

        ②、可能是握手协议没完成,导致应用接收到异常。这时候再看“Host 'xxx' is blocked because of many connection errors. Unblock with 'mysqladmin flush-hosts'”这个错误时,通过查阅,了解到一个mysql的参数:max_connect_errors 

参考文章:MySQL参数max_connect_errors分析释疑 - 潇湘隐者 - 博客园

且host_cache的字段是统计被视为“阻塞”的连接错误的数量(根据max_connect_errors系统变量进行评估)。 只计算协议握手错误,并且仅用于通过验证的主机(HOST_VALIDATED = YES)。

所以超过连接超时的时间范围内,握手协议未完成后,就会记录一次SUM_CONNECT_ERRORS,且COUNT_HANDSHAKE_ERRORS也增加一次。


所以综上所述,由于网络不稳定,导致客户端与数据库之间连接的握手协议没有完成,导致发生Communications link failure 和 ip is blocked because of many connection errors两个错误,就算解决掉blocked的错误后,握手协议不完成,依旧会连接失败,再加上线程池的使用,一个线程失败后,需要等到池里的连接过时才会继续连接,就会出现时好时坏的现象了

最终的网络问题还需要专业的人员解决。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值