gunicorn uvicorn worker.py 如何尊重 limit_concurrency 设置
gunicorn uvicorn worker.py how to honor limit_concurrency setting
FastAPI 使用 gunicorn 启动 uvicorn worker,如 https://www.uvicorn.org/settings/
中所述
但是 gunicorn 不允许使用自定义设置启动 uvicorn,正如 https://github.com/encode/uvicorn/issues/343
中提到的那样
问题建议覆盖源文件中的 config_kwargs,如 https://github.com/encode/uvicorn/blob/master/uvicorn/workers.py
我们试过了,但 uvicorn 不支持源中多个 uvicorn 文件中的设置 limit_concurrency
:
https://github.com/encode/uvicorn/blob/master/uvicorn/workers.py
# fail
config_kwargs = {
"app": None,
"log_config": None,
"timeout_keep_alive": self.cfg.keepalive,
"timeout_notify": self.timeout,
"callback_notify": self.callback_notify,
"limit_max_requests": self.max_requests, "limit_concurrency": 10000,
"forwarded_allow_ips": self.cfg.forwarded_allow_ips,
}
https://github.com/encode/uvicorn/blob/master/uvicorn/main.py
# fail
kwargs = {
"app": app,
"host": host,
"port": port,
"uds": uds,
"fd": fd,
"loop": loop,
"http": http,
"ws": ws,
"lifespan": lifespan,
"env_file": env_file,
"log_config": LOGGING_CONFIG if log_config is None else log_config,
"log_level": log_level,
"access_log": access_log,
"interface": interface,
"debug": debug,
"reload": reload,
"reload_dirs": reload_dirs if reload_dirs else None,
"workers": workers,
"proxy_headers": proxy_headers,
"forwarded_allow_ips": forwarded_allow_ips,
"root_path": root_path,
"limit_concurrency": 10000,
"backlog": backlog,
"limit_max_requests": limit_max_requests,
"timeout_keep_alive": timeout_keep_alive,
"ssl_keyfile": ssl_keyfile,
"ssl_certfile": ssl_certfile,
"ssl_version": ssl_version,
"ssl_cert_reqs": ssl_cert_reqs,
"ssl_ca_certs": ssl_ca_certs,
"ssl_ciphers": ssl_ciphers,
"headers": list([header.split(":") for header in headers]),
"use_colors": use_colors,
}
如何强制 uvicorn 遵守此设置?我们仍然从 FastAPI
中收到 503 错误
--------更新------------
gunicorn 设置 --worker-connections 1000
在发出 100 个分发给许多工作人员的并行请求时仍然会导致 503。
但是,我认为这是一个更复杂的问题:我们的 API 端点会做很多繁重的工作,通常需要 5 秒才能完成。
2核2工压力测试:
- 一个。 100+ 并发请求,端点重负载 --worker-connections 1
- 乙。 100+ 并发请求,endpoint 重载 --worker-connections 1000
- C。 100+ 并发请求,端点低负载 --worker-connections 1
- D. 100+ 并发请求,端点低负载 --worker-connections 1000
两个实验 A 和 B 都产生了 503 个响应,因此假设 worker-connections 设置确实有效,太多的模拟连接似乎不会导致我们的 503 错误。
我们对这种行为感到困惑,因为我们希望 gunicorn/uvicorn 将工作排队而不抛出 503 错误。
worker-connections
The maximum number of simultaneous clients.
limit-concurrency
Maximum number of concurrent connections or tasks to allow, before issuing HTTP 503 responses.
根据此信息,两个设置变量执行相同的操作。所以
uvicorn <b>--limit-concurrency 100</b> application:demo_app
几乎与
相同
gunicorn <b>--worker-connections 100</b> -k uvicorn.workers.UvicornWorker application:demo_app
注:我没有做过实测,如有错误请指正
此外,您可以通过subclass设置limit-concurrency
(或limit_concurrency
)正在 uvicorn.workers.UvicornWorker
class
from uvicorn.workers import UvicornWorker
class CustomUvicornWorker(UvicornWorker):
CONFIG_KWARGS = {
"loop": "uvloop",
"http": "httptools",
<b>"limit_concurrency": 100</b>
}
现在将此 CustomUvicornWorker
与 gunicorn
命令一起用作,
gunicorn <b>-k path.to.custom_worker.CustomUvicornWorker</b> application:demo_app
注意: 您可以检查 CustomUvicornWorker
class 中的 self.config.limit_concurrency
以确保已正确设置值。
FastAPI 使用 gunicorn 启动 uvicorn worker,如 https://www.uvicorn.org/settings/
中所述但是 gunicorn 不允许使用自定义设置启动 uvicorn,正如 https://github.com/encode/uvicorn/issues/343
中提到的那样问题建议覆盖源文件中的 config_kwargs,如 https://github.com/encode/uvicorn/blob/master/uvicorn/workers.py
我们试过了,但 uvicorn 不支持源中多个 uvicorn 文件中的设置 limit_concurrency
:
https://github.com/encode/uvicorn/blob/master/uvicorn/workers.py
# fail
config_kwargs = {
"app": None,
"log_config": None,
"timeout_keep_alive": self.cfg.keepalive,
"timeout_notify": self.timeout,
"callback_notify": self.callback_notify,
"limit_max_requests": self.max_requests, "limit_concurrency": 10000,
"forwarded_allow_ips": self.cfg.forwarded_allow_ips,
}
https://github.com/encode/uvicorn/blob/master/uvicorn/main.py
# fail
kwargs = {
"app": app,
"host": host,
"port": port,
"uds": uds,
"fd": fd,
"loop": loop,
"http": http,
"ws": ws,
"lifespan": lifespan,
"env_file": env_file,
"log_config": LOGGING_CONFIG if log_config is None else log_config,
"log_level": log_level,
"access_log": access_log,
"interface": interface,
"debug": debug,
"reload": reload,
"reload_dirs": reload_dirs if reload_dirs else None,
"workers": workers,
"proxy_headers": proxy_headers,
"forwarded_allow_ips": forwarded_allow_ips,
"root_path": root_path,
"limit_concurrency": 10000,
"backlog": backlog,
"limit_max_requests": limit_max_requests,
"timeout_keep_alive": timeout_keep_alive,
"ssl_keyfile": ssl_keyfile,
"ssl_certfile": ssl_certfile,
"ssl_version": ssl_version,
"ssl_cert_reqs": ssl_cert_reqs,
"ssl_ca_certs": ssl_ca_certs,
"ssl_ciphers": ssl_ciphers,
"headers": list([header.split(":") for header in headers]),
"use_colors": use_colors,
}
如何强制 uvicorn 遵守此设置?我们仍然从 FastAPI
中收到 503 错误--------更新------------
gunicorn 设置 --worker-connections 1000
在发出 100 个分发给许多工作人员的并行请求时仍然会导致 503。
但是,我认为这是一个更复杂的问题:我们的 API 端点会做很多繁重的工作,通常需要 5 秒才能完成。
2核2工压力测试:
- 一个。 100+ 并发请求,端点重负载 --worker-connections 1
- 乙。 100+ 并发请求,endpoint 重载 --worker-connections 1000
- C。 100+ 并发请求,端点低负载 --worker-connections 1
- D. 100+ 并发请求,端点低负载 --worker-connections 1000
两个实验 A 和 B 都产生了 503 个响应,因此假设 worker-connections 设置确实有效,太多的模拟连接似乎不会导致我们的 503 错误。
我们对这种行为感到困惑,因为我们希望 gunicorn/uvicorn 将工作排队而不抛出 503 错误。
worker-connections
The maximum number of simultaneous clients.
limit-concurrency
Maximum number of concurrent connections or tasks to allow, before issuing HTTP 503 responses.
根据此信息,两个设置变量执行相同的操作。所以
uvicorn <b>--limit-concurrency 100</b> application:demo_app
几乎与
相同gunicorn <b>--worker-connections 100</b> -k uvicorn.workers.UvicornWorker application:demo_app
注:我没有做过实测,如有错误请指正
此外,您可以通过subclass设置limit-concurrency
(或limit_concurrency
)正在 uvicorn.workers.UvicornWorker
class
from uvicorn.workers import UvicornWorker
class CustomUvicornWorker(UvicornWorker):
CONFIG_KWARGS = {
"loop": "uvloop",
"http": "httptools",
<b>"limit_concurrency": 100</b>
}
现在将此 CustomUvicornWorker
与 gunicorn
命令一起用作,
gunicorn <b>-k path.to.custom_worker.CustomUvicornWorker</b> application:demo_app
注意: 您可以检查 CustomUvicornWorker
class 中的 self.config.limit_concurrency
以确保已正确设置值。