badgateway是啥意思怎么解决(解决badgateway的方法)

前言

事实证明,读过Linux内核源码确实有很大的好处,尤其在处理问题的时刻。当你看到报错的那一瞬间,就能把现象/原因/以及解决方案一股脑的在脑中闪现。甚至一些边边角角的现象都能很快的反应过来是为何。1481百科网小编读过一些Linux TCP协议栈的源码,就在解决下面这个问题的时候有一种非常流畅的感觉。

Bug现场

首先,这个问题其实并不难解决,但是这个问题引发的现象倒是挺有意思。先描述一下现象吧,笔者要对自研的dubbo协议隧道网关进行压测(这个网关的设计也挺有意思,准备放到后面的博客里面)。先看下压测的拓扑吧:

badgateway是啥意思怎么解决(解决badgateway的方法)

为了压测笔者gateway的单机性能,两端仅仅各保留一台网关,即gateway1和gateway2。压到一定程度就开始报错,导致压测停止。很自然的就想到,网关扛不住了。

网关的情况

去Gateway2的机器上看了一下,没有任何报错。而Gateway1则有大量的502报错。502是Bad Gateway,Nginx的经典报错,首先想到的就是Gateway2不堪重负被Nginx在Upstream中踢掉。

badgateway是啥意思怎么解决(解决badgateway的方法)

那么,就先看看Gateway2的负载情况把,查了下监控,发现Gateway2在4核8G的机器上只用了一个核,完全看不出来有瓶颈的样子,难道是IO有问题?看了下小的可怜的网卡流量打消了这个猜想。

Nginx所在机器CPU利用率接近100%

这时候,发现一个有意思的现象,Nginx确用满了CPU!

badgateway是啥意思怎么解决(解决badgateway的方法)

再次压测,去Nginx所在机器上top了一下,发现Nginx的4个Worker分别占了一个核把CPU吃满-_-!

badgateway是啥意思怎么解决(解决badgateway的方法)

什么,号称性能强悍的Nginx竟然这么弱,说好的事件驱动epoll边沿触发纯C打造的呢?一定是用的姿势不对!

去掉Nginx直接通信毫无压力

既然猜测是Nginx的瓶颈,就把Nginx去掉吧。Gateway1和Gateway2直连,压测TPS里面就飙升了,而且Gateway2的CPU最多也就吃了2个核,毫无压力。

badgateway是啥意思怎么解决(解决badgateway的方法)

去Nginx上看下日志

由于Nginx机器权限并不在笔者手上,所以一开始没有关注其日志,现在就联系一下对应的运维去看一下吧。在accesslog里面发现了大量的502报错,确实是Nginx的。又看了下错误日志,发现有大量的

Cannot assign requested address

由于笔者读过TCP源码,一瞬间就反应过来,是端口号耗尽了!由于Nginx upstream和后端Backend默认是短连接,所以在大量请求流量进来的时候回产生大量TIME_WAIT的连接。

badgateway是啥意思怎么解决(解决badgateway的方法)

而这些TIME_WAIT是占据端口号的,而且基本要1分钟左右才能被Kernel回收。

badgateway是啥意思怎么解决(解决badgateway的方法)
cat /proc/sys/net/ipv4/ip_local_port_range
32768	61000

也就是说,只要一分钟之内产生28232(61000-32768)个TIME_WAIT的socket就会造成端口号耗尽,也即470.5TPS(28232/60),只是一个很容易达到的压测值。事实上这个限制是Client端的,Server端没有这样的限制,因为Server端口号只有一个8080这样的有名端口号。而在upstream中Nginx扮演的就是Client,而Gateway2就扮演的是Nginx

badgateway是啥意思怎么解决(解决badgateway的方法)

为什么Nginx的CPU是100%

而笔者也很快想明白了Nginx为什么吃满了机器的CPU,问题就出来端口号的搜索过程。

badgateway是啥意思怎么解决(解决badgateway的方法)

让我们看下最耗性能的一段函数:

int __inet_hash_connect(...)
{
		// 注意,这边是static变量
		static u32 hint;
		// hint有助于不从0开始搜索,而是从下一个待分配的端口号搜索
		u32 offset = hint + port_offset;
		.....
		inet_get_local_port_range(&low, &high);
		// 这边remaining就是61000 - 32768
		remaining = (high - low) + 1
		......
		for (i = 1; i <= remaining; i++) {
			port = low + (i + offset) % remaining;
			/* port是否占用check */
			....
			goto ok;
		}
		.......
ok:
		hint += i;
		......
}

看上面那段代码,如果一直没有端口号可用的话,则需要循环remaining次才能宣告端口号耗尽,也就是28232次。而如果按照正常的情况,因为有hint的存在,所以每次搜索从下一个待分配的端口号开始计算,以个位数的搜索就能找到端口号。如下图所示:

badgateway是啥意思怎么解决(解决badgateway的方法)

所以当端口号耗尽后,Nginx的Worker进程就沉浸在上述for循环中不可自拔,把CPU吃满。

badgateway是啥意思怎么解决(解决badgateway的方法)

为什么Gateway1调用Nginx没有问题

很简单,因为笔者在Gateway1调用Nginx的时候设置了Keepalived,所以采用的是长连接,就没有这个端口号耗尽的限制。

badgateway是啥意思怎么解决(解决badgateway的方法)

Nginx 后面有多台机器的话

由于是因为端口号搜索导致CPU 100%,而且但凡有可用端口号,因为hint的原因,搜索次数可能就是1和28232的区别。

badgateway是啥意思怎么解决(解决badgateway的方法)

因为端口号限制是针对某个特定的远端server:port的。所以,只要Nginx的Backend有多台机器,甚至同一个机器上的多个不同端口号,只要不超过临界点,Nginx就不会有任何压力。

badgateway是啥意思怎么解决(解决badgateway的方法)

把端口号范围调大

比较无脑的方案当然是把端口号范围调大,这样就能抗更多的TIME_WAIT。同时将tcp_max_tw_bucket调小,tcp_max_tw_bucket是kernel中最多存在的TIME_WAIT数量,只要port范围 - tcp_max_tw_bucket大于一定的值,那么就始终有port端口可用,这样就可以避免再次到调大临界值得时候继续击穿临界点。

cat /proc/sys/net/ipv4/ip_local_port_range
22768	61000
cat /proc/sys/net/ipv4/tcp_max_tw_buckets
20000

开启tcp_tw_reuse

这个问题Linux其实早就有了解决方案,那就是tcp_tw_reuse这个参数。

echo '1' > /proc/sys/net/ipv4/tcp_tw_reuse

事实上TIME_WAIT过多的原因是其回收时间竟然需要1min,这个1min其实是TCP协议中规定的2MSL时间,而Linux中就固定为1min。

#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT
				  * state, about 60 seconds	*/

2MSL的原因就是排除网络上还残留的包对新的同样的五元组的Socket产生影响,也就是说在2MSL(1min)之内重用这个五元组会有风险。为了解决这个问题,Linux就采取了一些列措施防止这样的情况,使得在大部分情况下1s之内的TIME_WAIT就可以重用。下面这段代码,就是检测此TIME_WAIT是否重用。

__inet_hash_connect
	|->__inet_check_established
static int __inet_check_established(......)
{
	......	
	/* Check TIME-WAIT sockets first. */
	sk_nulls_for_each(sk2, node, &head->twchain) {
		tw = inet_twsk(sk2);
		// 如果在time_wait中找到一个match的port,就判断是否可重用
		if (INET_TW_MATCH(sk2, net, hash, acookie,
					saddr, daddr, ports, dif)) {
			if (twsk_unique(sk, sk2, twp))
				goto unique;
			else
				goto not_unique;
		}
	}
	......
}

而其中的核心函数就是twsk_unique,它的判断逻辑如下:

int tcp_twsk_unique(......)
{
	......
	if (tcptw->tw_ts_recent_stamp &&
	    (twp == NULL || (sysctl_tcp_tw_reuse &&
			     get_seconds() - tcptw->tw_ts_recent_stamp > 1))) {
       // 对write_seq设置为snd_nxt+65536+2
       // 这样能够确保在数据传输速率<=80Mbit/s的情况下不会被回绕      
		tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2
		......
		return 1;
	}
	return 0;	
}

上面这段代码逻辑如下所示:

badgateway是啥意思怎么解决(解决badgateway的方法)

在开启了tcp_timestamp以及tcp_tw_reuse的情况下,在Connect搜索port时只要比之前用这个port的TIME_WAIT状态的Socket记录的最近时间戳>1s,就可以重用此port,即将之前的1分钟缩短到1s。同时为了防止潜在的序列号冲突,直接将write_seq加上在65537,这样,在单Socket传输速率小于80Mbit/s的情况下,不会造成序列号重叠(冲突)。同时这个tw_ts_recent_stamp设置的时机如下图所示:

badgateway是啥意思怎么解决(解决badgateway的方法)

所以如果Socket进入TIME_WAIT状态后,如果一直有对应的包发过来,那么会影响此TIME_WAIT对应的port是否可用的时间。开启了这个参数之后,由于从1min缩短到1s,那么Nginx单台对单Upstream可承受的TPS就从原来的470.5TPS(28232/60)一跃提升为28232TPS,增长了60倍。如果还嫌性能不够,可以配上上面的端口号范围调大以及tcp_max_tw_bucket调小继续提升tps,不过tcp_max_tw_bucket调小可能会有序列号重叠的风险,毕竟Socket不经过2MSL阶段就被重用了。

不要开启tcp_tw_recycle

开启tcp_tw_recyle这个参数会在NAT环境下造成很大的影响,建议不开启。

Nginx upstream改成长连接

事实上,上面的一系列问题都是由于Nginx对Backend是短连接导致。Nginx从 1.1.4 开始,实现了对后端机器的长连接支持功能。在Upstream中这样配置可以开启长连接的功能:

upstream backend {
    server 127.0.0.1:8080;
# It should be particularly noted that the keepalive directive does not limit the total number of connections to upstream servers that an nginx worker         	process can open. The connections parameter should be set to a number small enough to let upstream servers process new incoming connections as 	well.
    keepalive 32; 
    keepalive_timeout 30s; # 设置后端连接的最大idle时间为30s
}

这样前端和后端都是长连接,大家又可以愉快的玩耍了。

badgateway是啥意思怎么解决(解决badgateway的方法)

由此产生的风险点

由于对单个远端ip:port耗尽会导致CPU吃满这种现象。所以在Nginx在配置Upstream时候需要格外小心。假设一种情况,PE扩容了一台Nginx,为防止有问题,就先配一台Backend看看情况,这时候如果量比较大的话击穿临界点就会造成大量报错(而应用本身确毫无压力,毕竟临界值是470.5TPS(28232/60)),甚至在同Nginx上的非此域名的请求也会因为CPU被耗尽而得不到响应。多配几台Backend/开启tcp_tw_reuse或许是不错的选择。

1481百科网小编总结

应用再强大也还是承载在内核之上,始终逃不出Linux内核的樊笼。所以对于Linux内核本身参数的调优还是非常有意义的。如果读过一些内核源码,无疑对我们排查线上问题有着很大的助力,同时也能指导我们避过一些坑!

本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1543321114@qq.com 举报,一经查实,本站将立刻删除。转载请注明出处:https://www.1481.net/m/18200.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
1481百科网1481百科网
0 0
nc什么意思(电气no和nc是什么意思)
上一篇 2023年3月26日 下午10:06
中国和洪都拉斯建交公报(建立大使级外交关系)
下一篇 2023年3月26日 下午10:14

相关推荐

  • 口袋妖怪究极绿宝石5.3四大天王打法攻略

    口袋妖怪究极绿宝石5.3游戏中有很多的额外技能可以通过和NPC进行交谈来获取,但也并不是只有这一种方式,其实还有很多种,不过有很多玩家都还没有将游戏中的各种技能给收集齐,那么下面就让1481百科网小编为大家分享一下全部技能招式的获取方法吧。   《口袋妖怪究极绿宝石5.3》全部技能招式获取方法介绍   技能地震、强力鞭打、垃圾射击、尖石攻击   获取地点:鬼...

    1481百科网 1481百科网
    2023年3月31日 趣味百科
    935 00
  • 2021年十大畅销书(2021年度好书大全有哪些)

    1481百科网分享:未来已来,将至已至。空气中已经弥漫着跨年的期待。或凛冽,或温暖,我们且行且珍惜,在不确定的时刻依然感到,有光在前。在即将送走2021,迎来2022第一道曙光之时,大家准备好了吗? 专家评选和发布的“名人堂·年度人文榜”已经连续举办多届,在出版界、作家圈、读书群中影响越来越大。2021年12月“名人堂·2021年度人文榜”之“十大好书”的盘...

    1481百科网 1481百科网
    2023年2月23日 趣味百科
    312 00
  • 八月十五的来历和风俗故事(八月十五的由来和习俗是什么)

    1481百科网整理分享:中秋节作为我国法定的传统节假日,一直深受人们的喜爱,中秋节这天,人们终于能从劳碌的工作和生活中得到放松,还可以和家人团聚,在是一件多么幸福和享受的事情,对于中秋节大家又有多少的了解呢? “中秋”一词,最早出现、最早记录在《周礼》之中。一年可以分为四季,每个季节又分为孟,仲,季,因此中秋也叫仲秋,每年在农历八月十五日这一天的月亮比其他几...

    1481百科网 1481百科网
    2023年3月31日 趣味百科
    5.4K 00
  • 显示器ips是什么意思(显示器选择最基本的方法)

    随着更多优质内容可以通过网络的形式与我们见面,大家对屏幕素质的关注度也日渐提升。显示屏幕作为我们与“世界”的交互窗口,想要用的舒心首先要了解它们的区别,以及自己的使用场景。 原来为电脑选购一款显示器只在乎品牌和尺寸,仔细了解后发现这里的门道其实还真不少。像手机屏幕类似的LCD、OLED屏幕一样,电脑显示器的常见面板分为IPS、VA、TN三类。对性能有一定要求...

    1481百科网 1481百科网
    2023年4月22日 趣味百科
    496 00
  • 海缸开缸步骤(海缸开缸注意事项)

    1481百科网小编整理分享:在水族店第一次见到海水观赏鱼的人,一定会为它绚丽迷人的色彩而叹为观止,也许从那时开始便时常会萌发一种想拥的愿望,可是由于听到的太多关于海水鱼难养的经验之谈,又望而却步。 海水鱼饲养可算是一项较大的投资,若因错误的操作而痛失鱼只,不仅承受经济上的损失,而且也成为您心灵中的伤痛。 正是大多数海水鱼爱好者目前的这种心态,使许多人陷入敢爱...

    1481百科网 1481百科网
    2023年7月2日 趣味百科
    213 00

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

最新发布

联系我们

QQ:1543321114

在线咨询: QQ交谈

邮件:1543321114@qq.com

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

玻璃钢生产厂家景德镇校园玻璃钢雕塑定做河北玻璃钢座椅雕塑博白玻璃钢雕塑佛像玻璃钢雕塑设计万源玻璃钢雕塑工厂玻璃钢雕塑如何制作frp仙居玻璃钢雕塑厂家淮北玻璃钢卡通雕塑重庆玻璃钢动物雕塑小品制作商场美陈的案例山南玻璃钢雕塑厂家玻璃钢花盆哪家买亳州玻璃钢动物雕塑湖北玻璃钢雕塑企业潼南区玻璃钢雕塑合肥玻璃钢雕塑订做价格平湖玻璃钢雕塑生产厂陕西佛像玻璃钢雕塑市场无锡玻璃钢广场雕塑价格玻璃钢花盆栽手绘鹤壁佛像玻璃钢人物雕塑厂家昆明玻璃钢花盆批发玻璃钢几何马雕塑价格玻璃钢草菇雕塑江苏玻璃钢花盆订购潮州玻璃钢透光雕塑制作江苏园林玻璃钢花盆安阳玻璃钢景观雕塑厂家琼海玻璃钢雕塑制作厂家嘉兴玻璃钢雕塑怎么样香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化