【发布时间】:2018-09-12 17:02:53
【问题描述】:
我们正在运行一个 Flask 应用程序来公开存储在数据库中的数据。它返回很多503 错误。我的理解是,当达到最大并发线程数时,这些是由apache生成的。
根本原因很可能是应用程序性能不佳,但在这个阶段,我们无法承受更多的开发时间,因此我正在寻找一种廉价的部署配置黑客来缓解这个问题。
数据提供者正在高速发送数据。我相信他们的程序会得到很多
503并且只需尝试/捕获那些重试直到成功。数据消费者使用该应用的频率要低得多,我希望他们不要被这些问题所困扰。
我正在考虑限制来自每个提供商的 IP 的并发访问数。他们可能会获得较低的吞吐量,但他们会像现在一样接受它,这将使普通消费者的生活更轻松。
我发现mod_limitipconn 似乎是为此量身定做的。
mod_limitipconn [...] 允许管理员限制允许来自单个 IP 地址的同时请求数。
我想确定我了解它的工作原理以及限制是如何设置的。
由于 WSGI 设置,我一直认为最多有 5 个同时连接:threads=5。但是我在 mod_wsgi 文档中阅读了Processes and Threading,我很困惑。
考虑到下面的配置,这些假设是否正确?
一次只运行一个应用程序实例。
最多可以生成 5 个并发线程。
当处理 5 个请求时,如果有第六个请求到达,客户端会收到一个
503。限制同时请求 IP x.x.x.x 的数量。将 apache 级别设置为 3 将确保该 IP 可以使用这 5 个线程中的 3 个,而将 2 个留给其他 IP。
增加 WSGI 配置中的线程数可以通过在速率限制中提供更精细的粒度来帮助在客户端之间共享连接池(您可以将 4 个提供者中的每一个限制为 3 个,并保留 5 个以上,总共 17 个) 但不会提高整体性能,即使服务器有空闲内核,因为the Python GIL prevents several threads to run at the same time。
将线程数提高到 100 等高数可能会使请求更长,但会限制
503响应。如果客户将他们自己的并发请求限制设置得不太高,甚至可能就足够了,如果他们不这样做,我可以使用mod_limitipconn之类的东西来强制执行。过多地增加线程数会使请求时间过长,以至于客户端会超时,而不是
503,这并不是更好。
当前配置如下。不知道什么重要。
apachectl -V:
Server version: Apache/2.4.25 (Debian)
Server built: 2018-06-02T08:01:13
Server's Module Magic Number: 20120211:68
Server loaded: APR 1.5.2, APR-UTIL 1.5.4
Compiled using: APR 1.5.2, APR-UTIL 1.5.4
Architecture: 64-bit
Server MPM: event
threaded: yes (fixed thread count)
forked: yes (variable process count)
/etc/apache2/apache2.conf:
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
#
KeepAlive On
#
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
#
MaxKeepAliveRequests 100
/etc/apache2/mods-available/mpm_worker.conf(但这在event 中应该不重要,对吧?):
<IfModule mpm_worker_module>
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 150
MaxConnectionsPerChild 0
</IfModule>
/etc/apache2/sites-available/my_app.conf:
WSGIDaemonProcess my_app threads=5
【问题讨论】:
-
你使用的是什么 WSGI?也许我在您的详细问题中忽略了。顺便说一句,细节真的很好。你有没有把它与 gunicorn 或类似的东西联系起来?
-
回答了我自己的问题。您正在使用内置的 apache 之一。我只将 Flask 与 gunicorn 和 Nginx 结合使用作为反向 Web 代理。我很确定您的问题出在其中。
-
不,不涉及独角兽。只有 WSGI over apache。
标签: python multithreading apache flask mod-wsgi