Python 有没有办法通过Gunicorn限制来自一个IP的并发请求数?

Python 有没有办法通过Gunicorn限制来自一个IP的并发请求数?,python,nginx,flask,gunicorn,Python,Nginx,Flask,Gunicorn,基本上,我运行的是一个Flask web服务器,它处理一组数据并将其发送回用户。我们预计60岁左右的用户不会很多,但我已经注意到并发性可能存在的问题。现在,如果我打开一个选项卡并发送一个请求来处理一些数据,大约需要30秒,对于我们的应用程序来说,这是可以的 如果我打开另一个选项卡,同时发送相同的请求,unicorn将同时执行,如果我们有两个单独的用户发出两个单独的请求,这将非常好。但是,如果我让一个用户打开4个或8个选项卡并发送相同的请求,会发生什么?它为其他所有人备份服务器,我有没有办法告诉G

基本上,我运行的是一个Flask web服务器,它处理一组数据并将其发送回用户。我们预计60岁左右的用户不会很多,但我已经注意到并发性可能存在的问题。现在,如果我打开一个选项卡并发送一个请求来处理一些数据,大约需要30秒,对于我们的应用程序来说,这是可以的


如果我打开另一个选项卡,同时发送相同的请求,unicorn将同时执行,如果我们有两个单独的用户发出两个单独的请求,这将非常好。但是,如果我让一个用户打开4个或8个选项卡并发送相同的请求,会发生什么?它为其他所有人备份服务器,我有没有办法告诉Gunicorn一次只接受来自同一IP的一个请求?

这可能不是最好的烧瓶级别处理方法。但是如果你必须在那里做,那么结果是其他人已经设计了一个烧瓶插件来做这件事:

如果一个请求至少需要30秒,那么请按地址限制每30秒请求一次。这将解决不耐烦的用户沉迷于点击的问题,而不是等待一个很长的过程来完成


这并不完全是您所要求的,因为这意味着较长/较短的请求可能重叠并允许同时进行多个请求,这并不完全排除您描述的多个选项卡等行为。也就是说,如果您能够告诉用户等待30秒,听起来你是在为用户体验设定期望值。如果您可以构建一个异步服务器交互,那么一条好的等待/进度消息可能也会有所帮助。

对于@jon的回答,更好的解决方案是限制web服务器而不是应用服务器的访问。一个好的方法总是将应用程序的不同层执行的职责分开。理想情况下,应用服务器flask不应具有任何限制配置,也不应与来自何处的请求有关。web服务器(在本例中为nginx)的职责是根据某些参数将请求路由到正确的客户端。应在该层进行限制

现在,说到限制,您可以通过在nginx的http块配置中使用limit_req_zone指令来实现

http {
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

...

server {

    ...

    location / {
        limit_req zone=one burst=5;
        proxy_pass ...
    }
其中,binary_remote_addris是客户端的IP,平均每秒不超过1个请求,突发请求不超过5个

专业提示:由于来自同一IP的后续请求将被保存在队列中,因此nginx很有可能超时。因此,建议有一个更好的代理读取超时,如果报告需要更长的时间,则还可以调整gunicorn的超时

文件


nginx关于利率限制的博客文章可以找到

,非常有意义,谢谢!这让我绕过了很多其他问题。是的,我同意这是一个更好的答案,基于web和应用服务器之间的关注点分离