uWSGI socket 队列被占满的问题

栏目: Python · 发布时间: 6年前

内容简介:国庆之后第一天,同事在 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。主要操作分成两步:

  1. 加大内核的 socket queue
  2. 加大 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 参数但是不修改系统参数,将会碰到下面这个错误。

uWSGI socket 队列被占满的问题

修改之后可以重新看 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 行左右,惊为天人。

uWSGI socket 队列被占满的问题

uwsgitop 显示效果


以上所述就是小编给大家介绍的《uWSGI socket 队列被占满的问题》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Computational Advertising

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》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

SHA 加密
SHA 加密

SHA 加密工具