nginx测试异常问题定位

总结

在Intel上测试nginx发现了一个比较奇怪的现象,服务端压测时候,负载总是无法压上去,反而客户端随着核数增加,负载几乎100%,并且主要集中在sys上。

# 服务端测试命令:
​
taskset -c 0-7 /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
​
# 客户端测试命令: 使用lo网口
# 短链接
taskset -c 8-31 /home/nginx-test/httpress-1.1.0/bin/Release/httpress -n 1000000 -c 200 -t 16  http://127.0.0.1:10000/index.html
​

分析

从当前跟随核数的特征以及top显示的结果上看,问题大概率出现在抢锁的问题上。通过perf采样,可以证实:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UkZMMRs1-1654587488940)(https://user-images.githubusercontent.com/17999499/167791493-36ab3ab2-ac2d-4094-98b8-3d1ca5c57415.png)]

__inet_check_established函数主要实现如下:

从这个函数代码大概可以分析出这个函数的主要用途是 判断当前的socket状态是否是TCP_TIME_WAIT的状态,如果是的话,就需要通过twsk_unique获得一个端口:

int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
{
        const struct inet_timewait_sock *tw = inet_twsk(sktw);
        const struct tcp_timewait_sock *tcptw = tcp_twsk(sktw);
        struct tcp_sock *tp = tcp_sk(sk);
        int reuse = sock_net(sk)->ipv4.sysctl_tcp_tw_reuse;

        if (reuse == 2) {
                /* Still does not detect *everything* that goes through
                 * lo, since we require a loopback src or dst address
                 * or direct binding to 'lo' interface.
                 */
                bool loopback = false;
                if (tw->tw_bound_dev_if == LOOPBACK_IFINDEX)
                        loopback = true;
#if IS_ENABLED(CONFIG_IPV6)
                if (tw->tw_family == AF_INET6) {
                        if (ipv6_addr_loopback(&tw->tw_v6_daddr) ||
                            ipv6_addr_v4mapped_loopback(&tw->tw_v6_daddr) ||
                            ipv6_addr_loopback(&tw->tw_v6_rcv_saddr) ||
                            ipv6_addr_v4mapped_loopback(&tw->tw_v6_rcv_saddr))
                                loopback = true;
                } else
#endif

twsk_unique接口中,会根据tcp_tw_reuse配置来判断如何分配端口。

如果长时间找不到可以复用的端口,那么lock的时间就会变得很长,导致了锁冲突的产生。

但是很神奇的是,查看系统tcp_tw_reuse的配置,已经明确是打开了复用:

image

tcp_tw_reuse分析

既然tcp_tw_reuse配置已经打开,那为什么从热点上看,还有大量的连接在做hash_connect呢?

那么是否是有可能在这样大流量下的短链接本来就需要足够的端口来使用,资源已经严重不足了?

查看一下端口的使用情况以及限制:

不知道什么原因,对于系统对本地端口数量进行了限制,修改这个端口限制从40000-65535 到 0-65535后,性能提升了 100%

但是发现尽管性能提升了,但是客户端还是在大量的hash_connect抢锁, 所以似乎还有其它的问题导致了端口没有完全复用起来。

使用netstat | grep TIME_WAIT确定一下数量:

发现基本上已经达到极限了, 主要还是由于当前的吞吐量太高 ,已经端口复用已经无法承载了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

棋子闲敲

如果对您有用,可以请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值