代码之家  ›  专栏  ›  技术社区  ›  dkasipovic

在集群模式下使用带有pm2的NodeJS Express服务器

  •  0
  • dkasipovic  · 技术社区  · 5 年前

    因此,我将尽我所能解释这一点:

    我编写了一个TCP服务器,它使用 net 在里面 NodeJS . TCP服务器有 connections = {} 属性,该属性包含所有连接,如下所示:

    • 设备发送握手包,其中包含 device id
    • 插座的存储方式如下: connections[device_id] = socket

    同样的TCP服务器也有 express 允许我使用JSON post直接向设备发送数据的服务器: curl -XPOST https://localhost:8080/send/device_id -d '{"command": "test"}'

    服务器解析url并用 connections[params.device_id].write()

    这一切工作正常,当使用 pm2 start server.js . 我能够跟踪设备,接受和发送数据等。

    pm2 start -i 5 server.js 在群集模式下,设备连接可以正常工作,但是 表达 部分原因是给了我麻烦。

    例如:当我使用 卷曲-XPOSThttps://localhost:8080/send/device\u id-d'{“command”:“test”}' 在80%的时间里,这将转到错误的 server.js 服务器.js 每个人都有 表达 因为PM2管理所有的东西,所以我的请求将命中 tcp 指定服务器 device_id 是连接5次中的1次。据我所知,PM2引发了5次 服务器.js 管理和平衡 tcp协议 表达 .

    所以,我的问题是,我该怎么处理?有没有办法告诉PM2转发端口 8080

    这可能吗?如果可能,这是个好主意吗?如果没有,正确的方法是什么?

    希望我能解释清楚

    当做

    *编辑*

    从最初的问题来看可能不太清楚,但是 socket 问题是从 net.createServer 功能,比如

    const net = require('net');
    const PORT = 8181;
    let connections = {}
    
    const server = net.createServer((c) => {
      //... device id parse
      connections[device_id] = c;
    });
    
    server.listen(PORT, () => {
      console.log('Server started on', PORT);
    });
    
    0 回复  |  直到 5 年前
        1
  •  0
  •   Samuel Goldenbaum    5 年前

    不清楚您是计划在同一台服务器上以worker身份运行所有服务器实例,还是可能在多个节点上运行多个worker。

    connections[params.device_id] 但是,如果这些集合存在于单个worker的内存中,则不知道彼此的数据或其他连接的套接字。

    如果

    确保应用程序是无状态的,这意味着没有本地数据 会话内存和相关的。使用Redis、Mongo或其他数据库 在进程之间共享状态。

    套接字.io有一个 redis-adapter 有助于促进套接字.io实例,以便它们知道套接字连接并有助于促进广播。

    如果您在多个服务器上运行,那么您可能需要在适当的位置设置一些粘性会话,这样您就不会被路由到同一个服务器。但是,如果实现上面建议的共享状态,那么这不是问题。如果这是不可能的,那么也许一些包,如 express-sticky-cluster 我能帮上忙。

    我自己的实现允许多个节点上的多个worker使用共享数据存储和Redis支持的适配器,这样如果客户端重新连接到不同的实例,就不会有什么区别。

    希望有帮助!

    更新 甚至还有一个 guideline 在PM2上指定了这个确切的结构。