本篇内容主要讲解“TCP Keepalive对系统性能有什么影响”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“TCP Keepalive对系统性能有什么影响”吧!
话说当天 15:30分 左右收到 Nginx
告警信息(感谢运维童鞋的努力,让我们可以实时掌握系统运行情况),提示 Nginx Connection
数量超出常规设置。作为业界还算有点名声的网站,OSCHINA 社区网站流量突然飙升的情况可以说是家常便饭,一般情况下 Nginx Connection
超出我们设置的告警阀值之后,过段时间自然就会再回落(可能有些爬虫突然来访、或者部分善意的童鞋发送测试请求等)。所以,一开始并没有特别在意这个告警信息,只是等着「过段时间」即可。为了保证网站各项服务不出问题,我还是很小心的看了下集群中各个应用的情况 —— 一切正常如故。这时候,我也做好了准备,如果流量继续攀升导致服务收到影响的话,集群中的其他几台应用也要通过 upstream
开启分流模式,从而保证整站服务运行正常。
Nginx Connection 数量飙升
正在我犹豫是不是需要开启备用的其他几个应用分流时,突然又收到了 MySQL Connection
告警信息,这才开始意识到问题的严重性。一般情况下,我们配置的 MySQL
数据库链接是足够集群中的所有应用正常读写数据的,但如果 MySQL
连接数出现飙升的问题,集群中就可能出现部分节点无法拿到数据库连接的情况,从而导致部分用户请求受阻。就在短短几分钟之内,我们配置的数据库连接池被占满,大量用户请求因为无法获取数据库连接而开始缓慢,甚至部分用户开始出现无法访问、打开很慢等情况。
MySQL Connection 数量飙升
OSCHINA 网站大量使用了缓存技术,因此 MySQL
数据库的压力基本不大,QPS
也不会很高。但是此时,MySQL
连接数已经超过3k而且看似根本停不下来。这就勾起了我的好奇心:到底 MySQL 在做什么事情?为什么会有这么多的连接呢?如果出现个别很复杂的查询语句卡住,导致出现很多慢查询的话,其他正常的请求也会逐渐无法获取连接从而导致应用完全失去响应。立马 ssh
到 MySQL
那台机器查看了机器情况以及 MySQL
慢查询,却发现很多以前只需要几十毫秒执行时间的 SQL
查询,如今却稳稳地卡在那里没有任何响应或者查询耗费很久时间。这样看来,并不是我们的应用出发了某些复杂的查询导致 MySQL
查询效率降低从而出现「卡壳」,而单纯只是前端 Nginx
那边的流量飙升导致的。
确定了各项应用的基本状态,发现已经有部分应用响应已经出现不及时或者没响应的情况。同时,有好几位同事已经在Q群里 at 我反馈社区网站打不开。眼下迫切需要完成的事情是:流量飙升是什么问题造成的?于是立马登录到前端 Nginx
机器查询访问日志,发现有几个请求量很大的 IP(别问我是怎么发现的,这事情很多方法可以做),于是当机立断在前端 Nginx
配置了 deny
参数封掉了那几个搞事情的 IP。默默观察,果然没过多久,数据库连接开始下降,应用逐渐开始恢复,之后 MySQL
告警恢复正常。随后又观察了集群中几个应用的状态,为了避免出现其他意外情况,重启并配置了几个应用准备应不时之需。这时,离故障出现(开始收到告警信息)已经有差不多十多分钟的时间,我们的应用都已经恢复,MySQL Connection
也在逐渐降低至我们可以接受的合理范围内,网站也能正常访问了。但神奇的是,Nginx Connection
告警一直在继续。难道,还有其他没有发现的 IP 在搞事情么?录到前端 Nginx
所在的机器之后却发现,似乎系统有明显的卡顿情况出现。top
看了一眼才知道 CPU
和内存莫名其妙的飙升许多。本想着流量恢复正常之后,那些莫名其妙被打开的 Nginx
连接会自动释放,但是迟迟没看到有变化。
这下事情就很清晰了:流量突然飙升导致 Nginx Connection
数量大增,同时也会带动应用的 MySQL Connection
数量大增(这个过程也正好可以通过我收到的告警过程得到验证)。在解决了问题且流量恢复正常之后,应用层的 MySQL Connection
逐步释放并得到恢复。然而,那些已经失效的网络请求造成的 Nginx Connection
却始终无法被释放。所以,Nginx Connection
告警一直没有停止。
这时,虽然各项应用都已经恢复,但 Nginx Connection
告警一直未停止,令人不厌其烦。没办法只能向运维大神 @atompi 求救了。跟大神讲明了情况之后,大神果断登录到前端机器并查看了 Nginx
运行情况,没过多久回复说:很多底层 TCP
连接依旧不能正常释放,导致 Nginx Connection
居高不下。随即,我们简单验证了这个想法,发现系统默认配置的 TCP Keepalive
失效时间竟然需要两个小时之久(可能一开始配置系统参数时疏忽了)。马修改了相关配置,彻底停止再重启 Nginx
之后,一切恢复正常,Nginx Connection
数量也下降并恢复到正常值。
(所以,遇到自己解决不了的问题时,及时找大神帮忙。你们,学会了吗?)
想必大家都知道 HTTP
的 Request -> Response
无状态模式,在早期 HTTP 1.0
时代每个请求执行完成之后,作为 OSI七层模型 中传输层 TCP 连接是需要断开连接的,甚至每一次的请求中都需要 TCP三次握手四次挥手 才能完整处理。这样的处理方式虽然保证了网络传输的准确性及完整性,但效率实在不高。为了能够提升效率,在后来的 HTTP 1.1
规范中把 Connection
头写入了标准,并且默认启用。通过这个标准的定义,约束底层的 TCP
连接不会立马被释放(复用 TCP
连接),从而提升网络传输效率。现代浏览器基本上都默认会开启 Connection: keep-alive
以提升访问速度。(现代 web 服务器都具备自己的 keepalive_timeout
或者类似的配置,具体参数可能会有不同,但大致都是同样的作用。关于 HTTP Keepalive
以及 web 性能的分析,请阅读 《HTTP Keepalive Connections and Web Performance》)
抛开 HTTP Keepalive
不谈,TCP Keepalive
并不是一个大家约定的标准,但却被广泛支持。当网络上的连接已经建立之后,如果应用层很久没有传输数据、或者其他意外情况发生时,当前连接是不是应该继续保持呢?TCP Keepalive
正是检测 TCP
连接是否需要保持亦或需要断开的检测依据。TCP Keepalive
的机制是:它会在隔开一段时间之后发送几次没有数据内容的网络请求来判断当前连接是不是应该继续保留。在 CentOS
系统中 /etc/sysctl.conf
文件有关于 TCP Keepalive
的几个重要参数:
tcp_keepalive_time = 7200 (seconds) tcp_keepalive_intvl = 75 (seconds) tcp_keepalive_probes = 9 (number of probes)
上面几个参数可以通俗的理解为: TCP Keepalive
进程会等待 7200秒
之后发送第一个测试数据包来检测当前连接是否应该保持,然后间隔 75秒
再检测,一共检测 9
次。 这几个数字是默认值,根据自己的实际情况来做一定的调整即可达到更好的网络吞吐目的。
到此,相信大家对“TCP Keepalive对系统性能有什么影响”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。