Nodejs故障转移

9
我是一个Node.js的初学者,我想在生产中使用Node.js。我希望实现Node.js故障转移。由于我正在执行聊天应用程序,如果一个节点服务器失败,聊天不应该中断,并应该自动连接到另一个节点服务器,同时应该使用相同的socket id进行进一步的聊天,以便聊天消息不会丢失。这是否可以实现?是否有示例代码?
我不应该使用Ngnix/HAProxy。还请告诉我节点服务器应该如何设置:要么是主动-主动,要么是主动-被动。
5个回答

8
PM2是一个进程管理器,特别适合用于IT技术方面的自动故障转移、自动扩展和自动重启等功能。以下是简介:

PM2 is a production process manager for Node.js applications with a built-in load balancer. It allows you to keep applications alive forever, to reload them without downtime and to facilitate common system admin tasks.

Starting an application in production mode is as easy as:

$ pm2 start app.js

PM2 is constantly assailed by more than 700 tests.

Official website: http://pm2.keymetrics.io

Works on Linux (stable) & MacOSx (stable) & Windows (bêta).


3

你面临着几个问题:

守护进程 - 保持应用程序不停机: 如前所述,可以使用像forever这样的脚本来监控您的nodeJS应用程序,在失败时重新启动它。这对于在最坏的情况下启动应用程序非常有用。

同样,可以使用recluster来分叉应用程序,并通过创建一个监管进程和子进程使其更具容错性。

未捕获异常: 在nodejs中已知的障碍是不能使用try/catch块捕获异步错误。因此,异常可能会冒泡并导致整个应用程序崩溃。

与其让这种情况发生,您应该使用domains来创建一个逻辑活动组,受到异常影响,并根据需要处理它。如果您正在运行带状态的Web服务器,则应该捕获未处理的异常,并在终止应用程序之前优雅地关闭所有其他连接。

(如果您正在运行无状态应用程序,则可以尝试忽略异常并尝试继续运行;但这并不一定是明智之举,请谨慎使用。)

安全: 这是一个很大的主题。您至少需要确保:

  1. 您的应用程序以最低特权的非root用户运行。端口<1024需要root权限。通常,这些端口会通过nginx、docker或类似工具进行代理。
  2. 您正在使用helmet并已经尽可能使您的应用程序更加安全。

另外,我看到你在NodeJS前面使用了Apache,这不一定是必要的,因为Apache的线程模型可能比NodeJS的事件循环模型更难以承受负载。


1
假设您使用数据库验证客户端,那么要完成的事情并不多,我的意思是,需要一个脚本来管理服务器脚本的状态,就像forever一样。
它会尝试启动脚本,如果失败了,更重要的是,您应该设计服务器脚本来处理每个已知和可能的未知错误,任何发送给它的信号等。
一个小例子是流。
(Websocket Router)
 |       
 |_(Chat Channel #1) \
 |_(Chat Channel #2) - Channel Cache // hold last 15 messages of every channel  
 |_(Chat Channel #3) / 
 |_(Authentication handler) // login-logout

-- 希望我在某种程度上有所帮助。

谢谢回复。实际上我想要实现的是有两个节点服务器,我将通过apache访问它们。在apache中,我已经使用了ProxyPass和mod_proxy_balancer来路由到节点服务器。我已经在负载均衡器中设置了failonstatus=503。由于apache不支持(使用2.2)websocket,因此建立了xhr-polling连接。主要问题是当我们运行两个节点服务器时,客户端会不断尝试与节点服务器建立连接。在节点服务器中,我们发现了一个循环,“客户端未握手,客户端应重新连接”。有什么办法可以克服这个问题吗? - user2344173
我在按照你描述的方式使用Apache方面没有太多经验,有可能无法代理请求到Node WebSocket服务器。一个可能的解决方法是分别运行Node服务器和Apache服务器,提供客户端静态客户端socket.io脚本并尝试连接到Node服务器,然后从“共享”点验证cookie/session,以某种方式对其进行身份验证。此外,如果您只是使用Apache提供静态文件,请尝试轻松切换到Node.js静态文件服务器,这将节省很多精力。 - Gntem

1
对于简单的方法,我认为你应该在客户端建立一个重新连接机制,并使用进程管理工具如foreverPM2来管理你的Node.js进程。我尝试了很多方法,但仍然无法解决套接字问题,每当进程停止时它总是被杀死。

0
你可以尝试使用Pm2 start app.js -I 0。这将以集群模式运行您的应用程序,为同一线程创建许多子进程。您可以在各个进程之间共享套接字信息。

如果客户端和Pm2之间的网络不可达,Pm2将无法响应,因此即使您有100个实例提供请求,客户端也无法访问服务器,只是因为到Pm2实例的路径被中断。Node js实例设置应完全分布式,并通过Nginx + Keepalived或任何其他负载平衡进行同步。 - Ankur Soni

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接