Eventlet is_monkey_patched 问题 False

Eventlet is_monkey_patched issues False

您好,我有一个 Django 应用程序。我的整个系统配置如下: python 3, django 1.11, eventlet 0.21.0.

1) Nginx 作为上游服务器:

upstream proj_server {
        server unix:///tmp/proj1.sock fail_timeout=0;
        server unix:///tmp/proj2.sock fail_timeout=0;
}

2) 控制工人的主管。有一个gunicorn worker:

[program:proj]
command=/home/vagrant/.virtualenvs/proj/bin/gunicorn -c /vagrant/proj/proj/proj/deploy/gunicorn.small.conf.py proj.wsgi:application
directory=/vagrant/proj/proj/proj/deploy
user=www-data
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/proj.log

3) 这是一个gunicorn.small.conf内容:

bind = ["unix:///tmp/proj1.sock", "unix:///tmp/proj2.sock"]
pythonpath = "/vagrant/proj/proj/proj/deploy"
workers = 2
worker_class = "eventlet"
worker_connections = 10
timeout = 60
graceful_timeout = 60

4) 这是proj.wsgi内容:

"""
WSGI config for proj project.

This module contains the WSGI application used by Django's development server
and any production WSGI deployments. It should expose a module-level variable
named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
this application via the ``WSGI_APPLICATION`` setting.

Usually you will have the standard Django WSGI application here, but it also
might make sense to replace the whole Django WSGI application with a custom one
that later delegates to the Django one. For example, you could introduce WSGI
middleware here, or combine a Django application with an application of another
framework.

"""
import eventlet
eventlet.monkey_patch()
from eventlet import wsgi
import django.core.handlers.wsgi
import os

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "proj.settings")

# This application object is used by any WSGI server configured to use this
# file. This includes Django's development server, if the WSGI_APPLICATION
# setting points here.
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

# Apply WSGI middleware here.
# from helloworld.wsgi import HelloWorldApplication
# application = HelloWorldApplication(application)

因此,如您所见,存在一条链:nginx 作为上游服务器使用两个套接字调用其中一个 gunicorn eventlet worker proj1.sockproj2.sock。 请注意,根据 eventlet 文档,我尝试尽早使用 eventlet.monkey_patch() 。最合适的地方是 proj.wsgi ,它首先由 gunicorn 调用。

不过,该库似乎并未进行猴子修补。

为了检查这一点,我在 proj/proj/proj/__init__.py(django 应用程序调用的第一个模块)中添加了以下代码:

import eventlet
import os
print("monkey patched os is: " + str(eventlet.patcher.is_monkey_patched('os')))
print("monkey patched select is: " + str(eventlet.patcher.is_monkey_patched('select')))
print("monkey patched socket is: " + str(eventlet.patcher.is_monkey_patched('socket')))
print("monkey patched time is: " + str(eventlet.patcher.is_monkey_patched('time')))
print("monkey patched subprocess is: " + str(eventlet.patcher.is_monkey_patched('subprocess')))

then i issued **./manage.py check** and got that answer:

monkey patched os is: false
monkey patched select is: false
monkey patched socket is: false
monkey patched time is: false
monkey patched subprocess is: false

我做错了什么?

如果将 proj.wsgi 文件内容更改为一行 raise Exception 会怎么样?那应该消除嫌疑人的事件。

我不太会用 Django,这里纯属猜测:

  • 根据名称,proj.wsgi在WSGI服务器即将启动时执行
  • manage.py check好像和远程网络服务(WSGI)没有关系,好像是一般的管理命令,应该不会执行WSGI相关的代码

一个可能的解决方案,取自您的问题文本:

proj/proj/proj/init.py (the first module that called by the django application

尝试将 monkey_patch 调用放在那里。

P.S.: 你不需要 gunicorn 的主管,它的主进程(仲裁器)被设计为 运行 永远,尽管工人有问题。