2

我有以下用于supervisord的conf文件:

[program:backend]
command=../../../venv/bin/python backend.py

[program:celeryd]
command=../../../venv/bin/celery worker --app=tasks -l debug

[program:memcached]
command=memcached

我的 backend.py 是一个非常标准的烧瓶应用程序,带有 debug=True。它没有被守护(在控制台中运行 python backend.py 不会返回提示)

当我执行时supervisord,我看到以下提示:

[venv] supervisor$ supervisord
2013-05-08 18:42:22,148 INFO RPC interface 'supervisor' initialized
2013-05-08 18:42:22,148 CRIT Server 'unix_http_server' running without any HTTP authentication checking
2013-05-08 18:42:22,149 INFO supervisord started with pid 6778
2013-05-08 18:42:23,152 INFO spawned: 'celeryd' with pid 6781
2013-05-08 18:42:23,156 INFO spawned: 'memcached' with pid 6782
2013-05-08 18:42:23,159 INFO spawned: 'backend' with pid 6783
2013-05-08 18:42:24,314 INFO success: celeryd entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2013-05-08 18:42:24,314 INFO success: memcached entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2013-05-08 18:42:24,314 INFO success: backend entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

这是 pstree 的样子:

 | | \-+= 91117 vng -/bin/bash
 | |   \-+= 06778 vng /Volumes/Data2/Dropbox/projects/Giordano/venv/bin/python /Volumes/Data2/Dropbox/projects/Giordano/venv/bin/supervisord
 | |     |-+= 06781 vng /Volumes/Data2/Dropbox/projects/Giordano/venv/bin/python ../../../venv/bin/celery worker --app=tasks -l debug
 | |     | |--- 06795 vng /Volumes/Data2/Dropbox/projects/Giordano/venv/bin/python ../../../venv/bin/celery worker --app=tasks -l debug
 | |     | |--- 06796 vng /Volumes/Data2/Dropbox/projects/Giordano/venv/bin/python ../../../venv/bin/celery worker --app=tasks -l debug
 | |     | |--- 06797 vng /Volumes/Data2/Dropbox/projects/Giordano/venv/bin/python ../../../venv/bin/celery worker --app=tasks -l debug
 | |     | \--- 06798 vng /Volumes/Data2/Dropbox/projects/Giordano/venv/bin/python ../../../venv/bin/celery worker --app=tasks -l debug
 | |     |--= 06782 vng memcached
 | |     \-+= 06783 vng ../../../venv/bin/python backend.py
 | |       \--- 06790 vng /Volumes/Data2/Dropbox/projects/Giordano/src/giordano/web/../../../venv/bin/python backend.py

杀死主管会导致:

^C2013-05-08 18:43:18,305 WARN received SIGINT indicating exit request
2013-05-08 18:43:18,305 INFO waiting for celeryd, memcached, backend to die
2013-05-08 18:43:18,352 INFO stopped: backend (exit status 0)
2013-05-08 18:43:18,353 INFO stopped: memcached (terminated by SIGTERM)
2013-05-08 18:43:18,414 INFO stopped: celeryd (exit status 0)

不知从何而来,backend.py 在 pstree 中被取代:

 |--= 41659 root /usr/libexec/taskgated -s
 |--- 42779 vng /usr/local/Cellar/erlang/R15B03-1/lib/erlang/erts-5.9.3.1/bin/epmd -daemon
 |--= 88518 root /usr/sbin/ocspd
 |--- 97815 vng /Applications/Dropbox.app/Contents/MacOS/Dropbox /firstrunupdate 403
 |--= 97905 _usbmuxd /System/Library/PrivateFrameworks/MobileDevice.framework/Versions/A/Resources/usbmuxd -launchd
 \--- 06790 vng /Volumes/Data2/Dropbox/projects/Giordano/src/giordano/web/../../../venv/bin/python backend.py

我对此感到恼火,因为每次我重新启动 supervisord 时,我都会收到一个错误,表明该端口已被使用。

这里的任何人都知道是什么导致了这个问题?

编辑:

我的后端.py

app = Flask(__name__)
app.config.from_object(__name__)
app.secret_key = 'asgasdasdgasd'
app.debug = bool(int(os.environ.get("DEBUG", 1)))   # DEBUG=0
if app.debug:
  from giordano.web import colorer # Needed for coloring logging

app.config.update(
  MAIL_SERVER='smtp.gmail.com',
  MAIL_DEBUG=False,
  MAIL_PORT=465,
  MAIL_USE_SSL=True,
  MAIL_USERNAME = 'asdfasdfasdfasdfasdf@asdasdfas.com',
  MAIL_PASSWORD = 'asdfasdfasdfa'
)
mail = Mail(app)    # Very important to do it after!!

log_level = logging.DEBUG if app.debug else logging.INFO
logging.basicConfig(level=log_level, format='%(asctime)s %(levelname)s %(message)s')
logging.info("Launching app with debug=%s" % app.debug)

....

class TimedRequestHandler(BaseRequestHandler):
  """http://blog.sendhub.com/post/48832423565/hacking-flask-a-success-story
  """
  def handle(self):
    self.fancyStarted = time.time()
    rv = super(TimedRequestHandler, self).handle()
    return rv

  def send_response(self, code, message=None):
    self.fancyProcessed = time.time()
    super(TimedRequestHandler, self).send_response(code, message=None)

  def log_request(self, code='-', size='-'):
    duration = int((self.fancyProcessed - self.fancyStarted) * 1000)
    line = '"{0}" {1} {2} [{3}ms]'.format(self.requestline, code, size, duration)
    self.log('info', line)


if __name__ == "__main__":
   init_db() # run if you need to create tables
   app.run(host='0.0.0.0', port=8888, request_handler=TimedRequestHandler)
4

3 回答 3

1

添加stopasgroup=true您的配置,它应该可以工作。当您执行stop或时,此配置将杀死所有子进程restart

If true, the flag causes supervisor to send the stop signal to the whole process group and implies killasgroup is true. This is useful for programs, such as Flask in debug mode, that do not propagate stop signals to their children, leaving them orphaned.

http://supervisord.org/configuration.html

于 2017-09-20T04:29:52.480 回答
0

不确定这是否会对您有所帮助,但是您是否考虑过使用 nginx 来处理您的端口情况?因为我相信烧瓶默认在端口 5000 上运行,你可以创建一个 myapp.conf :

server {
    listen 80;
    server_name localhost;

    # location to your app
    root /srv/www/my_app;

    # Don't forget to create log files
    access_log /srv/www/logs/access.log;
    error_log /srv/www/logs/error.log;

    location / {
        proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://127.0.0.1:5000;
    }
}

将该配置放在“站点可用”和“站点启用”中,或者将其符号链接到ln -s /srv/www/my_app/nginx/my_app.conf /etc/nginx/<sites-available>

应用程序目录是完全任意的,但值得一试。

于 2013-05-10T21:17:45.237 回答
0

我使用启用了自动重新加载功能的 werkzeug 暂时将烧瓶应用程序向上推,类似于您正在做的事情,并且禁用自动重新加载功能解决了这个问题。你真的应该只使用 uwsgi 来处理你的烧瓶应用程序并在主管中运行它。您可以像 werkzeug 一样设置 uwsgi 来自动重新加载应用程序。

这是一个粗略的指南: http: //flaviusim.com/blog/Deploying-Flask-with-nginx-uWSGI-and-Supervisor/

你也可能有更好的运气,只是在主管中改变你的停止信号......

此外,您可以尝试在 fastcgi 模式下使用 werkzeug:http ://werkzeug.pocoo.org/docs/deployment/fastcgi/

于 2013-10-10T23:29:04.843 回答