JMeter压测Web应用时负载未分发至所有API服务器问题咨询
核心根因
你当前hash $remote_addr consistent;配置下所有压测请求落到单台节点的原因非常明确:单机运行JMeter发压时,所有请求的源IP都是压测机的固定出口IP,对同一个固定key做一致性哈希,计算结果唯一,自然全部请求都会路由到同一台后端。
之前切换轮询、ip_hash、sticky cookie策略后业务异常或流量不均的原因也很直接:
- 轮询策略会把同一用户的连续请求打散到不同节点,直接破坏应用依赖的会话粘滞逻辑,业务必然报错
ip_hash本质还是对源IP做哈希,和你当前用的$remote_addr哈希逻辑没有本质区别,单机压测下依然会全量落到单节点- 配置
sticky cookie srv_id后业务异常,基本都是压测侧没有做正确的cookie持久化配置导致的,不是策略本身的问题。
可行方案(同时满足会话粘滞+流量均匀分发要求)
以下方案均适配NGINX Plus版本能力,根据实际场景三选一即可:
方案1:Nginx Sticky Cookie + JMeter Cookie持久化(最推荐,和生产逻辑一致)
该方案完全匹配真实用户的访问链路,不需要修改业务逻辑,是优先级最高的选择:
- Nginx侧调整upstream配置为标准sticky cookie模式:
配置逻辑:用户首次发起请求时,Nginx会在响应头中注入upstream example { server abc; server def; server ghi; server jkl; sticky cookie srv_id expires=1h domain=.你的业务域名 path=/; }srv_idcookie,标记该用户被分配到的后端节点;后续请求只要携带该cookie,就会固定路由到对应节点,完全满足单用户全流程会话绑定要求。 - JMeter侧仅需加一个配置:在线程组下添加HTTP Cookie管理器,选择默认的标准cookie策略即可。该管理器会为每个压测线程(对应一个模拟用户)独立存储首次请求拿到的
srv_idcookie,后续请求自动携带,不会出现会话漂移。 - 压测时配置JMeter线程数(模拟用户数)≥4,随着新用户持续接入,Nginx会将新用户均匀分摊到4台后端节点,最终流量会趋近于完全均匀,同时每个用户的请求全程固定在分配的后端节点,不会影响业务流程。
方案2:调整哈希key为用户唯一标识(无cookie场景适配)
如果你不想依赖cookie实现粘滞,坚持用哈希策略,只需要把哈希维度从单一源IP替换为可区分不同模拟用户的标识即可:
- 在JMeter中给每个模拟用户的请求添加固定的自定义请求头,比如
X-User-ID,取值可以用JMeter内置线程ID生成,保证每个线程的ID全局唯一、且同一线程的所有请求该值固定。 - 修改Nginx upstream的哈希规则:
配置逻辑:Nginx会对每个请求携带的upstream example { hash $http_x_user_id consistent; server abc; server def; server ghi; server jkl; }X-User-ID做一致性哈希,不同ID的用户会被分散到不同后端节点,同一个ID的所有请求固定路由到同一节点,既满足会话粘滞要求,又能实现流量均匀分发。
方案3:JMeter分布式压测(大流量压测场景适配)
如果你需要模拟的并发规模太大,单机JMeter无法承载,可以采用JMeter分布式压测架构:
- 部署至少4台JMeter Agent节点,所有节点出口IP互不相同
- 可以保留原有
hash $remote_addr consistent;配置不需要修改 - 保证每台Agent节点发起的压测负载基本一致,不同IP的流量会被哈希到不同后端节点,最终实现流量均匀分布;同时单台Agent发出的同一用户请求会固定路由到对应后端,满足粘滞要求。
配置检查项
如果调整后依然有问题,逐一排查以下点:
- 配置sticky cookie时,确认JMeter侧没有开启“每次请求自动清空cookie”的错误配置,否则每个请求都相当于新用户,会被重新分配节点导致会话中断
- 检查upstream块中的4台后端服务器没有配置
down标记,也没有设置偏差过大的weight权重,否则会出现人为的流量倾斜 - 单机压测场景下不要继续使用
hash $remote_addr策略,该策略下永远不可能将流量分散到多台后端,属于哈希策略的固有逻辑,不是配置错误。
内容的提问来源于stack exchange,提问作者prasanna
相关产品推荐
相关产品推荐

