V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Sparetire
V2EX  ›  Node.js

node 在高并发下的性能优化,各位有哪些好的建议吗?

  •  
  •   Sparetire · 2016-11-24 21:35:38 +08:00 · 7907 次点击
    这是一个创建于 2940 天前的主题,其中的信息可能已经有所发展或是发生改变。

    公司业务需要用 node 转发微信消息给其他后端服务器,每次推送 20W 模板消息, node 会收到 TEMPLATESENDJOBFINISH 的消息回复

    一开始和这个问题的情况类似,逻辑很简单,就接受消息转发消息,也是用 request 发送消息,并发量一大后面的请求处理时间就很长,导致经常 5s 内无法响应微信服务器进而报警。后来查了半天发现 node 默认线程池只有 4 个线程,以及 socket 池最多 5 个 socket 连接,于是就把这两个给调大了,竟然有用,好的时候都能在 5s 内处理完,但还是发生了一两次超时的情况,微信报警都是 1W+ 的无返回。

    目前看来大部分时候能处理完,说明 node 本身应该是能撑住这么多并发。但那一两次报警都有 1W+,显然也不正常,而那一两次报警时,接受的请求和数量都没什么不同,求教大家可能的情况?

    大家如果有其他 node 性能优化或者高并发的建议,也欢迎讨论

    16 条回复    2016-11-26 21:08:00 +08:00
    lbp0200
        1
    lbp0200  
       2016-11-24 21:40:00 +08:00
    不懂 node ,不过为什么不用 nginx 或者其他成熟的软件
    Sparetire
        2
    Sparetire  
    OP
       2016-11-24 21:44:19 +08:00
    @lbp0200 主要逻辑是转发消息,但还是稍稍有些判断的, node 帮助挡掉 TEMPLATESENDJOBFINISH 的消息,其他时候根据用户 groupid 转发给不同的后端
    airyland
        3
    airyland  
       2016-11-24 21:45:30 +08:00 via iPhone
    直接 return success 再用 setTimeout 或者队列转发到后端呀,后端根据需要用客服接口发送消息就可以。
    Sparetire
        4
    Sparetire  
    OP
       2016-11-24 21:57:19 +08:00
    @airyland 对于 TEMPLATESENDJOBFINISH 是直接 return success 的,对于用户发来的消息,会根据情况转发给不同的后端,现在的问题是后端发送大量模板消息,微信回复的 TEMPLATESENDJOBFINISH 消息就都到 node 这来, node 有两次有 1W+ 的消息没在 5s 内处理完,感觉很诡异,要说扛不住,那应该每次都扛住了,但现在大部分时候扛住了就这么两次处理超时。。
    xxxyyy
        5
    xxxyyy  
       2016-11-24 22:19:48 +08:00 via Android
    那就再加大点 thread pool 和 max sockets 😁
    Sparetire
        6
    Sparetire  
    OP
       2016-11-24 22:28:07 +08:00
    @xxxyyy 加到多少呢。。现在是 4 核的机器, PM2 开了 4 个进程 64 个线程
    xxxyyy
        7
    xxxyyy  
       2016-11-24 22:37:21 +08:00 via Android
    @Sparetire socket pool 加到多大了?
    Sparetire
        8
    Sparetire  
    OP
       2016-11-24 22:53:46 +08:00
    @xxxyyy 7000 。。这个数字我看别人调几 W ,感觉机器比较一般就调了 7000 ,我也不知道调多少比较好
    songdezu
        9
    songdezu  
       2016-11-25 02:49:39 +08:00
    nodejs 最大的优点不是可以 scale up 用多台服务器均衡 request
    vietor
        10
    vietor  
       2016-11-25 07:38:04 +08:00 via Android   ❤️ 1
    用 DB 或其他的作一个队列
    vghdjgh
        11
    vghdjgh  
       2016-11-25 07:52:26 +08:00   ❤️ 2
    1 、调 v8 引擎参数;
    2 、最大 socket 数在 0.12 版本之前默认是 5 ,之后都是正无穷,所以直接改成正无穷,或者升级版本;
    3 、调系统限制参数,各种 limit ;
    4 、开多个服务来扩展;
    5 、运行时通过 v8-profiler ,查看内存和 CPU 状态,查出瓶颈;
    6 、考虑上个消息队列。
    vultr
        12
    vultr  
       2016-11-25 08:37:08 +08:00 via Android   ❤️ 1
    收到消息记录到内存或文件立即返回,再用其他进程处理消息,在 node 前面加个 nginx ,分发到不同的 node 节点上。
    sampeng
        13
    sampeng  
       2016-11-25 15:48:07 +08:00
    最好的办法?当然是不用 node 。。。。。
    maxmilia
        14
    maxmilia  
       2016-11-26 16:44:41 +08:00
    同意 11L 。
    如果没有特别实时性的要求,可以尝试 redis 等做 message queue
    jarlyyn
        15
    jarlyyn  
       2016-11-26 20:21:47 +08:00
    感觉应该直接压到队列里面啊。
    loqixh
        16
    loqixh  
       2016-11-26 21:08:00 +08:00
    我觉得是发生 fullGC 导致无法响应
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1738 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 16:19 · PVG 00:19 · LAX 08:19 · JFK 11:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.