首页 > 解决方案 > 烧瓶/gunicorn 服务在物理机上运行良好,但在 docker 中连接松散,即使设置了超时

问题描述

我有一个用 gunicorn 运行的connexion(基于 Flask 的框架)编写的 REST 服务。该服务对一个数据库执行繁重的 SQL 查询并将结果转储到另一个数据库中。SQL 查询在单独的线程中完成。当我直接在终端上运行我的 gunicorn 命令时,该服务会在 10 分钟后以 200 状态码很好地响应。这是我正在使用的 gunicorn 命令:

gunicorn "src.group.application.my_service.api.app:create_app()" -b 0.0.0.0:8080 --timeout 900 --workers 1 --log-level debug

当我在 docker 中(在 entrypoint.sh 文件中)使用相同的命令时,服务开始按应有的方式执行。但 1 分钟后,端点返回:

TypeError: The network connection was lost.

日志消息说:

[WARNING] Worker with pid 9 was terminated due to signal 9
my_service_1  | [2021-06-02 11:51:53 +0000] [194] [INFO] Booting worker with pid: 194

并重新启动服务。

即使我将--timeout标志设置为较大的值,也会发生这种情况。似乎没有考虑我设置为此标志的值,我不知道为什么。

我也尝试设置--graceful-timeout标志,但没有成功。我也尝试过使用异步工作者,比如 gthread。我仍然得到相同的行为。

我重新运行 Gunicorn 命令并将其--log-level设置为调试,并且找不到 docker 内部和外部的 gunicorn 配置之间的差异。这是两种情况下的 gunicorn 配置:

docker里面的Gunicorn配置

config: ./gunicorn.conf.py
wsgi_app: None
bind: ['0.0.0.0:8080']
backlog: 2048
workers: 1
worker_class: sync
threads: 1
worker_connections: 1000
max_requests: 0
max_requests_jitter: 0
timeout: 900
graceful_timeout: 30
keepalive: 2
limit_request_line: 4094
limit_request_fields: 100
limit_request_field_size: 8190
reload: False
reload_engine: auto
reload_extra_files: []
spew: False
check_config: False
print_config: False
preload_app: False
sendfile: None
reuse_port: False
chdir: /app
daemon: False
raw_env: []
pidfile: None
worker_tmp_dir: None
user: 0
group: 0
umask: 0
initgroups: False
tmp_upload_dir: None
secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
forwarded_allow_ips: ['127.0.0.1']
accesslog: None
disable_redirect_access_to_syslog: False
access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
errorlog: -
loglevel: debug
capture_output: False
logger_class: gunicorn.glogging.Logger
logconfig: None
logconfig_dict: {}
syslog_addr: udp://localhost:514
syslog: False
syslog_prefix: None
syslog_facility: user
enable_stdio_inheritance: False
statsd_host: None
dogstatsd_tags:
statsd_prefix:
proc_name: None
default_proc_name: group.application.my_service.api.app:create_app()
pythonpath: None
paste: None
on_starting: <function OnStarting.on_starting at 0x7fa9a084d940>
on_reload: <function OnReload.on_reload at 0x7fa9a084da60>
when_ready: <function WhenReady.when_ready at 0x7fa9a084db80>
pre_fork: <function Prefork.pre_fork at 0x7fa9a084dca0>
post_fork: <function Postfork.post_fork at 0x7fa9a084ddc0>
post_worker_init: <function PostWorkerInit.post_worker_init at 0x7fa9a084dee0>
worker_int: <function WorkerInt.worker_int at 0x7fa9a0862040>
worker_abort: <function WorkerAbort.worker_abort at 0x7fa9a0862160>
pre_exec: <function PreExec.pre_exec at 0x7fa9a0862280>
pre_request: <function PreRequest.pre_request at 0x7fa9a08623a0>
post_request: <function PostRequest.post_request at 0x7fa9a0862430>
child_exit: <function ChildExit.child_exit at 0x7fa9a0862550>
worker_exit: <function WorkerExit.worker_exit at 0x7fa9a0862670>
nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x7fa9a0862790>
on_exit: <function OnExit.on_exit at 0x7fa9a08628b0>
proxy_protocol: False
proxy_allow_ips: ['127.0.0.1']
keyfile: None
certfile: None
ssl_version: 2
cert_reqs: 0
ca_certs: None
suppress_ragged_eofs: True
do_handshake_on_connect: False
ciphers: None
raw_paste_global_conf: []
strip_header_spaces: False

docker里面的Gunicorn配置

config: ./gunicorn.conf.py
wsgi_app: None
bind: ['0.0.0.0:8080']
backlog: 2048
workers: 1
worker_class: sync
threads: 1
worker_connections: 1000
max_requests: 0
max_requests_jitter: 0
timeout: 900
graceful_timeout: 30
keepalive: 2
limit_request_line: 4094
limit_request_fields: 100
limit_request_field_size: 8190
reload: False
reload_engine: auto
reload_extra_files: []
spew: False
check_config: False
print_config: False
preload_app: False
sendfile: None
reuse_port: False
chdir: /Users/user/<code_folder>
daemon: False
raw_env: []
pidfile: None
worker_tmp_dir: None
user: 501
group: 20
umask: 0
initgroups: False
tmp_upload_dir: None
secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
forwarded_allow_ips: ['127.0.0.1']
accesslog: None
disable_redirect_access_to_syslog: False
access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
errorlog: -
loglevel: debug
capture_output: False
logger_class: gunicorn.glogging.Logger
logconfig: None
logconfig_dict: {}
syslog_addr: unix:///var/run/syslog
syslog: False
syslog_prefix: None
syslog_facility: user
enable_stdio_inheritance: False
statsd_host: None
dogstatsd_tags:
statsd_prefix:
proc_name: None
default_proc_name: src.group.application.my_service.api.app:create_app()
pythonpath: None
paste: None
on_starting: <function OnStarting.on_starting at 0x100efd1f0>
on_reload: <function OnReload.on_reload at 0x100efd310>
when_ready: <function WhenReady.when_ready at 0x100efd430>
pre_fork: <function Prefork.pre_fork at 0x100efd550>
post_fork: <function Postfork.post_fork at 0x100efd670>
post_worker_init: <function PostWorkerInit.post_worker_init at 0x100efd790>
worker_int: <function WorkerInt.worker_int at 0x100efd8b0>
worker_abort: <function WorkerAbort.worker_abort at 0x100efd9d0>
pre_exec: <function PreExec.pre_exec at 0x100efdaf0>
pre_request: <function PreRequest.pre_request at 0x100efdc10>
post_request: <function PostRequest.post_request at 0x100efdca0>
child_exit: <function ChildExit.child_exit at 0x100efddc0>
worker_exit: <function WorkerExit.worker_exit at 0x100efdee0>
nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x100f06040>
on_exit: <function OnExit.on_exit at 0x100f06160>
proxy_protocol: False
proxy_allow_ips: ['127.0.0.1']
keyfile: None
certfile: None
ssl_version: 2
cert_reqs: 0
ca_certs: None
suppress_ragged_eofs: True
do_handshake_on_connect: False
ciphers: None
raw_paste_global_conf: []
strip_header_spaces: False

信号 9 是什么意思?如何使 docker 内部的服务的行为方式与 docker 外部相同?

标签: dockerrestflaskgunicornconnexion

解决方案


推荐阅读