我有一个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))
让我们假设处理程序是一个带有数据库连接,缓存连接等的APP。
更新处理程序的最佳方法是什么。
调用reload(处理程序)是否安全?
这会破坏数据库连接吗?
数据库连接是否能够继续重启?
当前的交易会丢失吗?
这会产生反物质吗?
如果有的话,你们通常使用的最佳实践模式是什么?
答案 0 :(得分:4)
可以安全地拨打reload(handler)
。
取决于初始化连接的位置。如果你在handler()中建立连接,那么是的,当handler()
对象超出范围时,它们将被垃圾收集。但你不会在主回路内连接,是吗?我强烈推荐像:
dbconnection = connect(...)
while True:
...
socket.send(handler(data, dbconnection))
如果没有其他原因,你就不会在紧密循环中进行昂贵的连接。
那就是说,我建议采用完全不同的架构。创建一个侦听器进程基本上只是监听UDP数据报,将它们发送到RabbitMQ之类的消息传递队列,然后等待回复消息将结果发送回客户端。然后编写实际服务器,从消息传递队列中获取请求,处理它们,然后发送回复消息。
如果要升级UDP服务器,请启动在另一个端口上侦听的新实例。更新防火墙规则以将传入流量重定向到新端口。重新加载规则。杀死旧的过程。 Voila:无缝切换。
真正的胜利来自于解耦你的后端。由于多个进程可以从前端“代理”服务侦听相同的消息,因此如果您愿意,可以在不同的计算机上并行运行多个进程。要升级后端,请启动一个新实例,然后终止旧实例,以便至少有一个实例没有运行时没有时间。
要扩展代理,请在不同的端口或不同的主机上运行多个实例,并将防火墙配置为随机将传入的数据报重定向到其中一个代理。
要缩放后端,请运行更多实例。