不能用 nginx http 代理模块代理 dubbo 协议,因其基于 tcp 私有二进制协议;必须启用 stream 模块做四层 tcp 代理,配置在 stream{} 块中,配合 upstream 实现负载均衡与健康检查。

不能直接用 Nginx 的 HTTP 代理模块(proxy_pass http://...)来代理 Dubbo 协议服务,因为 Dubbo 默认使用的是基于 TCP 的私有二进制协议(非 HTTP),而 ngx_http_proxy_module 只处理七层(应用层)HTTP 流量。
必须启用 Nginx 的 stream 模块做四层代理
Nginx 自 1.9.0 起支持 stream 上下文,用于处理 TCP/UDP 流量,这才是代理 Dubbo(dubbo://、tri:// 等)的正确方式。它不解析协议内容,只做连接转发,兼容所有基于 TCP 的 RPC 协议。
-
确认编译时启用了 stream 模块:运行
nginx -V 2>&1 | grep -o with-stream,输出含with-stream才可用 - 配置位置不在
http{}块内,而在顶层stream{}块中 -
Dubbo 提供者需暴露真实 IP + 端口(如
20880),且防火墙放行该端口
基础 TCP 负载均衡配置示例
在 /etc/nginx/nginx.conf 末尾或独立 include 文件中添加:
stream {
upstream dubbo_backend {
server 192.168.1.101:20880 weight=3;
server 192.168.1.102:20880 weight=2;
server 192.168.1.103:20880 backup;
}
server {
listen 20880;
proxy_pass dubbo_backend;
proxy_timeout 1s;
proxy_responses 1;
proxy_buffer_size 512k;
}
}
-
listen 20880是 Nginx 对外暴露的统一 Dubbo 入口端口,消费者直连此地址 -
weight实现加权轮询;backup标记为备用节点,仅当其他全不可用时才启用 -
proxy_timeout和proxy_buffer_size需按实际调用耗时与响应体大小调整,避免连接中断或截断
健康检查与高可用增强
stream 模块原生支持简单连接级健康检查(TCP 握手成功即认为存活),但无法识别 Dubbo 协议层面的业务异常。可配合以下手段提升可靠性:
- 启用
health_check子指令(Nginx Plus 或开源版 1.19+):health_check interval=3 fails=2 passes=2; - 结合外部工具(如 Consul Template + nginx reload)实现服务注册发现联动
- 若 Dubbo 使用 Triple 协议(gRPC over HTTP/2),可退回到
http{}块,用grpc_pass代理(需开启http_v2)
与 ZooKeeper 负载均衡的关系
Nginx 在这里承担的是消费者侧网关级负载均衡,即统一入口分发流量到多个 Dubbo 提供者实例;而 Dubbo 自身通过 ZooKeeper 注册中心实现的是消费者 SDK 内置的客户端负载均衡(如随机、最小活跃数等)。两者不冲突,可共存:
- 若消费者直连 Nginx VIP,则由 Nginx 完成首次分发,Dubbo SDK 不再参与选址
- 若消费者仍直连 ZooKeeper,则 Nginx 此时更多作为容灾网关或灰度发布通道,非必需组件
- 生产建议:Nginx 用于南北向流量(如 Web 层调用 Dubbo)、ZooKeeper 用于东西向服务间调用,职责分离更清晰











