关闭非常繁忙的生产节点

Mer*_*erc 5 node.js

我在生产服务器上有一个非常非常繁忙的节点应用程序.该应用程序处理实时聊天(使用websockets)以及电子商务付款.虽然一切都是绝对设置的,所以当服务器关闭时,客户端将重新连接其套接字等,我仍然有一个问题:每当服务器停止时,使用SIGINT,事件循环都会被切断.这意味着任何挂起的DB写入(可能用于金融交易)都会被丢弃.有两个特别关键的时刻(当信用卡商家给出OK时,但我们在数据库上写下记录之前),目前我们在非高峰时间关闭它以防止任何可能的问题.但这很糟糕.

我认为这是一个解决方案:

  • 我向进程发送一个自定义UNIX信号(例如SIGUSR2?);
  • 当server.js获得信号时:
    • 它停止听80端口
    • 它等待事件循环干涸
    • 如果在10秒之后它仍然悬挂,它会强制关闭.这意味着在每次重启时服务器将最多停机10秒钟.

这是现实世界中的人们做的吗?有问题吗?如何检查事件循环是否为空?

Alp*_*pha 1

我希望这能解决你的问题,但至少希望能有所帮助(而且评论太长了)。

这是负载均衡器最有帮助的目的,您可以控制特定服务器的流量达到这样的程度,如果您需要关闭服务器,您可以安全地告诉它不再被使用。由于您直接与服务器打开 Websocket,因此这些连接很可能会直接保留到该服务器,并且无法通过负载均衡器进行代理(不确定这一点),但不创建新连接最终会导致这些连接最终消亡。

或者,考虑一个穷人版本的负载均衡器,并在此服务器上设置一个代理,该代理将访问其他服务器。如果您的所有状态都通过公共数据库保存,则不会中断任何操作,并且您可以给予足够的时间(无论是什么)来完成事件循环。

至于服务器的使用情况,如果您当前没有任何方法来判断事件循环发生了什么,那么服务器中的任何应用程序日志都可能有助于确定您的应用程序正在做什么,只需良好的判断就可以知道您在特定点将其关闭有多安全。(再次强调,在此之前您可以减少使用量越多越好。)

最后,正如 Archimendix 所建议的,使用process.on()处理优雅终止几乎是跨平台的标准。(让我想起很多基于 Java 的服务器需要一些时间才能关闭。)根据非终止应用程序影响的严重程度,您可能希望让进程挂起更长的时间,甚至执行关闭程序,但您应该考虑到这并不总是可能的。

最后,尽量避免完全依赖任何特定服务器。受控关闭很容易处理,但中断和硬件故障不会给您带来等待事件循环的好处。