内容简介:国庆之后第一天,同事在 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应用-异步消息队列与延时队列
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Computational Advertising
by Kushal Dave、Vasudeva Varma / Now Publishers Inc / 2014
Computational Advertising (CA), popularly known as online advertising or Web advertising, refers to finding the most relevant ads matching a particular context on the Web. The context depends on the t......一起来看看 《Computational Advertising》 这本书的介绍吧!