Python金字塔关闭事件

时间:2018-08-09 13:51:34

标签: python docker pyramid netflix-eureka waitress

对于Python和Pyramid,我是新手,如果在这里做错了事,我深表歉意。

我目前正在Docker容器中运行一个Pyramid应用程序,具有以下入口点:

pipenv run pserve development.ini --reload

这可以正确地为我的应用程序提供服务,然后我可以直接在容器内编辑代码。这一切都很好。然后,我尝试将该服务注册到Netflix的Eureka服务注册表实例,以便随后可以使用网关(例如Netflix Zuul)将此服务代理到该服务。我使用Eureka的REST API来实现这一目标,而且一切都很好。

但是,当我关闭Pyramid服务时,我想向Eureka发送一个额外的HTTP请求以删除注册的服务-这是理想的选择,因此我不必等待Eureka的到期,并且永远不会是Zuul可能会将请求代理到已关闭的服务的窗口。

问题是我无法可靠地找到在金字塔中运行关闭事件的方法。基本上,当我停止Docker容器时,该服务会收到退出代码137(我相信这是kill -9的结果),并且什么也没有发生。我尝试使用atexit以及信号事件(例如SIGKILL,SIGTERM,SIGINT等),但没有任何反应。我也尝试过在没有--reload标志的情况下运行pserve,但这仍然行不通。

无论如何,我是否有必要在服务器和Docker容器关闭之前可靠地获取此DELETE事件以发送?

这是我正在使用的development.ini文件:

[app:main]
use = egg:my-app
pyramid.reload_templates = true
pyramid.includes =
    pyramid_debugtoolbar
    pyramid_redis_sessions
    pyramid_tm

debugtoolbar.hosts = 0.0.0.0/0

sqlalchemy.url = mysql://root:root@mysql/keyblade

my-app.secret = secretkey

redis.sessions.secret = secretkey
redis.sessions.host = redis
redis.sessions.port = 6379

[server:main]
use = egg:waitress#main
listen = 0.0.0.0:8000

# Logging Configuration

[loggers]
keys = root, debug, sqlalchemy.engine.base.Engine

[logger_debug]
level = DEBUG
handlers =
qualname = debug

[handlers]
keys = console

[formatters] 
keys = generic

[logger_root]
level = INFO
handlers = console

[logger_sqlalchemy.engine.base.Engine]
level = INFO
handlers =
qualname = sqlalchemy.engine.base.Engine

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s

2 个答案:

答案 0 :(得分:2)

WSGI应用程序没有关闭协议/ api(尽管人们使用/希望应用程序创建接近服务器开始处理请求的时间,但是从技术上讲,也没有一个用于启动的协议/ api)。您也许可以找到提供一些挂钩的WSGI服务器(例如gunicorn提供http://docs.gunicorn.org/en/stable/settings.html#worker-exit),但是更好的方法是让上游通过运行状况检查来处理消失的服务器。期望您能够在出现问题时可靠地发送DELETE,这不太可能是一个可靠的解决方案。

答案 1 :(得分:0)

  

但是,当我关闭Pyramid服务时,我想向Eureka发送一个额外的HTTP请求以删除注册的服务-这是理想的选择,因此我不必等待Eureka的到期,并且永远不会是Zuul可能会将请求代理到已关闭的服务的窗口。

这是特定于Web服务器的,Pyramid无法为其提供抽象,因为“您的里程可能会有所不同”。 Web服务器工作人员本身不知道何时杀死他们,因为它是外部强制的。

我将采用一种方法,其中您需要一个外部进程来监视Web服务器,然后在检测到Web服务器不再运行时执行清理操作。不再运行的定义可能是“没有单个进程处于活动状态”。然后,您只有一个后台计划作业(cron)来检查这种情况。甚至更好的做法是,将其放在另一个监视实例上,该实例位于不同的服务器上,并且可以在服务器本身发生故障的情况下采取措施。