grpc 客户端 load_balancer 配置项设在 config/autoload/services.php 的 consumers 数组内,值为字符串 'round_robin'、'random' 或 'least_conn',非字符串常量;未设置或非法时静默回退单点直连。

Hyperf 3.1.69 已内置 gRPC 多客户端负载均衡支持,无需额外安装扩展或手动 patch —— 但默认不启用,必须显式配置 load_balancer 和服务发现后才生效。
gRPC 客户端 load_balancer 配置项在哪设?
它不在 config/autoload/grpc.php 里,而是在消费者(consumer)配置中声明,即 config/autoload/services.php 的 consumers 数组内:
-
load_balancer必须是字符串,值为'round_robin'、'random'或'least_conn'(v3.1.66+ 新增) - 不能写成
LoadBalancer::ROUND_ROBIN这类常量引用,框架只认字符串字面量 - 若未设置该键,或值非法,Hyperf 会静默回退到单点直连,不会报错也不会警告
- 每个 consumer 可独立配置,不同服务可混用策略
为什么启用了 load_balancer 却没轮到多个节点?
常见原因是服务地址没真正“多起来”——gRPC 客户端负载均衡依赖服务发现结果,不是靠 servers 数组硬编码的列表。检查以下几点:
- 确认
publish_to指向了有效的注册中心(如consul或nacos),且对应服务在注册中心已注册 ≥2 个健康实例 -
servers数组在 consumer 中仅作兜底 fallback,当服务发现失败时才用;它本身不参与负载均衡决策 - 确保
governance组件已启用,且hyperf/service-governance版本 ≥3.1.66 - 调用前用
php bin/hyperf.php service:discover手动刷新一次缓存,避免本地缓存旧地址
least_conn 策略下连接数统计不准怎么办?
least_conn 在 v3.1.69 中基于每个 gRPC channel 的活跃 stream 数做判断,但默认不开启连接复用监控。需额外配置:
- 在 consumer 配置中加
'keep_alive' => true,否则 channel 会频繁重建,stream 计数失效 - 确保 gRPC server 端也启用了 HTTP/2 keep-alive(Swoole 5.0+ 默认开启,低版本需手动设
http2_keep_alive_idle) - 避免在协程内反复 new
GrpcClient实例,必须复用同一Channel对象,否则连接状态无法聚合 - 可通过
hyperf/guzzle的Pool配置间接观察:若max_connections设为 10,但实际只建了 2 条连接,说明负载根本没打散
真正关键的是服务发现链路是否闭环——从服务注册、心跳上报、客户端监听变更,到本地地址列表实时更新,任一环断开,load_balancer 就只是个摆设。别只盯着配置项,先确认 consul members 或 nacos service list 里看到的是你预期的实例数。











