node+socket.io
我使用的是websocket-bench进行并发测试。
服务器和测试都在本地。node 端采用多进程多端口。
但是测试的过程中发现,负载只在一个 ws 服务器的时候是没问题的,但是同时使用多个 ws 服务器,就会出现 400 错误,请求错误。
我初步估计是发送 ws 的 key 的时候和之后升级协议分配到了不同的服务器,导致不认这个请求,所以报 400 错误。如果还有其他可能,请指正。
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;
}
}
我的毕设不解决这个问题大概就要吹了- -
本地压测解决了。可喜可贺可喜可贺。本来还想改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我明明是个前端)
1
djhuahao 2017-04-27 18:02:32 +08:00
为何不抓个包试试呢?
|
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 """ |
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 这种。 |
4
cassia 2017-04-27 18:12:09 +08:00
session 共享做了吗?
|
5
ivyliner 2017-04-27 18:13:01 +08:00 1
可以增加一下 consistent_hash 试试
|
7
vuuv 2017-04-27 21:49:41 +08:00 via Android
websocket 协议本身有会话校验的,需要确保同一会话的请求由同一服务处理。
可以考虑在现有网卡上配置多个 IP 或者创建一批虚拟网卡,然后绑定 IP 压测,Nginx 开启 hash。 |
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 又不是长跑,没多少钱的 |
9
vebuqi 2017-04-28 09:03:52 +08:00 via Android
感觉应该用 sticky 策略
|
10
yernsun 2017-04-28 10:32:41 +08:00
可以通过追加 cookie 之类的解决,然后通过 cookie 值进行 hash
|
12
cccRaim OP @panlilu haproxy 试过了,好像策略上也不满足我的要求,jmeter 的 ip 欺骗好像只限于 http,ws 的还不支持
|
13
cccRaim OP 当然选择改 websocket-bench 源码也是可以的,不过我没开始看
|