记一次MySQL假死经历

最近在测试环境联调,发现个好玩的,记录一下:
起因:调用接口,返回状态码 504。
经过:一系列面向Google解决Bug。

Nginx 504 Gateway Time-out:

一般是由于程序执行时间过长导致响应超时,例如程序需要执行90秒,而nginx最大响应等待时间为30秒,这样就会出现超时。

通常有以下几种情况导致:
  • 程序在处理大量数据,导致等待超时。
  • 程序中调用外部请求,而外部请求响应超时。
  • 连接数据库失败而没有停止,死循环重新连。

出现这种情况,我们可以先优化程序,缩短执行时间。另一方面,可以调大nginx超时限制的参数,使程序可以正常执行。

解决方法:

修改Nginx配置:
nginx.conf中,设置以下几个参数,增加超时时间
fastcgi_connect_timeout fastcgi连接超时时间,默认60秒
fastcgi_send_timeout nginx 进程向 fastcgi 进程发送请求过程的超时时间,默认值60秒
fastcgi_read_timeout fastcgi 进程向 nginx 进程发送输出过程的超时时间,默认值60秒

你以为到这就完事了?并没有,事情并没有辣么的简单。要是如此简单就不会有这篇记录了。
查了一下java程序的日志,发现是mysql的问题。

顺便查了一下mysql的错误日志(error.log)
日志啊,都是错……瞬间爆炸……

以下是一些有用的错误信息:

Got timeout reading communication packets => (读取通信包超时)

'Can't create thread to handle new connection' error(s) suppressed => ('不能创建线程来处理新连接'错误被抑制)

Can't create thread to handle new connection(errno= 11)  => (无法创建线程来处理新连接(errno= 11))

Forcing close of thread 50106  user: 'root' => (强制关闭线程50106用户:'root')

经过几分钟的猜测与分析:(只有猜测和Google)

导致响应504是因为java程序连接不上mysql,数据库炸了的主要错误信息Forcing close of thread xxx user: ‘root‘
这是MySQL自身的原因:DNS 反解析:

mysql默认状态下是自动dns反向解析的,这是属于mysql系统上的一个特殊设定(感觉上是个Bug);不管链接的的方式是经过 hosts 或是 IP 的模式,它都会对 DNS 做反查 mysqld 会尝试去反查 IP → dns ,由于反查解析过慢,就会无法应付过量的查询。如果处于公网上的MySQL出现大量的非法用户尝试登陆的情况,给服务器带来的负荷是不可想像的。

解决方法:

修改my.cnf,重启数据库。

[mysqld]
skip-name-resolve

贴一张mysql官网的图,有图有真相奥。


MySQL官网截图 有图有真相

应个某人要求,贴个翻译哈


结果:由于是第一次遇到这个问题,暂时不能确诊,只能说经这一波操作之后504的问题没有出现,再留院观察观察……

你可能感兴趣的:(记一次MySQL假死经历)