在生产环境中,我们通常希望客户端只配置一个地址(如 nacos.example.com 或 VIP),而不是把所有节点的 IP 都写死在代码里。

要实现 Nacos 2.x 的“单入口完全代理”,必须同时处理 HTTP(控制台/OpenAPI)和 TCP/gRPC(服务注册/配置推送)。

核心机制: Nacos 2.x Java 客户端会自动根据主端口(例如 8848)计算出 gRPC 端口(主端口 + 1000 = 9848)。因此,Nginx 必须同时监听这两个端口并进行转发

以下是完整的 Nginx TCP Stream 转发配置方案


一、 修改 Nginx 配置文件 (nginx/nginx.conf)

请将原来的 nginx.conf 完全替换为以下内容。我们需要引入 stream 模块来处理 gRPC 流量。

Nginx

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

# --- 1. TCP/gRPC 负载均衡 (处理 9848 端口) ---
stream {
    upstream nacos-grpc {
        # 注意:这里使用容器内的服务名和内部端口
        # 只要都在同一个 Docker 网络中,它们之间就是互通的
        server nacos1:9848 weight=1;
        server nacos2:9848 weight=1;
        server nacos3:9848 weight=1;
    }

    server {
        listen 9848;
        proxy_pass nacos-grpc;
    }
}

# --- 2. HTTP 负载均衡 (处理 8848 端口 - 控制台/API) ---
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    keepalive_timeout  65;

    upstream nacos-http {
        server nacos1:8848 weight=1;
        server nacos2:8848 weight=1;
        server nacos3:8848 weight=1;
    }

    server {
        # 建议 Nginx 监听 8848,保持与 Nacos 默认习惯一致
        # 这样客户端计算出的 gRPC 端口刚好是 9848,匹配上面的 stream 配置
        listen 8848; 
        
        location / {
            proxy_pass http://nacos-http;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            # 支持 WebSocket (Nacos 控制台部分功能需要)
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
    }
}

二、 修改 Docker Compose 配置 (docker-compose.yml)

我们需要修改 nginx 服务的端口映射。现在 Nginx 将作为统一入口,分别暴露 88489848

修改后的 nginx 服务部分:

YAML

  # ... 其他服务保持不变 ...

  # --- Nginx 统一入口 ---
  nginx:
    image: nginx:latest
    container_name: nacos-nginx
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    ports:
      # 对外暴露标准的 Nacos 端口
      - "8848:8848" # HTTP 入口 (浏览器/API)
      - "9848:9848" # gRPC 入口 (Java 客户端连接)
    depends_on:
      - nacos1
      - nacos2
      - nacos3
    networks:
      - nacos-net

注意: 如果你使用了这套配置,之前 Nacos 节点暴露的端口(如 8858/9858 等)虽然还在,但不再需要配置到你的 Java 项目中了。你可以选择在 docker-compose 中保留它们用于调试,或者移除 ports 映射以增强安全性(只允许通过 Nginx 访问)。


三、 Java 项目配置更新

现在,你的 Spring Boot 配置变得非常简洁,完全像连接单机一样:

YAML

spring:
  cloud:
    nacos:
      # 只需填写 Nginx 的地址和端口
      # 客户端会自动计算出 9848 去连接 Nginx 的 Stream 代理
      server-addr: localhost:8848 
      username: nacos
      password: nacos

四、 验证单入口是否成功

  1. 重启容器

    Bash

    docker-compose down
    docker-compose up -d
    
  2. 验证 HTTP: 访问 http://localhost:8848/nacos。如果你能看到控制台,说明 HTTP 转发成功。

  3. 验证 gRPC (最关键): 启动你的 Spring Boot 项目。观察控制台日志。

    • 成功标志:日志中没有报错,且能看到类似 [Nacos] ... connected to server ... 的信息。
    • 排查:如果报错 Connection refusedServer check fail,通常是因为 Nginx 的 stream 模块没生效,或者 9848 端口没有在 Docker 映射出来。

总结

通过这种方式,Nginx 充当了真正的 L4 (TCP) + L7 (HTTP) 混合负载均衡器

  • Web 流量 走 HTTP 代理。
  • 注册/配置流量 走 TCP 透传。
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐