阿里云安全组怎么设置 阿里云服务器过户办法

简介:Redis客户端库连接Redis服务器超时差不多一两年前,我在阿里云上遇到一个奇怪的Redis连接问题。每隔十分钟,服务中的Redis客户端库报告与Redis服务器的连接超时。当时费了九牛二虎之力才发现,阿里云会断开闲置了很久的TCP连接,而且没有给两个FIN或者RST包。当时我们的...

简介:Redis客户端库连接Redis服务器超时

差不多一两年前,我在阿里云上遇到一个奇怪的Redis连接问题。每隔十分钟,服务中的Redis客户端库报告与Redis服务器的连接超时。当时费了九牛二虎之力才发现,阿里云会断开闲置了很久的TCP连接,而且没有给两个FIN或者RST包。当时我们的Redis服务器没有开放tcp_keepalive选项,所以Redis服务器端的连接仍然存在于Linux conntrack表中,而Redis客户端因为连接池重用连接get和set发现连接断开而关闭。因此,客户端对应的本地端口被恢复,当Redis重用这个本地端口来发起与Redis服务器的连接时,因为<>

解决这个问题很简单,打开Redis服务器的tcp_keepalive选项就可以了。但是,当时没想到,这个问题的深层次原因影响之大,后果之严重!

恶债:”选择1 ″触发JDBC 4 . communication s exception

最近,生产环境中的Java服务几乎每分钟都会报告如下错误:

由于之前有阿里云调查Redis连接异常中断的先例,所以怀疑是类似问题。比较客户端和服务器的conntrack表花了很多时间,但是没有介绍中描述的问题。然后,比较了多个MySQL服务器的sysctl设置,研究了iptables TRACE,研究了tcpdump捕获的消息。试验tw_reuse、tw_recyle等参数,调整阿里云负载均衡器后面挂载的MySQL服务器数量。然而,我们* *出乎意料地发现了一个* *新问题。当使用下面这个命令不经过阿里云SLB直接连接数据库时,有的数据库600s就能返回,有的挂了半个多小时,也回不来了。即使按ctrl-c也不能中断。

当时查了一个正常数据库和一个异常数据库,发现两个数据库的wait_timeout和interactive_timeout都是600s。我想了好的坏的,但我不明白这是怎么回事。然后偶然发现了另一个数据库的wait_timeout=60s,却突然明白了原来的“选择1 ”有什么问题?

我们的服务使用光JDBC连接池[1],其idleTimeout默认为600s,最大生存期默认为1800s。前者是指空闲JDBC连接数超过minimumIdle数,空闲时间超过idleTimeout,那么这个空闲连接就会被关闭,后者是指连接池中的连接不能活得超过***xLifetime,到达点就会被关闭。

在“选择1 ”出问题后,我们认为这两个参数大于数据库的wait_timeout=600s,于是将这两个参数降为idle timeout = 570s,***xlifetime = 585s,并设置minimumIdle=5。但这两个时间设置还是大于其中一个数据库错误设置的wait_timeout=60s,所以60s后空闲连接被MySQL服务器主动关闭。但是JDBC没有任何事件触发的回调机制来关闭JDBC连接,时间也不够光触发idleTimeout和***xLifetime清理逻辑,于是光就拿这个“关闭”的连接发“选择1 ”SQL检查到服务器的连接的有效性,这触发了上面的异常。

解决方法很简单,只需将错误配置的数据库中的wait_timeout从60s改为600s即可。以下继续“选择睡眠(1000)”会挂掉退不掉的问题。

缘起:阿里云安全集团和TCP KeepAlive

最近看了一些佛教常识,对“一切法皆由因缘生”的缘起论印象很深。我正在调查“选择睡眠(1000)”在问题中,我真切地感受到了“从因缘”的含义

首先解释一下为什么有些数据库服务器对“选择睡眠(1000)”可以退,但有些退不了。实际上,wait_timeout和interactive_timeout参数只对“空闲”数据库连接有效,即没有SQL运行的连接。对于“选择睡眠(1000)”,有一个正在执行的SQL,其最大执行时间受限于MySQL服务器的***x_execution_time。该参数在我公司一般设置为600s,即“普通数据库”在600多岁时。选择睡眠(1000)”中断执行并退出。

不幸的是(另一个错误配置),我们的数据库***x_execution_time是6000s,所以“选择睡眠(1000)”在mysql服务器上,正常执行会在1000s结束——但问题是通过二分搜索法、tcpdump和iptables TRACE,阿里云会“默默”丢弃>:=910s的空闲TCP连接,没有向客户端和服务器发送FIN或RST强制断开连接,所以MySQL服务器在1000s结束时向客户端发送的ACK+PSH TCP包无法到达客户端,然后wait_timeout=600s,MySQL服务器断开了这个空闲连接——很不幸,MySQL客户端它持续等待MySQL服务器返回。Linux内核的conntrack表显示这个连接已经建立,尽管MySQL服务器已经关闭了相应的连接,但是这个关闭动作的FIN TCP包是无法到达客户端的!

以下是来自iptables TRACE log的这个问题的真锤证明。

mysql命令行所在机器的iptables跟踪日志显示,mysql客户端在23:58:25连接mysql服务器,开始执行SELECT sleep(1000),之后再也没有收到服务器消息。最后在00:41:20,我手动杀死mysql客户端的命令行进程。mysql客户端向mysql服务器发送FIN包,但是没有收到响应(此时mysql服务器的连接已经关闭)。

MySQL server 在 00:15:05 时执行 SELECT sleep(1000) 结束,给 mysql 客户端回送结果,但 mysql 客户端无响应(被阿里云丢包了,mysql 客户端压根收不到),在 00:25:05 时,由于 wait_timeout=600s,所以 MySQL server 给 mysql 客户端发 FIN 包以断开连接,自然,mysql 客户端收不到,所以也没有回应,结局是 MySQL server 一侧的 Linux 内核反正自行关闭 TCP 连接了,mysql client 一侧的 Linux 内核还在傻乎乎的在 conntrack table 维持着 ESTABLISHED 状态的 TCP 连接,mysql client 命令行还在傻乎乎的 recv 等着服务端返回或者关闭链接。00:15:05,服务器执行SELECT sleep(1000),将结果返回给mysql客户端,但是mysql客户端没有响应(被阿里云丢失,mysql客户端根本接收不到)。00:25:05,由于wait_timeout=600s,因此,mysql服务器向mysql客户端发送FIN包断开连接。MySQL客户端自然收不到,所以不响应。最终,MySQL服务器端的Linux内核还是自己关闭了TCP连接。mysql客户端的Linux内核还在傻乎乎的维护conntrack表中已经建立的TCP连接,mysql客户端命令行还在傻乎乎的等待服务器返回或者关闭recv中的链接。

好了,现在我知道是阿里云>:= 910s。如果虚拟机之间没有TCP包传输,空闲的TCP连接会“默默”丢包,那么有没有虚拟机之间呢?它是任何港口吗?服务器需要挂在负载均衡器后面吗?您是否需要到相应端口的一定数量的并发连接?

阿里云提交工单进行查询后,并没有得到任何有价值的信息。经过艰苦的实验——每个实验都要等将近二十分钟——一切都有了回报。我发现了一个稳定循环的规则:

两台虚拟机分别处于不同安全组,没有共同安全组;服务端的安全组开放端口 P 允许客户端的安全组连接,客户端不开放端口给服务端(按照一般有状态防火墙的配置规则,都是只开服务端端口,不用开客户端端口);客户端和服务端连接上后,闲置 >= 910s,不传输任何数据,也不传输有 keep alive 用途的 ack 包;然后服务端在此长连接上发给客户端的 TCP 包会在网络上丢弃,到不了客户端;但如果客户端此时给服务端发点数据,那么会重新“激活”这条长链接,但此时还是单工状态,客户端能给服务端发包,服务端的包还到不了客户端(大概是在服务端 OS 内核里重试中);激活后,服务端再给客户端发数据时,之前发送不出去的数据(如果还在内核里的 TCP/IP 协议栈重试中),加上新发的数据,会一起到达客户端,此后这条长连接进入正常的双工工作状态;

下图是nc测试的结果。

计算机网络服务器

和网友讨论后才知道,这应该是阿里云安全组实施“集中式防火墙”造成的。由于集中式防火墙处于网络的中枢,要应对海量的连接,其内存中的conntrack表需要相对较短的空闲超时(目前为910s)来清理长时间不活动的conntrack记录以节省内存,所以上述问题的根源很明显:

client 连接 server,安全组(其实是防火墙)发现规则允许,于是加入一个记录到 conntrack table;client 和 server 到了 910s 还没数据往来,所以安全组把 conntrack 里那条记录去掉了;server 在 910s 之后给 client 发数据,数据包到了安全组那里,它一看 conntrack table 里没记录,而 client 侧安全组又不允许这个端口的包通过,所以丢包了,于是 server -> client 不通;client 在同一个长连接上给 server 发点数据,安全组一看规则允许,于是加入 conntrack table 里;server 重试的数据包,或者新数据包,通过安全组时,由于已经有 conntrack record 了,所以放行,于是能到达客户端了。

我明白为什么了。我该如何解决这个问题?阿里云给了我两个不可接受的变通办法:

把 server、client 放进同一个安全组;修改 client 所在安全组,开放所有端口给 server 所在安全组;

想了想,通过netstat -o发现我们的Java服务使用的Jedis库和mysql JDBC库都在socket文件句柄上有SO_KEEPALIVE选项[2]:

MySQL服务器也为其open socket文件句柄开放了SO_KEEPALIVE选项,所以我只需要在下层服务器和客户端的至少一侧修改对应的sysctl选项即可。下面是我们服务器的默认配置,也就是说TCP连接空闲1800s后,每30s就会给对方发送一个ACK包。最多发3次。如果对方在此期间回复,定时器将重置,然后等待1800s的空闲状态。如果发送了3次对方都没有响应,那么它会向对方发送RST包,同时关闭本地socket文件句柄,也就是关闭这个长连接。

由于阿里云跨安全组的910s空闲超时限制,需要将
net . IP v4 . TCP _ keepalive _ time设置为小于910s,比如300s。

默认的tcp_keepalive_time特别大,这也解释了为什么Redis客户端在设置了SO_KEEPALIVE选项后,会被阿里云默默断开连接。

如果有些网络库封装后不提供调用setsockopt的机会,需要通过LD_PRELOAD等黑科技强制设置。只有当socket文件句柄的SO_KEEPALIVE选项开启时,以上三个sysctl才会在这个socket文件句柄上生效。当然也可以使用setsockopt函数在代码中进一步设置keep_alive_intvl和keepalive_probes,而不是Linux内核的全局默认设置。

最后,除了Java对SO_KEEPALIVE的处理比较好,使用netstat -o check,发现对门NodeJS著名的Redis客户端库已经开放了SO_KEEPALIVE但是其著名的mysql客户端库没有,而Golang的则严谨得多,两个库都开放了SO_KEEPALIVE。为什么介绍里说这个问题很严重?但是,如果服务器处理缓慢,如OLAP场景,并且服务器不通过阿里云SLB直连在910秒内不返回数据,则可能没有机会向客户端返回数据。来看看这个问题是不是死了!你可能会问我为什么不通过阿里云SLB中转。SLB不会无声无息地丢失数据包——但它的空闲超时限制是900秒!!!

图片来源:“没有虫子”野兔

高可用性架构

改变互联网的构建方式

本文来自又何必自找失落╮投稿,不代表舒华文档立场,如若转载,请注明出处:https://www.chinashuhua.cn/24/575799.html

打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
() 0
上一篇 06-03
下一篇 06-03

相关推荐

  • 云服务器管理有哪些功能 云服务器管理的作用

    生活中经常听说云服务器。你知道云服务器的功能是什么吗?如果你不知道,那就和边肖一起看看吧。1.网络服务对于需要有网络站点的中小企业和个人来说,租用服务器是一个不错的选择。因为云服务器的预配置不需要那么多,可以买现成的,也有很多宽带选择,所以每个网站都可以有自

    2023-07-27 21:46:01
    444 0
  • 服务器备份软件有哪些(服务器自动备份及恢复软件)

    SyncBackPro备份软件是由2BrightSparks公司开发的用于备份、同步和恢复数据文件的专业工具。该软件可以在便携式设备之间自动传输媒体文件,并备份数据文件、图片、电子邮件、音乐文件、文档、电子表格和电影。SyncBackPro通过结合运行、创建配置文件脚本和自动驱动器故障检测

    2023-07-27 18:47:01
    531 0
  • 域名怎么用在服务器上,域名使用文档介绍

    购买域名后如何使用?你有什么技能?买了域名之后,就看你用它做什么了。注册后可以用域名申请企业邮箱,大部分用来建网站。我们来看看如何使用域名,购买后有哪些技巧。购买域名后如何使用?你有什么技能?1.企业电子邮件应用程序购买域名后,可以直接申请企业邮箱,进入西数

    2023-07-27 10:41:01
    1059 0
  • 服务器一般多少钱一个月 阿里云服务器租用费用

    目前市场上的网站价格参差不齐,每家公司都没有明码标价,导致很多企业不知道如何选择专业水平的网站建设公司,怕被骗花钱,做出来的网站没有效果。事实上,顾客的担心并非多余。有些公司收钱是为了盈利,但并不是真的为客户服务。这种现象依然存在。今天财利信息分析一下做一

    2023-07-27 09:56:01
    377 0

评论列表

联系我们

在线咨询: QQ交谈

邮件:admin@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信