当MySQL数据库遇到Syn Flooding
syn攻击是最常见又最容易被利用的一种攻击手法,利用tcp协议的缺陷,发送大量伪造tcp连接请求,常用假冒的ip发来海量的syn包,被攻击的服务器回应syn+ack,因为对方是假冒的ip,永远收不到包并且不会回应,导致被攻击服务器保持大量syn_recv状态的半连接,并且会重试默认5次回应握手包,塞满tcp等待连接队列,资源耗尽,让正常的业务请求连接不进来。
syn攻击常见于应用服务器,而数据库服务器在内网中,应该很难碰到类似的攻击,但有时候应用程序如果和数据库建连姿势不正确,在数据库端,也会被认为是syn攻击,并拒绝连接建立。
【问题描述】
数据库突发的拒绝链接,应用报错,出问题的时间点上,数据库服务器的操作系统日志里,即/var/log/messages,可看到如下报错信息:
kernel: possible syn flooding on port 3306. sending cookies.
【问题分析】
出问题的点上,从数据库的监控指标来看,threads connected 这个指标有增长。这个也是很明显,因为对数据库来说,syn flooding就是应用程序突发的对数据库发起建连,操作系统处理不过来,所以报syn flooding, 从数据库的性能指标来看,连接数肯定是会有一个突发的增长。应对方案就是需要分析这些突发的增长是怎么来的,削峰填谷,让连接更平稳。
【解决方案】
在数据库服务端,做如下调整:这个调整的意思是说:增加tcp半连接的缓冲,默认值是2048,我们调整到8192,让系统的抗突发压力增大一些。tcp_syn_retires和tcp_synack_retires默认是5,也就是服务器端要发送五次包,才会终止重试,我们把这个参数调整为2. 只重试一次,让出错的包尽量提早出错,以减少缓存的连接数。
echo 8192 > /proc/sys/net/ipv4/tcp_max_syn_backlog echo 2 > /proc/sys/net/ipv4/tcp_syn_retries echo 2 > /proc/sys/net/ipv4/tcp_synack_retries
这个参数调整,即时生效,无需重启。当然服务器重启后,这些参数也会回退到默认值。经此调整,数据库端的抗压能力得到加强,但并没有完全解决问题。
我们在客户端也做相应调整:
为减少数据库的连接数压力,通常我们建议连接池做如下配置:
testwhileidle="false"。空闲时不检测连接串健康 minidle="0"。连接池里面空闲连接的最小个数 maxage="30000"。一个链接超过多少毫秒就可以回收掉。 initialsize="1"。连接池里面初始连接的最小个数 timebetweenevictionrunsmillis="5000"。回收线程的运行间隔(毫秒)
对于现在的场景,我们建议调高minidle这个参数,从0调整到5. 让连接池平时有5个空闲连接存在,这样,发起对数据库请求的时候,会先使用这5个空闲连接。达到削峰填谷的作用。当然,副作用就是数据库平时的连接数会增长。具体调整到多少合适,需要结合实际的数据库连接负载情况。对于.net程序,也有相应的连接池参数可以调整:可以适当修改minpoolsize这个参数,也调整到5.
经此调整,基本上大部分的数据库syn flooding问题都能解决。
当然,这些都是调优的手段,只能是微微的改善系统。提高抗压能力。最终的分析,还是要看连接压力从何而来。以及为何需要突发建立大量连接到数据库。对于此种突发场景,用数据库是否合适。替代方案是前面用redis加一层缓冲。避免突发的对数据库发起建连请求。这个就涉及到应用的改造了。
上一篇: 卸载未能成功安装的mysql时的解决方案
下一篇: 海瑞为什么敢骂嘉靖帝?他不害怕吗
推荐阅读
-
Mysql数据库从5.6.28版本升到8.0.11版本部署项目时遇到的问题及解决方法
-
解决当MySQL数据库遇到Syn Flooding问题
-
python 连接数据库mysql解压版安装配置及遇到问题
-
当MySQL数据库遇到Syn Flooding
-
Python-Web框架之 - 利用SQLALchemy创建与数据库MySQL的连接, 详解用Flask时会遇到的一些大坑 !
-
eclipse Java web项目数据库由oracle更改为mysql中遇到的问题(使用JPA注解)附上修改过程
-
EFCore.MySql当模型遇到int[]怎么办
-
Spring boot中Spring-Data-JPA操作MySQL数据库时遇到的错误(一)
-
node连接mysql数据库遇到的问题和解决方案
-
Jmeter连接MySQL数据库进行查询实例及遇到问题