You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Swarm用Replicas扩展Rust Web服务,规避内置负载均衡

问题背景与需求

我用Rust开发Web服务器,在Docker Compose中手动定义两个服务时运行正常,配置如下:

x-common_auth_service: &common_auth_service
  container_name: auth
  build: 
    context: ./auth
    dockerfile: Dockerfile
  network_mode: host
  restart: always
  deploy:
    resources:
      limits:
        memory: 40M
      reservations:
        memory: 20M
  depends_on:
    - redis

services:
  
  auth:
    <<: *common_auth_service
    container_name: auth
    environment: 
      APP_PORT: 3002 # 指定端口
  
  auth2:
    <<: *common_auth_service
    container_name: auth2
    environment: 
      APP_PORT: 3003 # 指定端口

但切换到Docker Swarm部署并使用Replicas时遇到问题,当前配置如下:
compose.yml

auth_service:
  image: service/auth_app_rust
  build: 
    context: ./auth
    dockerfile: Dockerfile
  networks:
    - network_overlay # 之前用的host网络,这就是问题所在
  ports:
    - "5000-5001:3002"
  deploy:
    mode: replicated
    replicas: 2

nginx:
  image: nginx:latest
  volumes:
    - ./nginx/auth.conf:/etc/nginx/nginx.conf
  networks:
    - host
  depends_on:
    - auth_service

nginx.conf

upstream auth_server {
    server 127.0.0.1:5000;
    server 127.0.0.1:5001;
    keepalive 200;
}

server {
    listen 9999;
    location / {
        proxy_buffering off;
        proxy_set_header Connection "";
        proxy_http_version 1.1;
        proxy_set_header Keep-Alive "";
        proxy_set_header Proxy-Connection "keep-alive";
        proxy_pass http://auth_server;
    }
}

原本手动定义服务时,每个副本用不同端口,于是尝试用端口范围映射,但发现Docker Swarm不会给每个容器分配固定端口,反而会在副本间做内置负载均衡——比如执行curl http://localhost:5000时,不一定访问到容器1。

需求:

  • 继续使用Replicas扩展服务,不逐个定义服务
  • 不使用Docker Swarm内置负载均衡(已有Nginx实现,内置负载适配效果不佳)
  • 实现Rust Web服务器容器的批量扩展

Host网络场景解决方案

核心思路:通过{{.Task.Slot}}占位符为每个任务副本分配唯一端口,避免冲突;同时修改update_config配置,确保容器更新时不会出现端口占用冲突。

关键配置片段:

update_config:
  parallelism: 1
  order: stop-first

完整的compose.yml配置(Host网络模式,提升性能):

auth_service:
  image: service/auth_app_rust
  hostname: auth-service-{{.Task.Slot}}
  build: 
    context: ./auth
    dockerfile: Dockerfile
  networks: # 端口使用300*段
    - host
  environment:
    REDIS_HOST: localhost
    APP_PORT: "300{{.Task.Slot}}" # 基于任务槽位ID指定服务端口
    METRIC_PORT: "301{{.Task.Slot}}"
  deploy:
    mode: replicated
    replicas: 2
    update_config:
      parallelism: 1 # 每次仅更新1个副本
      order: stop-first # 先停止旧副本再启动新副本,避免端口冲突
      failure_action: rollback
      delay: 5s
    resources:
      limits:
        memory: 40M
      reservations:
        memory: 20M
  depends_on:
    - redis
    - rust_service_builder
  healthcheck:
    test: wget --no-verbose --tries=1 --spider http://127.0.0.1:3002/health
    retries: 5
    interval: 3s
    timeout: 5s


networks:
   host:
     name: host
     external: true

内容的提问来源于stack exchange,提问作者rick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 15:43:15