<p>gunicorn 20.0.0:--paste 未检测 [server:main] 下的参数</p>

创建于 2019-11-12  ·  31评论  ·  资料来源: benoitc/gunicorn

你好 gunicorn 维护者,

环境:

  • python 3.6.1
  • pyramid==1.9.2

2019 年 9 月 12 日,根据 Stack Overflow 的建议,我重构了内部pyramid服务器的部署方式,将waitress替换为gunicorn

https://stackoverflow.com/a/26872261/10491481

在进行内部 PR 时, gunicorn的最新版本是 19.9.0。

今天我被要求再次审查实施,特别是测试我们的开发和生产CentOS 6.5服务器上的更改。 我决定用我们的代码库中的一个新的git clone来做这件事。

在我做 PR 的时候,我没有在setup.py中指定gunicorn的版本,因此当我今天运行pip install时,它(意外)下载并安装gunicorn==20.0.0

不清楚为什么我在 $ [server:main] development.ini #$ 中的设置在启动时没有反映。

需要明确的是,在我们的development.ini中使用以下设置:

[server:main]
use = egg:gunicorn#main
host = 0.0.0.0
port = 9090
workers = 1
worker_class = gevent
certfile=/etc/ssl/certs/current/webserver.cer
keyfile=/etc/ssl/certs/current/private.key.u
ca_certs=/etc/ssl/certs/current/intermediate.cert

gunicorn 19.9.0

$ gunicorn --version
gunicorn (version 19.9.0)
$ gunicorn --paste development.ini 
[2019-11-12 12:42:59 -0800] [16733] [INFO] Starting gunicorn 19.9.0
[2019-11-12 12:42:59 -0800] [16733] [INFO] Listening at: https://0.0.0.0:9090 (16733)
[2019-11-12 12:42:59 -0800] [16733] [INFO] Using worker: gevent
[2019-11-12 12:42:59 -0800] [16744] [INFO] Booting worker with pid: 16744

gunicorn 20.0.0

$ gunicorn --version
gunicorn (version 20.0.0)
$ gunicorn --paste development.ini 
[2019-11-12 12:45:28 -0800] [17295] [INFO] Starting gunicorn 20.0.0
[2019-11-12 12:45:28 -0800] [17295] [INFO] Listening at: http://127.0.0.1:8000 (17295)
[2019-11-12 12:45:28 -0800] [17295] [INFO] Using worker: sync
[2019-11-12 12:45:28 -0800] [17300] [INFO] Booting worker with pid: 17300

两个输出之间的注意事项:

  • 不再使用 SSL 部署(注意gunicorn 20.0.0的输出是http
  • host参数不再正确(使用默认127.0.0.1而不是0.0.0.0
  • port参数不再正确(使用默认8000而不是9090

我查看了gunicorn 20.0.0的更改日志:

http://docs.gunicorn.org/en/stable/news.html

但是似乎没有提到对--paste参数的任何故意破坏性更改。

对于它的价值,如果我在命令行中使用gunicorn 20.0.0传递我可以传递的参数,服务器将按预期启动:

$ gunicorn \
  --paste development.ini \
  -b 0.0.0.0:9090
  --workers 1 \
  --certfile /etc/ssl/certs/current/webserver.cer \
  --keyfile /etc/ssl/certs/current/private.key.u
[2019-11-12 12:54:08 -0800] [18979] [INFO] Starting gunicorn 20.0.0
[2019-11-12 12:54:08 -0800] [18979] [INFO] Listening at: https://0.0.0.0:9090 (18979)
[2019-11-12 12:54:08 -0800] [18979] [INFO] Using worker: sync
[2019-11-12 12:54:08 -0800] [18985] [INFO] Booting worker with pid: 18985

任何有助于理解此问题的帮助将不胜感激。

如果我可以提供有关我的环境的更多详细信息以使其可重现,请告诉我。

谢谢,
科里

最有用的评论

我将重新打开问题并自行分配。 当我更新变更日志以使其在此处更清晰时,我将关闭它。

再次,我很抱歉最初没有在变更日志中更清楚地指出它。

所有31条评论

我很抱歉。 更改日志条目仅显示“简化粘贴部署文档”,我应该在这里帮助准备更好的新闻条目。

公关在这里: https ://github.com/benoitc/gunicorn/pull/1957

以前,我们已经弃用use = egg:gunicorn#main ,但它不再被弃用。 此更改旨在阐明 Gunicorn 在 Paste Deploy 兼容环境中的作用。

将 Gunicorn 与这种风格的.ini文件一起使用有两种选择。

第一个选项是使用gunicorn CLI。 执行此操作时,您必须使用 Gunicorn 自己的 CLI 标志或 Gunicorn 自己的配置模块(默认gunicorn.conf.py )来配置服务器参数。 Gunicorn 绑定的套接字,管理重新加载,写入 PID 文件等。 Gunicorn 可以使用 $#$ .ini $#$ 中的app部分来配置应用程序可调用。

第二种选择是使用粘贴脚本运行器,例如pserve 。 在这种情况下,此脚本运行器管理重新加载、写入 PID 文件等。 大多数其他选项应该仍然有效,但是要使用.ini文件的server块,您需要调用与粘贴兼容的脚本运行器。 Gunicorn 不再是这样的脚本运行者。

让我知道是否可以增加更多清晰度。

在您的情况下,您应该能够像以前一样继续,但使用pserve而不是gunicorn来启动您的应用程序。 然后,Gunicorn 的所有服务器配置都可以在您的server块中,就像您似乎已经完成的那样。

先前的行为可能会造成混淆,因为它允许在命令行上指定与文件冲突的选项。 我们还要求添加在.ini文件中指定用于插值的配置变量的功能,并指定不同的server块(除了不同的app块)。 因此,决定弃用 Gunicorn 作为 Paste _server_ 运行程序,而不是尝试添加对所有这些功能的支持。 Gunicorn CLI 现在支持读取 Paste Deploy .ini文件来构建应用程序,但使用server块留给该生态系统中的专用工具。

在您的情况下,您应该能够像以前一样继续,但使用pserve而不是gunicorn来启动您的应用程序。

感谢@tilgovi 的快速回复!

根据您的建议:

$ pserve development.ini
# ...
Starting server in PID 40148.
[2019-11-12 14:26:30 -0800] [40148] [INFO] Starting gunicorn 20.0.0
[2019-11-12 14:26:30 -0800] [40148] [INFO] Listening at: https://0.0.0.0:9090 (40148)
[2019-11-12 14:26:30 -0800] [40148] [INFO] Using worker: gevent
[2019-11-12 14:26:30 -0800] [40263] [INFO] Booting worker with pid: 40263

太好了,因为我打开的部分内部 PR 涉及必须将命令pserve更改为gunicorn ,我有点担心,因为我不是我们的原始开发人员内部 API 服务器。

这解决了我的问题,请随时关闭此问题 =)

谢谢,
科里

最后一点,然后我想我已经添加了我能回忆起的所有细节。 即使 $# gunicorn --paste production.ini server块指定了egg:gunicorn#main _!

由于 Gunicorn 主要是一个服务器和进程管理器,因此将 Gunicorn 用作调用任意粘贴兼容服务器的通用 CLI 是没有意义的。 相反,Gunicorn 是一个支持 Paste Deploy 应用程序的服务器,它是一个与 Paste 兼容的服务器。 不过,它_不是_ 一个粘贴脚本运行器 CLI!

我为此在 Pyramid 食谱上打开了一个问题: https ://github.com/Pylons/pyramid_cookbook/issues/222

我以为我已经在 Gunicorn 中彻底记录了这一点,但一开始我找不到参考资料。 它在这里: http ://docs.gunicorn.org/en/stable/run.html#paste -deployment

@tilgovi 提醒一下,这对我的团队来说也是一个重大变化。 也许值得转移到变更日志的重大变更部分?

我将重新打开问题并自行分配。 当我更新变更日志以使其在此处更清晰时,我将关闭它。

再次,我很抱歉最初没有在变更日志中更清楚地指出它。

@tilgovi颠簸

请让我知道这是否应该作为一个单独的问题打开。

这可能是我们代码库的一个孤立问题,但经过更多测试后,我的团队注意到对于我们的 API 服务器, gunicorn 20.0.0破坏了函数pyramid_ldap3.get_ldap_connector

gunicorn 20.0.0

启动时:

$ pip list | grep gunicorn
gunicorn             20.0.0
$ pserve bioapps/development.ini
[2019-11-20 15:55:30 -0800] [9902] [INFO] Starting gunicorn 20.0.0
[2019-11-20 15:55:30 -0800] [9902] [INFO] Listening at: https://0.0.0.0:10999 (9902)
[2019-11-20 15:55:30 -0800] [9902] [INFO] Using worker: gevent
[2019-11-20 15:55:30 -0800] [10034] [INFO] Booting worker with pid: 10034
/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/gunicorn/workers/ggevent.py:53: MonkeyPatchWarning: Monkey-patching ssl after ssl has already been imported may lead to errors, including RecursionError on Python 3.6. It may also silently lead to incorrect behaviour on Python 3.7. Please monkey-patch earlier. See https://github.com/gevent/gevent/issues/1016. Modules that had direct imports (NOT patched): ['urllib3.util.ssl_ (/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/urllib3/util/ssl_.py)', 'urllib3.util (/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/urllib3/util/__init__.py)'].
  monkey.patch_all()

尝试验证后:

[2019-11-20 15:57:54,189] INFO  [access:342][DummyThread-1] 10.9.202.54 - - "POST https://bioappsdev02.bcgsc.ca:10999/session HTTP/1.1" {'username': 'colim', 'password': ''}
[2019-11-20 15:57:57,276] ERROR [exc_logger:114][DummyThread-1] 'https://bioappsdev02.bcgsc.ca:10999/session'
Traceback (most recent call last):
  File "/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/pyramid/tweens.py", line 39, in excview_tween
    response = handler(request)
  File "/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/pyramid/router.py", line 156, in handle_request
    view_name
  File "/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/pyramid/view.py", line 642, in _call_view
    response = view_callable(context, request)
  File "/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/pyramid/config/views.py", line 181, in __call__
    return view(context, request)
  File "/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/pyramid/viewderivers.py", line 390, in attr_view
    return view(context, request)
  File "/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/pyramid/viewderivers.py", line 368, in predicate_wrapper
    return view(context, request)
  File "/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/pyramid/viewderivers.py", line 439, in rendered_view
    result = view(context, request)
  File "/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/pyramid/viewderivers.py", line 148, in _requestonly_view
    response = view(request)
  File "/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/cornice/service.py", line 493, in wrapper
    response = view_(request)
  File "/home/colim/Projects/bioapps/bioapps.api.ssl/bioapps/api/endpoints/session.py", line 139, in session_post
    username, request.validated['password'], request,
  File "/home/colim/Projects/bioapps/bioapps.api.ssl/bioapps/api/endpoints/session.py", line 27, in get_ldap_groups
    auth = connector.authenticate(username, password)
  File "/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/pyramid_ldap3/__init__.py", line 208, in authenticate
    password=escape_for_search(password))
  File "/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/pyramid_ldap3/__init__.py", line 82, in execute
    with manager.connection() as conn:
  File "/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/pyramid_ldap3/__init__.py", line 165, in connection
    auto_bind=True, lazy=False, read_only=True)
  File "/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/ldap3/core/connection.py", line 326, in __init__
    self.do_auto_bind()
  File "/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/ldap3/core/connection.py", line 343, in do_auto_bind
    self.bind(read_server_info=True)
  File "/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/ldap3/core/connection.py", line 585, in bind
    _, result = self.get_response(response)
  File "/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/ldap3/strategy/base.py", line 370, in get_response
    raise LDAPResponseTimeoutError('no response from server')
ldap3.core.exceptions.LDAPResponseTimeoutError: no response from server
[2019-11-20 15:57:57,298] INFO  [access:362][DummyThread-1] 10.9.202.54 - - "POST https://bioappsdev02.bcgsc.ca:10999/session HTTP/1.1" 500 206

gunicorn 19.9.0

启动时:

$ pip install gunicorn==19.9.0
Collecting gunicorn==19.9.0
  Using cached https://files.pythonhosted.org/packages/8c/da/b8dd8deb741bff556db53902d4706774c8e1e67265f69528c14c003644e6/gunicorn-19.9.0-py2.py3-none-any.whl
Installing collected packages: gunicorn
  Found existing installation: gunicorn 20.0.0
    Uninstalling gunicorn-20.0.0:
      Successfully uninstalled gunicorn-20.0.0
Successfully installed gunicorn-19.9.0
$ pip list | grep unicorn
gunicorn             19.9.0
$ gunicorn --paste bioapps/development.ini
[2019-11-20 16:03:45 -0800] [12015] [INFO] Starting gunicorn 19.9.0
[2019-11-20 16:03:45 -0800] [12015] [INFO] Listening at: https://0.0.0.0:10999 (12015)
[2019-11-20 16:03:45 -0800] [12015] [INFO] Using worker: gevent
[2019-11-20 16:03:45 -0800] [12018] [INFO] Booting worker with pid: 12018

尝试验证后:

[2019-11-20 16:04:39,292] INFO  [access:342][DummyThread-1] 10.9.202.54 - - "POST https://bioappsdev02.bcgsc.ca:10999/session HTTP/1.1" {'username': 'colim', 'password': ''}
[2019-11-20 16:04:39,527] INFO  [access:362][DummyThread-1] 10.9.202.54 - - "POST https://bioappsdev02.bcgsc.ca:10999/session HTTP/1.1" 200 639

gunicorn 20.0.0gunicorn 19.9.0 development.ini进行任何更改。

有趣的是,如果我们使用以下命令启动服务器,我们可以使用gunicorn 20.0.0停止错误:

$ pip list | grep unicorn
gunicorn             20.0.0
$ gunicorn --paste bioapps/development.ini -b 0.0.0.0:8999 --workers 1 --certfile /etc/ssl/certs/current/webserver.cer  --keyfile /etc/ssl/certs/current/private.key.u
[2019-11-20 16:14:27 -0800] [14783] [INFO] Starting gunicorn 20.0.0
[2019-11-20 16:14:27 -0800] [14783] [INFO] Listening at: https://0.0.0.0:8999 (14783)
[2019-11-20 16:14:27 -0800] [14783] [INFO] Using worker: sync
[2019-11-20 16:14:27 -0800] [14798] [INFO] Booting worker with pid: 14798
[2019-11-20 16:16:39,550] INFO  [access:342][MainThread] 10.9.202.54 - - "POST https://bioappsdev02.bcgsc.ca:8999/session HTTP/1.1" {'username': 'colim', 'password': ''}
[2019-11-20 16:16:39,768] INFO  [access:362][MainThread] 10.9.202.54 - - "POST https://bioappsdev02.bcgsc.ca:8999/session HTTP/1.1" 200 639

我不确定它是否相关,但使用gunicorn 20.0.0pserve启动服务器是我们唯一看到此警告的时间:

/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/gunicorn/workers/ggevent.py:53: MonkeyPatchWarning: Monkey-patching ssl after ssl has already been imported may lead to errors, including RecursionError on Python 3.6. It may also silently lead to incorrect behaviour on Python 3.7. Please monkey-patch earlier. See https://github.com/gevent/gevent/issues/1016. Modules that had direct imports (NOT patched): ['urllib3.util.ssl_ (/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/urllib3/util/ssl_.py)', 'urllib3.util (/home/colim/Projects/bioapps/bioapps.api.ssl/centos7venv/lib/python3.6/site-packages/urllib3/util/__init__.py)'].
  monkey.patch_all()

@tilgovi您会在更改日志中更改什么?

@benoitc我想呼吁在 Gunicorn CLI 中删除对 Paste Deploy 服务器定义的支持。 我今天可以做到这一点。

如果我追溯修改更改日志以使其更清晰(在 20.0 版本中进行重大更改部分),是否可以?

@CorreyL有趣! 您绝对可以使用命令行上指定的选项运行gunicorn 。 我认为这是运行gunicorn的首选和最安全的方式。 与pserve的集成很方便,但很高兴知道它会在这里引起问题。 我希望我没有错误地取消弃用它。

如果我追溯修改更改日志以使其更清晰(在 20.0 版本中进行重大更改部分),是否可以?

@tilgovi是的

@tilgovi您今天可以添加此更改吗? 拥有 20.0.1 会很酷 :)

在 c25563f 中添加了一行注释。 自更改发生以来,文档已经更新。 希望任何看到该注释的人都能找到文档和这些问题。 😅

@tilgovi谢谢

只是想添加另一个确认受到此意外影响。 就我而言,这并不是很重要,但我很困惑为什么 gunicorn 自升级以来停止在 dev 中自动重新加载以及其他一些小的行为变化。 我今天花了一些时间试图弄清楚,并意识到我的--paste INI 文件中的设置不再有效,这帮助我找到了解决这个问题的方法。

我不知道这是否可行,但是如果 gunicorn 检测到您仍在尝试通过 Paster 文件设置服务器参数,是否可以让 gunicorn 输出警告?

我为中断道歉,@Deimos。 我会审查 PR,但我没有具体计划在这里添加更多内容。

如果您实际上想将 --paste 与 --config 一起使用,情况如何? 在我们的例子中(RhodeCode),对于我们在 gunicorn 配置中获得的内存监控的特殊逻辑来说,这是一个很大的要求。

@marcinkuzminski这是理想的用例。 只需指定--paste--config 。 但是,Gunicorn 不会读取粘贴 ini 文件的“服务器”部分,因为期望您将在 gunicorn 配置文件中配置服务器。

那真不幸。

我们在安装程序中将 gunicorn 发送给客户,所有逻辑和配置都已委托给 .ini 文件。 这也是 Internet 上大多数示例为 Pyramid 项目指定的方式。

这种变化打破了这一点,我们可能更容易分叉 gunicorn 以将其恢复,然后将逻辑和委托配置更改为 gunicorn_conf.py :(

如果使用特殊前缀读取 --paste 选项呢? 例如,您可以使用 --paste 配置 gunicorn,但它只会读取以gunicorn.为前缀的配置选项

例如

gunicorn.workers = 2
gunicor.XXX = YYY

您不需要使用--config 。 您可以完全使用粘贴 INI。 为此使用pserve而不是gunicorn 。 请参阅文档: https: //docs.gunicorn.org/en/stable/run.html#paste -deployment

所做的更改只是删除了对使用 Gunicorn 作为可以运行服务器的通用粘贴部署 CLI 的支持。 Gunicorn 仍然_是一个_粘贴兼容服务器本身。

进行此更改是为了消除.ini文件将在其server块中指定服务员或任何其他服务器的潜在混淆,但使用gunicorn --paste production.ini运行它实际上不会使用女服务员。 人们还经常要求能够指定除server:main之外的备用server块。 当像pserve这样完美的 CLI 存在时,保持对这些功能的支持似乎没有意义。

gunicorn CLI 可以从 INI 文件中读取应用程序定义,但它使用自己的配置文件来配置服务器。 如果您想使用 INI 文件来配置 Gunicorn 服务器,请使用另一个工具(如pserve )作为脚本/进程运行器。

但根据我的第一条评论,我们必须将 --config 与 --paste 一起使用。
在我们的项目中,一切都由单个配置文件 (.ini) 管理。有很多升级/自动缩放逻辑只是调整 .ini 文件。 然后我们也使用 --config 来指定一个自定义的 python 配置来设置

  • 自定义记录器格式(这在技术上不可能使用 .ini 文件指定)
  • 工作人员内存管理(Python 代码)

Gunicorn 是 Paste 兼容的,但这种方式的功能受到限制,它给我们带来了一个问题,我们无法从中恢复,因为我们不能有 2 个配置文件,而且移动到另一个文件上的配置比实际分叉更多的工作Gunicorn 并维护该分叉只是为了恢复这种行为。

我知道这张票的基本原理,但我们曾经一起使用 gunicorn 和 waitress,我认为运行 gunicorn 二进制文件已经足够明确了,恕我直言。 此外,我认为您甚至可以检测用户是否使用不同的鸡蛋并使其成为硬错误。

如果我记得的话,我们没有考虑过这种用法。 我们可能可以带回来
作为用例的支持听起来不错。 有一个可以吗
记录警告吗?

2020 年 10 月 16 日星期五 08:28 Marcin Kuźmiński [email protected]
写道:

但我们必须将 --config 与 --paste 一起使用,根据我的第一次
评论。
在我们的项目中,一切都由单个配置文件(.ini)管理
有很多升级/自动缩放逻辑只是调整 .ini 文件。
然后我们也使用 --config 来指定一个自定义的 python 配置来设置

  • 自定义记录器格式(这在技术上是不可能的
    使用 .ini 文件指定)
  • 工作者内存管理

Gunicorn 是粘贴兼容的,但是这样限制了功能,
它给我们带来了一个我们无法恢复的问题。

我知道原因,但我们曾经一起使用gunicorn和服务员,
我认为运行 gunicorn 二进制文件已经足够明确了,恕我直言。


你收到这个是因为你被提到了。
直接回复此邮件,在 GitHub 上查看
https://github.com/benoitc/gunicorn/issues/2169#issuecomment-709838842 ,
或退订
https://github.com/notifications/unsubscribe-auth/AAADRIQR2CLVUOYK6FDY2ZDSK7RZFANCNFSM4JMI65YA
.

>

从我的手机发送

如果可能的话,我实际上考虑了另一种解决方案。 将 pserve 与 unicorn egg 一起使用时,最好将配置文件设置在 .ini 文件中。

例如

use = egg:gunicorn#main
workers = 2
config = /path/to/gunicorn_conf.py

所以它会像 --config=/path/to/gunicorn_conf.py 一样加载 gunicorn_conf.py

所以上面对我们有用,它也解决了这张票的问题。 不确定实施起来有多容易和可行。

否则,如果您可以在运行 gunicorn 二进制文件时带来从 .ini 文件加载配置的功能,那就太棒了,这将为我们省去很多麻烦。 有一个警告是没有问题的

如果可能的话,我实际上考虑了另一种解决方案。 将 pserve 与 unicorn egg 一起使用时,最好将配置文件设置在 .ini 文件中。

这应该有效并记录在案。 如果没有,请提交错误!

好的,我们会检查这个。 但是 AFAIR 在 gunicorn 与 pserve 二进制文件的工作方式上有细微的变化。 如果我记得, gunicorn --paste 可以访问 .ini 文件路径,而 pserve 使用 gunicorn egg 没有。 如果需要,我们会检查并打开相关票证。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

bywangxp picture bywangxp  ·  4评论

benoitc picture benoitc  ·  4评论

ttcqaq picture ttcqaq  ·  4评论

Abraxos picture Abraxos  ·  4评论

twosigmajab picture twosigmajab  ·  4评论