对 websocket 服务器进行压测, nginx 负载均衡,该怎么做? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
cccRaim
V2EX    NGINX

对 websocket 服务器进行压测, nginx 负载均衡,该怎么做?

  •  1
     
  •   cccRaim
    cccraim 2017-04-27 17:33:08 +08:00 10197 次点击
    这是一个创建于 3136 天前的主题,其中的信息可能已经有所发展或是发生改变。

    服务端

    node+socket.io

    测试工具

    我使用的是websocket-bench进行并发测试。

    服务器和测试都在本地。node 端采用多进程多端口。

    问题:400 错误

    但是测试的过程中发现,负载只在一个 ws 服务器的时候是没问题的,但是同时使用多个 ws 服务器,就会出现 400 错误,请求错误。

    我初步估计是发送 ws 的 key 的时候和之后升级协议分配到了不同的服务器,导致不认这个请求,所以报 400 错误。如果还有其他可能,请指正。

    nginx 配置如下

    upstream io_nodes { #ip_hash; # 实际需求肯定采用这个策略,但是本地压测使用的都是同一个 ip,将会导致请求只分配到同一个服务器上 server 127.0.0.1:8001; server 127.0.0.1:8002; server 127.0.0.1:8003; server 127.0.0.1:8004; } server { listen 8088; server_name server.com; error_log logs/error.log debug; access_log logs/access.log; location / { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_http_version 1.1; proxy_pass http://io_nodes; } } 

    求解决方法

    1. 或许是希望好心人能提供能解决这种情况的测试工具
    2. 或许是一个正确的 nginx 配置或一致性策略
    3. 或许是个更好的服务端架构

    我的毕设不解决这个问题大概就要吹了- -

    第 1 条附言    2017-05-01 23:43:43 +08:00

    本地压测解决了。可喜可贺可喜可贺。本来还想改websocket-bench源码的,还好还没开始改。

    负载均衡服务器:

    依然采用nginx,nginx的1.7.2版本以后自带hash了,自定义配置各种策略,所以不用装consistent_hash。

    测试工具:

    测试工具换成jmeter。
    因为websocket-bench可自定义的东西太少,并且如果要根据nginx负载均衡的策略来看,我压测的每个请求必须得每个请求都不太一样,此处我采用jmeter的random函数,我在请求的参数加上了${__Random(1,100)},这是jmeter的随机函数,当然范围可自定义,倒是实现了压测时每个请求都不太一样。

    所以根据我上面的改动,nginx的配置改动如下

    #ip_hash; hash $request_uri; # 根据请求的uri来分配 

    感谢@ivyliner 的回复让我在绞尽脑汁想找测试工具的时候让我把解决问题出发点换到了服务器上面(虽然他本人肯定没意识到),之前绕的路太多了,辛酸泪就不说了。甚至在jmeter的ws的sample没有模拟ip功能的情况下,想要改java代码(我真是不想活了, QAQ我明明是个前端)

    13 条回复    2017-05-02 08:44:23 +08:00
    djhuahao
        1
    djhuahao  
       2017-04-27 18:02:32 +08:00
    为何不抓个包试试呢?
    devops
        2
    devops  
       2017-04-27 18:05:23 +08:00   1
    用 go 写,就不需要 nginx 了。有 cloudflare 为这个背书呢 https://blog.cloudflare.com/exposing-go-on-the-internet/

    """
    The days of needing NGINX in front of all Go services are gone
    """
    panlilu
        3
    panlilu  
       2017-04-27 18:07:39 +08:00
    nginx 的负载模式在没有装额外插件的情况下只有 轮询 最小连接 iphash 3 种,应该是满足不了你的需求的。
    比较方便的方案是用 haproxy 代替 nginx,详细配置参考 http://toon.io/configuring-haproxy-multiple-engine-io-servers/ 这篇文章。

    分布式的压测工具有很多(比如 Tsung、jmeter ),但是学习曲线大都比陡,尤其是要压 socket.io 这种。
    cassia
        4
    cassia  
       2017-04-27 18:12:09 +08:00
    session 共享做了吗?
    ivyliner
        5
    ivyliner  
       2017-04-27 18:13:01 +08:00   1
    可以增加一下 consistent_hash 试试
    cccRaim
        6
    cccRaim  
    OP
       2017-04-27 18:31:24 +08:00
    @cassia 使用的是同一个 redis,不是 session 问题吧
    vuuv
        7
    vuuv  
       2017-04-27 21:49:41 +08:00 via Android
    websocket 协议本身有会话校验的,需要确保同一会话的请求由同一服务处理。
    可以考虑在现有网卡上配置多个 IP 或者创建一批虚拟网卡,然后绑定 IP 压测,Nginx 开启 hash。
    ryd994
        8
    ryd994  
       2017-04-28 06:03:48 +08:00 via Android
    IP hash 应该能用啊………
    本地压测好办,127.0.0.1/8 下面的任何地址都可以用,
    ip addr 127.0.0.2 dev lo
    自己写个脚本加一堆地址就好了
    测试工具一一对应绑在地址上
    再再再不行,上 docker 啊,上虚拟机啊,上 AWS 啊
    反正 AWS 又不是长跑,没多少钱的
    vebuqi
        9
    vebuqi  
       2017-04-28 09:03:52 +08:00 via Android
    感觉应该用 sticky 策略
    yernsun
        10
    yernsun  
       2017-04-28 10:32:41 +08:00
    可以通过追加 cookie 之类的解决,然后通过 cookie 值进行 hash
    cccRaim data-uid=
        11
    cccRaim  
    OP
       2017-04-28 20:18:36 +08:00
    @vebuqi sticky 试了,没用,测试工具估计不记录 cookie
    cccRaim
        12
    cccRaim  
    OP
       2017-05-01 22:53:53 +08:00
    @panlilu haproxy 试过了,好像策略上也不满足我的要求,jmeter 的 ip 欺骗好像只限于 http,ws 的还不支持
    cccRaim
        13
    cccRaim  
    OP
       2017-05-02 08:44:23 +08:00
    当然选择改 websocket-bench 源码也是可以的,不过我没开始看
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3023 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 12:50 PVG 20:50 LAX 04:50 JFK 07:50
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86