【问题标题】:How to setup flask+uWSGI app to timeout long requests如何设置flask+uWSGI应用程序超时长请求
【发布时间】:2021-05-20 17:27:21
【问题描述】:

我有一个客户端和服务器设置(客户端是一个产品,无法更改,服务器是我们编写的代码,Python + Flask + uWSGI),客户端以 10 秒的超时时间快速发送 HTTP 请求。达到超时后,客户端再执行 3 次重试,同样的 10 秒超时,但有一些指数回退等待。

尽管每个单独的任务处理得相当快,但由于发送的请求量很大,任务在 uWSGI 队列中等待超过 10 秒,它们在客户端超时。问题是,即使是那些超时的任务最终也会被服务器处理,当您包括客户端重试时,一个任务最多可以处理 4 次(1 个原始请求 + 3 次重试)。

有没有办法设置我的 uWSGI 服务器,使其超时所有未在 10 秒内处理的传入请求?

我尝试了 uWSGI 的 harakiri 选项,但它会杀死整个进程,并且只有当它工作超过超时时才会终止。我还在 python 中尝试了 harakiri uWSGI 装饰器。 我尝试了 uWSGI 文档中的所有其他超时选项,但没有任何效果。

您可以使用以下代码复制此问题。

client.py

import requests
import threading

def foo():
    while True:
        try:
            resp = requests.get("http://localhost:9090/", timeout=5)
            print("I made it!", resp.text)
        except Exception as e:
            print("DIDN'T make it.. error:", e)

threads = []
for i in range(5):
    t = threading.Thread(target=foo)
    t.daemon = True
    t.start()
    threads.append(t)

for t in threads:
    t.join()

server.py

import flask as fl
import time
import random

app = fl.Flask(__name__)

@app.route('/')
def index():
    t = random.randrange(1, 4)
    print("working for", str(t), "seconds...", end="")
    time.sleep(t)
    ident = random.randrange(1, 1000000)
    print("DONE WORKING, RETURNING RESULT!", "ID:", ident)
    return "I slept for " + str(t) + " seconds! ID: " + str(ident)

uwsgi.ini 配置文件

[uwsgi]
http = :9090
wsgi-file = server.py
callable = app

master = true
processes = 2
strict = true
disable-logging = true

harakiri = 5
http-timeout = 4

服务器的输出如下所示:

working for  1  seconds...DONE WORKING, RETURNING RESULT!!! ID: 33021
working for  1  seconds...DONE WORKING, RETURNING RESULT!!! ID: 240084
working for  1  seconds...DONE WORKING, RETURNING RESULT!!! ID: 107112
working for  2  seconds...DONE WORKING, RETURNING RESULT!!! ID: 259223
working for  1  seconds...DONE WORKING, RETURNING RESULT!!! ID: 699282
working for  3  seconds...DONE WORKING, RETURNING RESULT!!! ID: 146855
working for  1  seconds...DONE WORKING, RETURNING RESULT!!! ID: 292973
working for  1  seconds...DONE WORKING, RETURNING RESULT!!! ID: 299534

来自客户端的输出抛出断开连接的错误,来自 http-timeout 参数,但服务器仍在处理请求:

I made it! I slept for 1 seconds! ID: 33021
I made it! I slept for 1 seconds! ID: 240084
I made it! I slept for 1 seconds! ID: 107112
I made it! I slept for 2 seconds! ID: 259223
DIDN'T make it.. error: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response',))
I made it! I slept for 1 seconds! ID: 699282
I made it! I slept for 1 seconds! ID: 292973
I made it! I slept for 1 seconds! ID: 299534
I made it! I slept for 1 seconds! ID: 249919
DIDN'T make it.. error: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response',))
I made it! I slept for 2 seconds! ID: 608657
DIDN'T make it.. error: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response',))

谢谢!

【问题讨论】:

    标签: python flask uwsgi


    【解决方案1】:

    uWSGI 方面的文档不多,但是,是否会检查连接(来自客户端的请求)是否仍然“打开”工作?

    https://uwsgi-docs.readthedocs.io/en/latest/PythonModule.html#uwsgi.is_connected

    类似:

    if uwsgi.is_connected(uwsgi.connection_fd())
        <process request>
    

    【讨论】:

    • 不幸的是,这不起作用。我什至尝试将服务器“处理时间”增加到 8 秒,所以来自客户端的每个请求都会超时但没有运气
    猜你喜欢
    • 2023-03-09
    • 2019-07-13
    • 2018-08-28
    • 2013-10-06
    • 1970-01-01
    • 2013-03-10
    • 1970-01-01
    • 2013-04-15
    • 2016-02-20
    相关资源
    最近更新 更多