Spring Boot微服务通过API网关访问端点出现503服务不可用错误
错误信息
{ "timestamp": "2024-06-24T14:01:32.938+00:00", "path": "/departments", "status": 503, "error": "Service Unavailable", "requestId": "1a88ca39-1" }
问题描述
所有服务已容器化,表面运行正常,但通过API网关访问端点返回503错误。Eureka注册中心仅注册了API网关,department-service、employee-service、project-service均未注册,推测核心问题是业务服务未正确从config-server获取配置,导致无法注册到Eureka,进而网关无法定位服务实例。
相关配置文件
服务注册中心(Eureka)配置
server: port: 8761 spring: application: name: service-registry eureka: client: register-with-eureka: false fetch-registry: false serviceUrl: defaultZone: http://service-registry:8761/eureka/
API网关配置
server: port: 8060 eureka: client: serviceUrl: defaultZone: http://service-registry:8761/eureka/ spring: application: name: api-gateway cloud: gateway: routes: - id: employee-service uri: lb://employee-service predicates: - Path=/employees/** - id: department-service uri: lb://department-service predicates: - Path=/departments/** - id: project-service uri: lb://project-service predicates: - Path=/projects/**
Department服务本地配置
spring: application: name: department-service config: import: "optional:configserver:http://config-server:8088"
Employee和Project服务配置与Department一致,仅
spring.application.name不同
Config Server配置
server: port: 8088 spring: application: name: config-server profiles: active: native cloud: config: server: native: search-locations: classpath:/config
Config Server中Department服务的配置
eureka: client: serviceUrl: defaultZone: http://service-registry:8761/eureka/ spring: application: name: department-service datasource: url: jdbc:jdbc:postgresql://postgres:5432/microservice_comp_data username: postgres password: password driver-class-name: org.postgresql.Driver jpa: hibernate: ddl-auto: update show-sql: true properties: hibernate: format_sql: true database: postgresql database-platform: org.hibernate.dialect.PostgreSQLDialect server: error: include-message: always port: 8081 management: tracing: sampling: probability: 1.0
Employee和Project服务在Config Server中的配置与Department一致,仅
spring.application.name和server.port不同
Docker Compose配置
version: '3.8' services: config-server: build: context: ./config-server ports: - "8088:8088" service-registry: build: context: ./service-registry ports: - "8761:8761" depends_on: - config-server department-service: build: context: ./department-service ports: - "8081:8081" environment: SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/microservice_comp_data SPRING_DATASOURCE_USERNAME: postgres SPRING_DATASOURCE_PASSWORD: password depends_on: - service-registry - postgres employee-service: build: context: ./employee-service ports: - "8082:8082" environment: SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/microservice_comp_data SPRING_DATASOURCE_USERNAME: postgres SPRING_DATASOURCE_PASSWORD: password depends_on: - department-service project-service: build: context: ./project-service ports: - "8083:8083" environment: SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/microservice_comp_data SPRING_DATASOURCE_USERNAME: postgres SPRING_DATASOURCE_PASSWORD: password depends_on: - employee-service api-gateway: build: context: ./api-gateway ports: - "8060:8060" depends_on: - service-registry postgres: image: postgres:latest container_name: postgres-container environment: POSTGRES_DB: microservice_comp_data POSTGRES_USER: postgres POSTGRES_PASSWORD: password ports: - "5431:5432" zipkin: image: openzipkin/zipkin ports: - "9411:9411"
问题原因与修复步骤
1. 配置加载容错导致问题隐藏
业务服务配置中使用optional:configserver:,意味着config-server不可达时服务会忽略配置加载失败直接启动,不会抛出错误,但此时服务缺少Eureka注册配置,无法完成注册。
修复:移除optional:,强制服务从config-server获取配置,加载失败时直接报错,便于定位问题:
spring: config: import: "configserver:http://config-server:8088"
2. Docker依赖未考虑服务就绪状态
depends_on仅保证容器启动顺序,不保证服务内部初始化完成。可能出现service-registry容器启动了,但Eureka服务尚未就绪,此时业务服务启动时无法连接Eureka,注册失败。
修复:
- 为业务服务添加启动等待逻辑,比如使用
wait-for-it脚本等待service-registry的8761端口就绪后再启动服务,需在服务Dockerfile中加入该脚本:department-service: # 其他配置不变 command: ["./wait-for-it.sh", "service-registry:8761", "--", "java", "-jar", "app.jar"] - 调整所有业务服务的
depends_on,直接依赖config-server和service-registry,而非其他业务服务。
3. Config Server中数据库URL错误
Config Server里Department的数据库URL多写了一个jdbc:,导致数据库连接失败,服务启动异常,无法完成Eureka注册。
修复:修正数据库URL:
spring: datasource: url: jdbc:postgresql://postgres:5432/microservice_comp_data
4. 业务服务缺少Eureka客户端依赖
如果业务服务的依赖文件(pom.xml/build.gradle)中未引入Eureka Client依赖,即使配置了Eureka地址,也无法完成注册。
修复:添加Eureka Client依赖:
- Maven:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
- Gradle:
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
5. 业务服务依赖链不合理
当前employee-service依赖department-service、project-service依赖employee-service,导致前序服务启动失败时后续服务也无法正常启动,且无必要。
修复:调整Docker Compose中业务服务的depends_on,改为直接依赖service-registry、postgres和config-server:
employee-service: # 其他配置不变 depends_on: - service-registry - postgres - config-server project-service: # 其他配置不变 depends_on: - service-registry - postgres - config-server
内容的提问来源于stack exchange,提问作者Pangkey

