zoukankan      html  css  js  c++  java
  • Erlang C1500K长连接推送服务-性能

    Whatsapp已经使用Erlang在生产环境跑到96GB内存单机 3M长连接,参加:WhatsApp的Erlang世界。毕竟业务级别能达到Whatsapp那样极少,现在只有千万级,单机太多挂一台影响太大,再者就是没有多线接入,每个机房都得扔那么几台机器吧,所以1M就能满足要求。

    Erlang 作为长连接网关有着天生的优势:

    - 擅长与IO密集型业务,也要求将网关设计尽量简单,认证完后,简单解析报头,就直接将请求转发给后端服务处理

    - 网络层有beam c 实现得非常高效 ,erlang 代码只是简单流程控制,也就是说代码性能很接近优化的很好c程序

    - 代码简单,易维护,erlang 进程和连接一对一关系,代码500行左右

    - 基于进程GC,node 内存多大也不用担心stop of word

    - 热升级,网关设计本尽量简单,减少升级,但也不可避免,热升级保证不断连接

    - 稳定,beam 足够稳定,即使天天更新的服务,连续一两年不重启也正常

    - 多语言混合,后端可很容易使用其他语言实现

    劣势:CPU密集型业务,性能差,如果不想用c解包,尽量使用二进制协议,尽量将包协议标识放在包体固定位置,方便dispatch

    1. 测试环境

      - 服务端: R620 2*(E5-2620 6核心12线程)/mem:128GB

      - 客户端:R620 2*(E5-2620 6核心12线程)/mem:48GB(5台*5 IP,共25IP)

    2. 调优

      1. beam 启动参数

      +sbt db 绑定调度器与CPU的亲缘性

      +P 2000000 进程数限制(合适即可)

      +K true 启用epoll

      +sbwt none 关闭beam 调度器 spinlock,降低CPU

      +swt low 提高调度器唤醒灵敏度,避免长时间运行睡死问题

      参考我另外一篇:erlang cpu 相关参数调整

      2. Erlang 网络库:ranch 需要修改

        - 配置acceptors 数量1024,backlog 32768

        同时系统backlog调整: net.core.somaxconn, net.core.netdev_max_backlog, net.ipv4.tcp_max_syn_backlog 32768

        - 删除新加连接时的 ranch_sup 和 connection monitor,占用内存且用处不大,同时单进程热点问题,也造成backlog 无法及时处理

        - acceptor 设置 process_flag(prority, high),否则因为公平调度问题,即使CPU不高,backlog 无法及时得到处理

           3. Erlang内存占用

       因为Erlang GC 基于进程,每个连接对应一个进程,每个连接的业务量都很小。那样就会造成一种现象数百w进程内都有一点垃圾,无法得到GC。

       使用hibernate,erlang:hibernate 会清空但前调用栈,并强制GC,下次进程收到消息后,会通过参数MFA继续执行。

       使用gen_server 简单的在没有个包处理完后,都加上hibernate, CPU无明显增加情况下,可将内存使用降低到1/3 以下,非常值得使用。

    3. 压测场景

      - 客户端在5台机器,25个IP,开启 tcp_tw_reuse tcp_tw_recycle 后每个IP稳定跑6w连接还是没问题的。

      - 6K/s 登陆、认证、心跳、退出 操作

      - 1w/s 消息推送、ack

      - 运行12 小时

    4. 结果

     ss -s
    Total: 1500254 (kernel 1500317)
    TCP:   1500090 (estab 1500077, closed 0, orphaned 0, synrecv 0, timewait 0/0), ports 74
    
    Transport Total     IP        IPv6
    *      1500317   -         -
    RAW      0         0         0
    UDP      0         0         0
    TCP      1500090   1500090   0
    INET      1500090   1500090   0
    FRAG      0         0         0

      网关机器:

      - CPU 500%

      - 网卡 6w/s tcp packet in/out

      - node mem 12GB (内部memory(total) 显示实际使用9GB)

      - kernel mem 11GB

      - 也就是150w连接,使用了23GB内存,每个连接占用15KB,约一半是内核使用,erlang 使用内存并不多。

      - 在如此业务量压力下,500% CPU表现也不俗,随无法和c相比,但其多核扩展性好。

      - 服务器有24核心,但环境其他服务、客户端IP数限制,没有继续增大压力,理论上单机200~300w 连接,5w/s 消息推送 应该不是问题。

  • 相关阅读:
    Eclipse在线集成maven M2eclipse插件
    RBAC用户权限管理数据库设计
    Linux下修改mysql密码
    Red hat 6.4下面的qt安装
    export default {} 和new Vue()区别
    Ajax中POST和GET的区别
    JS es6-Symbol
    JS es6编程规范
    JS之箭头函数
    JS异步加载的方式
  • 原文地址:https://www.cnblogs.com/lulu/p/4132278.html
Copyright © 2011-2022 走看看