内容简介:国庆之后第一天,同事在 uWSGI 的日志发现这样的东西:真有意思,看日志的表面意思是 socket 的队列被占满了。介绍一下我们的业务场景吧,这个 uWSGI 服务负责处理的 HTTP 请求大多数一个前端的应用发过来的,请求耗时会很长,最长可能到 2 分钟,最短 ms 级别。处理请求的耗时不稳定,请求的频率也不稳定,比如可能突然发过来很多耗时长的请求。
国庆之后第一天,同事在 uWSGI 的日志发现这样的东西:
Mon Oct 1 07:23:00 2018 - *** uWSGI listen queue of socket "127.0.0.1:3031" (fd: 4) full !!! (101/100) *** Mon Oct 1 07:23:01 2018 - *** uWSGI listen queue of socket "127.0.0.1:3031" (fd: 4) full !!! (101/100) *** Mon Oct 1 07:23:02 2018 - *** uWSGI listen queue of socket "127.0.0.1:3031" (fd: 4) full !!! (101/100) *** Mon Oct 1 07:23:03 2018 - *** uWSGI listen queue of socket "127.0.0.1:3031" (fd: 4) full !!! (101/100) *** Mon Oct 1 07:23:04 2018 - *** uWSGI listen queue of socket "127.0.0.1:3031" (fd: 4) full !!! (101/100) *** Mon Oct 1 07:23:05 2018 - *** uWSGI listen queue of socket "127.0.0.1:3031" (fd: 4) full !!! (101/100) *** Mon Oct 1 07:23:06 2018 - *** uWSGI listen queue of socket "127.0.0.1:3031" (fd: 4) full !!! (101/100) *** Mon Oct 1 07:23:07 2018 - *** uWSGI listen queue of socket "127.0.0.1:3031" (fd: 4) full !!! (101/100) *** Mon Oct 1 07:23:08 2018 - *** uWSGI listen queue of socket "127.0.0.1:3031" (fd: 4) full !!! (101/100) ***
真有意思,看日志的表面意思是 socket 的队列被占满了。
介绍一下我们的业务场景吧,这个 uWSGI 服务负责处理的 HTTP 请求大多数一个前端的应用发过来的,请求耗时会很长,最长可能到 2 分钟,最短 ms 级别。处理请求的耗时不稳定,请求的频率也不稳定,比如可能突然发过来很多耗时长的请求。
我们的 uWSGI 基本没有配置,大多都是默认的参数,所以出现这种日志几乎是必然的。在网上搜索了一下,看到几篇 CSDN “互相参考” 风格的解决方案:加大 socket queue 的 size。主要操作分成两步:
- 加大内核的 socket queue
- 加大 uWSGI 的 queue
uWSGI 有一个 stat server ,因为我们使用的默认的参数,查看 uWSGI 的 stats 可以看到 socket 的队列最大为 100:
sockets: [
{
name: "127.0.0.1:3031",
proto: "uwsgi",
queue: 0,
max_queue: 100,
shared: 0,
can_offload: 0
}
],
开始修改,首先使用 sysctl 加大 kernel 的 socket queue. 执行 sudo echo "net.core.somaxconn = 1024" >> /etc/sysctl.conf; sysctl -p 。然后在 uWSGI 启动参数添加 listen = 2014 。
要注意的是,如果只修改了 uWSGI 的 listen 参数但是不修改系统参数,将会碰到下面这个错误。
修改之后可以重新看 stats 发现确实修改成了 1024:
sockets: [
{
name: "127.0.0.1:3031",
proto: "uwsgi",
queue: 0,
max_queue: 1024,
shared: 0,
can_offload: 0
}
],
看起来大功告成了,但是突然,我眉头一皱,发现事情并没有这么简单。如果 uWSGI 并发能力不够,那么加大队列并没有什么意义啊,早晚是会满的,无论改成多大,占满队列只是时间问题。所以同样的 warning 不加思索的照抄网上的方法是不可取的,要思考根本原因。根本原因就是有些请求处理时间太长了,而且都是 IO 耗时,这个时候最合理的方案是加大线程数量,增加并发能力。
uWSGI 默认是单进程单线程启动的,并发能力当然低了。一般来说进程数与 CPU 数相等。但是我们这个应用处理请求是高 IO 的,所以我每个进程又开了 32 个线程。在 uWSGI 中添加的配置如下:
processes = 8 threads = 32
推荐一个 debug 的工具,简直是神器: uwsgitop 。uWSGI 自身提供一个 stats 服务器,可以是 socket 的,也可以是 http 的。这个 工具 可以自动帮你刷新 uWSGI 的实时状态,像 top 那样展示出来。关键是代码竟然只有 300 行左右,惊为天人。
uwsgitop 显示效果
以上所述就是小编给大家介绍的《uWSGI socket 队列被占满的问题》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- rabbitmq实现延时队列(死信队列)
- 消息队列(三)常见消息队列介绍
- 消息队列探秘 – RabbitMQ 消息队列介绍
- 消息队列和任务队列有什么区别?
- 数据结构之——队列与循环队列
- Redis应用-异步消息队列与延时队列
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Spring in Action
Craig Walls / Manning Publications / 2011-6-29 / USD 49.99
Spring in Action, Third Edition has been completely revised to reflect the latest features, tools, practices Spring offers to java developers. It begins by introducing the core concepts of Spring and......一起来看看 《Spring in Action》 这本书的介绍吧!