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

Docker Compose部署时Eureka仅注册单个服务实例问题排查

问题分析与解决

核心问题

你之前的docker-compose配置方式是错误的:

  • 直接在单个currency-exchange-service服务下绑定"8000:8000"和"8001:8000",只会启动一个容器,把两个宿主机端口映射到这个容器的8000端口,根本没启动两个服务实例。
  • 用--scale启动多实例时,固定端口映射会导致端口冲突,第二个实例无法绑定已被占用的宿主机端口。
  • 服务的server.port固定为8000,且Eureka默认用${spring.application.name}:${server.port}作为实例ID,就算启动两个实例,实例ID完全重复,Eureka会判定为同一实例,后启动的会覆盖先启动的注册信息。

1. 修正docker-compose.yml配置

要启动多实例,需调整端口映射规则,并配置实例ID的唯一性:

version: "3.7"

services:
  currency-exchange-service:
    image: ...
    mem_limit: 1000m
    ports:
      - "8000-8001:8000"  # 让Docker在8000-8001范围内自动分配宿主机端口给容器的8000端口
    networks:
      - microservices-network
    depends_on:
      - service-registry
    environment:
      EUREKA.CLIENT.SERVICEURL.DEFAULTZONE: http://service-registry:8761/eureka
      MANAGEMENT.ZIPKIN.TRACING.ENDPOINT: http://zipkin:9411/api/v2/spans
      SPRING.CLOUD.EUREKA.INSTANCE.INSTANCE-ID: "${spring.application.name}:${random.value}"  # 生成唯一实例ID

如果不需要限制宿主机端口范围,也可以用更灵活的配置,让Docker自动分配可用端口:

ports:
  - "8000"  # 容器内8000端口映射到宿主机随机可用端口

启动命令必须用scale参数指定实例数:

docker-compose up --scale currency-exchange-service=2

2. 调整服务的application.properties配置

修改配置文件,确保实例ID唯一,同时统一Eureka服务地址:

spring.application.name=currency-exchange-service
server.port=8000

# 配置唯一实例ID,避免Eureka覆盖注册
spring.cloud.eureka.instance.instance-id=${spring.application.name}:${random.uuid}

# 容器内访问Eureka需用docker-compose服务名,而非localhost
eureka.client.serviceUrl.defaultZone=http://service-registry:8761/eureka

关键注意事项

  • 启动多实例必须用--scale命令,而非在单个服务下绑定多个端口。
  • 实例ID必须唯一,这是Eureka区分不同服务实例的核心标识。
  • 容器内访问其他微服务,必须使用docker-compose中定义的服务名(如service-registry),不能用localhost——因为每个容器都是独立的网络环境,localhost指向容器自身而非宿主机。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 21:53:16