V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
feilaoda
V2EX  ›  程序员

C10K-C20K, 每个连接每秒发送 10-30 个消息,每个消息大概 100 个字节左右,长连接

  •  
  •   feilaoda ·
    feilaoda · 2014-07-23 11:15:10 +08:00 · 9221 次点击
    这是一个创建于 3778 天前的主题,其中的信息可能已经有所发展或是发生改变。
    问题是这样的,需要一个服务器,满足如下要求:
    1、并发在10k-20k左右
    2、长链接
    3、每个链接每秒发送10个到20个消息,大小为100字节左右
    4、每个发送消息都有回应消息,回应消息在20字节左右

    可以理解成一个echo服务器。

    目前不知道哪些程序能尽量满足这样的性能要求;C10K-C20K, Requests 10w/s-40w/s

    nginx?haproxy?netty?

    测下来还没有能达到的,不知道有没有其他的思路?或者优化的建议?
    40 条回复    2014-07-24 11:00:35 +08:00
    clino
        1
    clino  
       2014-07-23 11:20:41 +08:00
    试试 openresty ?
    canesten
        2
    canesten  
       2014-07-23 11:23:28 +08:00
    硬件条件有什么限制?
    3-4之间有什么特殊的耗时运算吗?
    feilaoda
        3
    feilaoda  
    OP
       2014-07-23 11:30:33 +08:00
    @canesten 需要存到后端MQ中去,当然可以暂时不考虑存储,3-4之间,接收后直接返回,暂不考虑耗时问题。
    mengskysama
        4
    mengskysama  
       2014-07-23 11:38:12 +08:00
    nginx妥妥不靠谱啊,你在后端又加个东西

    折腾libev吧

    然后就是带宽了,200*2000=4,000,000字节
    50M带宽妥妥的。
    canesten
        5
    canesten  
       2014-07-23 11:38:25 +08:00
    你测试用的硬件什么配置?
    i7 8 GB gigabit Ethernet 的情况netty达到50W/秒是没问题的
    mengskysama
        6
    mengskysama  
       2014-07-23 11:39:34 +08:00
    发现少了个0.
    icqdany
        7
    icqdany  
       2014-07-23 11:44:50 +08:00
    swoole+php
    feilaoda
        8
    feilaoda  
    OP
       2014-07-23 11:45:34 +08:00
    @canesten i5 2.4GHz, 8G, 并发是10K下的50w/s? 我测下来,并发1000,在6w+/s,和你差距好大;


    @mengskysama 暂时是想找找有没现成的方案,nginx可能不适合这种长链接的案例?
    lsylsy2
        9
    lsylsy2  
       2014-07-23 11:46:02 +08:00
    @mengskysama openresty性能很高,撑得住的
    以及LZ可以试试golang
    canesten
        10
    canesten  
       2014-07-23 11:49:21 +08:00
    @feilaoda
    C10K相关的内核参数你都调整过吗
    跑测试的时候注意显卡跑满了吗?
    canesten
        11
    canesten  
       2014-07-23 11:49:36 +08:00
    SORRY 网卡跑满了吗?
    missdeer
        12
    missdeer  
       2014-07-23 11:53:47 +08:00
    前些天在码农周刊看到的 http://blog.csdn.net/ghj1976/article/details/27996095 文中附有不少高质量的参考资料
    dingyaguang117
        13
    dingyaguang117  
       2014-07-23 12:07:25 +08:00
    @canesten C10K 内核参数应该怎么调好呢?求问
    dndx
        14
    dndx  
       2014-07-23 12:07:31 +08:00
    性能问题出在哪?是内存还是 CPU 不够用?消息处理占用多少资源?

    另外通信协议是什么?是 WebSocket 之类的还是私有协议?

    20k 对 Linux 来说根本就是小菜一碟,应该是哪里没弄好。
    feilaoda
        15
    feilaoda  
    OP
       2014-07-23 12:09:48 +08:00
    @canesten 内核调过,虚拟机服务器下,C10K下只有1w+/s,网卡没仔细观察,再测试一下看看。

    @clino
    @lsylsy2 openresty 难道是用的姿势不对?没netty高。
    feilaoda
        16
    feilaoda  
    OP
       2014-07-23 12:19:57 +08:00
    @dndx 简单的文本协议(私有),使用\n作为结束符号。C10k问题不大,主要是处理速度,没达到10w+/s


    @canesten 请教下,怎么你用哪个测试工具测试的,有没有推荐的?我使用的是修改后的ab程序
    tjmao
        17
    tjmao  
       2014-07-23 12:25:20 +08:00 via iPhone
    @feilaoda 虚拟机性能太烂了。我测试的NAS吞吐量只达物理机上的1/3以内。
    canesten
        18
    canesten  
       2014-07-23 12:44:08 +08:00
    @feilaoda
    虚拟机就别捣乱了
    feilaoda
        19
    feilaoda  
    OP
       2014-07-23 13:07:36 +08:00
    @canesten 不是PC上的虚拟机,是母鸡上划出来的。

    找了个ucloud机器,4核,16Gb,C10K, 2.5w+/s,cpu 120%,mem:3.5%
    canesten
        20
    canesten  
       2014-07-23 13:15:38 +08:00
    @dingyaguang117

    当前系统的全局最大打开文件数
    单个进程最大打开文件数
    缓冲区内存大小
    打开socket快速回收
    socket重用
    还有就是
    net.ipv4.tcp_max_orphans
    net.ipv4.tcp_synack_retries
    一类的
    CMGS
        21
    CMGS  
       2014-07-23 13:22:53 +08:00
    并发吃内存,下发吃CPU。。。
    你并发C20K不算多,关键是10w/s-40w/s……这个数值对于大多数CPU来说压力比较大吧
    canesten
        22
    canesten  
       2014-07-23 13:23:20 +08:00
    @feilaoda
    1000并发这个数字很可疑,很像是单个进程最大打开文件数没改过
    ulimit -n
    看看吧
    tjmao
        23
    tjmao  
       2014-07-23 13:26:35 +08:00 via iPhone
    @feilaoda 四核才120%占用率啊,剩下的时间不是在等待,就是给同一台物理机上别的虚拟机用去了。
    如果程序写access log,你也关掉试试看。曾用此法榨干Apache HTTPd的性能。
    feilaoda
        24
    feilaoda  
    OP
       2014-07-23 17:18:16 +08:00
    @canesten
    @tjmao
    @CMGS

    最新进展,找了一台物理机,8核,8Gb CentOS,客户端:i5 2.4Mhz, 8Gb

    内核参数:
    fs.file-max = 999999
    net.ipv4.tcp_rmem = 4096 4096 16777216
    net.ipv4.tcp_wmem = 4096 4096 16777216
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_fin_timeout = 15
    net.core.rmem_max = 16777216
    net.core.wmem_max = 16777216
    net.core.netdev_max_backlog = 4096
    net.core.somaxconn = 4096
    net.ipv4.tcp_max_syn_backlog = 4096
    net.ipv4.tcp_syncookies = 1
    net.ipv4.tcp_max_tw_buckets = 360000
    net.ipv4.tcp_no_metrics_save = 1
    net.ipv4.tcp_syn_retries = 2
    net.ipv4.tcp_synack_retries = 2



    [root@sz-monitor ~]# ulimit -n
    1000000
    [root@sz-monitor ~]# ulimit -Sn
    1000000
    [root@sz-monitor ~]# ulimit -Hn
    1000000


    并发10000,ab -n 5000000 -c 10000
    Requests per second: 70806.95 [#/sec] (mean)
    Time per request: 141.229 [ms] (mean)
    Time per request: 0.014 [ms] (mean, across all concurrent requests)
    Transfer rate: 5255.20 [Kbytes/sec] received


    网卡的速度
    05:16:19 PM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s
    05:16:24 PM lo 0.20 0.20 0.10 0.10 0.00 0.00 0.00
    05:16:24 PM eth0 147588.73 75031.99 14179.64 10316.23 0.00 0.00 0.00

    rxkB/s 14179.64
    txkB/s 10316.23

    CPU在200%-400%左右
    内存在3.5%左右

    正常速度70806.95/s,离400000/s差距甚远啊
    canesten
        25
    canesten  
       2014-07-23 17:51:04 +08:00
    @feilaoda
    这个是你的服务器网卡速度么?
    rxkB/s 14179.64
    txkB/s 10316.23
    算起来和你说的
    3、每个链接每秒发送10个到20个消息,大小为100字节左右
    比较相符了
    10000并发的话差不多是每秒每并发14个消息

    也就是说你这个测试就是每秒低于14万的测试

    怎么可能得到40万的结果?

    看样子网卡是收到了所有的测试压力
    而且发送的数据量远多于你描述的 100字节的五分之一
    按说
    发送的带宽达到2.xMB应该就是完成所有的请求了吧

    是不是你自己的测试客户端有什么问题


    可以试试多开几个客户端同时压

    再另
    请使用netty 4.0.21并打开native transport,使用epoll
    请尽量使用PooledDerictByteBuf并预先分配好足够多的内存
    canesten
        26
    canesten  
       2014-07-23 18:07:42 +08:00
    另外加上TCP报头什么的
    我强烈怀疑你客户端的输出能力也就是7W/秒了
    hellojinjie
        27
    hellojinjie  
       2014-07-23 18:13:05 +08:00
    @canesten 我也觉得是测试客户端的问题,我测试的时候,ab 运行在不同的机器上得到的数据是不一样的。
    ab 运行在性能较差的笔记本上,得到的数据A
    ab 运行在性能较好的笔记本上,得到的数据B
    数据B要比数据A好。。。
    canesten
        28
    canesten  
       2014-07-23 18:26:03 +08:00
    @hellojinjie
    所以可以把测试客户端部署在多个终端上
    或者用LoadRunner一类的来控制
    wecoders
        29
    wecoders  
       2014-07-23 18:37:32 +08:00
    @canesten 忘了说,本次测试发送的数据大小是60字节左右,这样应该是24万多/s?

    我也怀疑客户端的压力可能不够,再测试一下。

    netty用的4.0.12,我升级再优化一下试试。
    canesten
        30
    canesten  
       2014-07-23 18:49:37 +08:00
    @wecoders
    忘了算TCP包头最少还有40字节
    canesten
        31
    canesten  
       2014-07-23 18:59:34 +08:00
    当然你也可以打开Nagle’s Algorithm来节省TCP头来节省些带宽
    barbery
        32
    barbery  
       2014-07-23 21:31:14 +08:00
    这种需求,果断openresty啊~
    CMGS
        33
    CMGS  
       2014-07-23 21:48:42 +08:00
    - -你这CPU已经扛不住了啊。。。
    canesten
        34
    canesten  
       2014-07-23 22:44:26 +08:00 via iPad
    @CMGS 估计是内存没调,分配缓冲和GC占了不少。
    nezhazheng
        35
    nezhazheng  
       2014-07-24 09:14:11 +08:00
    @canesten
    请教大神,一直不太明白netty的native transport意义是啥,JDK1.7不已经就是epoll了吗
    canesten
        36
    canesten  
       2014-07-24 10:10:02 +08:00   ❤️ 1
    @nezhazheng
    是从1.5
    JVM添加了NIO就开始支持了的
    具体实现是sun.nio.ch.EPollSelectorImpl

    http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/nio/ch/EPollSelectorImpl.java

    这里具体的select操作还是在JVM内的

    Netty的革新在于
    io.netty.channel.epoll.Native

    https://github.com/netty/netty/blob/master/transport-native-epoll/src/main/java/io/netty/channel/epoll/Native.java

    这是一个全JNI的设计
    所有的操作都是在JVM外的
    所以效能和C++一样

    它依赖于
    sudo apt-get install autoconf automake libtool make gcc-multilib tar
    nezhazheng
        37
    nezhazheng  
       2014-07-24 10:16:50 +08:00
    @canesten
    明白啦,也就是说Netty的natvie transport epoll实现比JDK原生的epoll性能要好是吧?
    canesten
        38
    canesten  
       2014-07-24 10:23:54 +08:00
    @nezhazheng
    对的
    更完全的JNI
    所以说用Netty做网络通信
    性能上跟用C++没啥区别
    我专门和ZeroMQ做过些简单的对比
    性能上几乎是一样的
    nezhazheng
        39
    nezhazheng  
       2014-07-24 10:39:10 +08:00
    恩,netty确实是非常牛B的框架,感觉Netty应该是Java世界最优秀的框架了
    canesten
        40
    canesten  
       2014-07-24 11:00:35 +08:00
    @nezhazheng
    Java世界里网络通信的库肯定是Netty首选了
    Netty进步的速度很快
    社区也很活跃
    库里面有很多对现成协议的支持
    很多其他的框架也采用了Netty作为网络层的基础
    比如Grizzly,VertX
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1066 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 20:28 · PVG 04:28 · LAX 12:28 · JFK 15:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.