我有一个Python应用程序,更准确地说是一个无法关闭的网络应用程序,这意味着我无法杀死PID,因为它实际上与其他服务器和客户端等进行通信......每分钟很多欧元停机时间,您知道通常的 24/7 系统。
无论如何,在我的爱好项目中,我也经常使用 WSGI 框架,并且我注意到即使在非高峰时段我也遇到同样的问题。
无论如何,想象一个使用 TCP/UDP 的普通服务器(在这里放置您最喜欢的 WSGI/SIP/分类信息服务器/等)。
现在,您在远程服务器中执行 git pull,新的 python 文件将进入服务器(这些文件当然只会影响数据处理,而不影响实际的套接字,因此无需重新启动套接字或以任何方式触摸网络部分)。
我通常不使用文件监视器,因为我更喜欢使用 SIGNAL 来唤醒内部应用程序更新程序。
现在想象一下以下代码
from mysuper.app import handler
while True:
data = socket.recv()
if data:
socket.send(handler(data))
让我们假设处理程序是一个具有数据库连接、缓存连接等的应用程序。
更新处理程序的最佳方法是什么。
调用 reload(handler) 安全吗?
这会破坏数据库连接吗?
数据库连接会在此次重启后继续存在吗?
当前交易会丢失吗?
这会产生反物质吗?
你们通常使用的最佳实践模式是什么?
最佳答案
调用reload(handler)
是安全的。
取决于您初始化连接的位置。如果您在 handler() 内部建立连接,那么是的,当 handler()
对象超出范围时,它们将被垃圾收集。但你不会在主循环内部进行连接,对吗?我强烈推荐类似的东西:
dbconnection = connect(...)
while True:
...
socket.send(handler(data, dbconnection))
如果没有其他原因,您不会在紧密循环内建立昂贵的连接。
也就是说,我建议采用完全不同的架构。创建一个监听器进程,该进程基本上只监听 UDP 数据报,将它们发送到消息队列,如 RabbitMQ ,然后等待回复消息将结果发送回客户端。然后编写实际的服务器,从消息队列获取请求,处理它们,然后发回回复消息。
如果您想升级 UDP 服务器,请启动在另一个端口上监听的新实例。更新防火墙规则以将传入流量重定向到新端口。重新加载规则。杀死旧进程。瞧:无缝切换。
真正的胜利来自于后端的解耦。由于多个进程可以监听来自前端“代理”服务的相同消息,因此如果您愿意,您可以在不同的计算机上并行运行多个进程。要升级后端,请启动一个新实例,然后终止旧实例,这样就不会出现至少一个实例未运行的情况。
要扩展您的代理,请在不同端口或不同主机上运行多个实例,并将防火墙配置为将传入数据报随机重定向到其中一个代理。
要扩展后端,请运行更多实例。
关于python - 操作方法 - 更新实时运行的 Python 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7836820/