Spring Boot Actuator 显示微服务的状态已关闭
Spring Boot Actuator shows status down for microservices
我正在尝试为我的微服务添加 Eureka 服务,但是即使微服务 运行 并且消息传递正常工作,Eureka 也无法发现服务,因为它们已关闭?这是 http://localhost:8080/actuator/health
的输出
{
"status": "DOWN",
"components": {
"binders": {
"status": "UP",
"components": {
"rabbit": {
"status": "UP",
"details": {
"version": "3.7.8"
}
}
}
},
"coreServices": {
"status": "DOWN",
"details": {
"movie": {
"status": "DOWN",
"details": {
"error": "io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) failed: Connection refused: movie/172.21.0.8:80"
}
},
"reviews": {
"status": "DOWN",
"details": {
"error": "io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) failed: Connection refused: review/172.21.0.9:80"
}
},
"recommendations": {
"status": "DOWN",
"details": {
"error": "io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) failed: Connection refused: recommendation/172.21.0.6:80"
}
}
}
},
"discoveryComposite": {
"description": "Discovery Client not initialized",
"status": "UNKNOWN",
"components": {
"discoveryClient": {
"description": "Discovery Client not initialized",
"status": "UNKNOWN"
}
}
},
"diskSpace": {
"status": "UP",
"details": {
"total": 84014424064,
"free": 28400906240,
"threshold": 10485760
}
},
"ping": {
"status": "UP"
},
"rabbit": {
"status": "UP",
"details": {
"version": "3.7.8"
}
},
"reactiveDiscoveryClients": {
"description": "Discovery Client not initialized",
"status": "UNKNOWN",
"components": {
"Simple Reactive Discovery Client": {
"description": "Discovery Client not initialized",
"status": "UNKNOWN"
}
}
}
}
}
这是为什么? by 运行 docker ps 全部可用:
(base) mat@mat-Vostro-5471:~/Projects/movie-rest-services$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
376da889ce8c movie-rest-services_review "java -jar /app.jar" 23 minutes ago Up 23 minutes 8080/tcp movie-rest-services_review_1
f4fe8c2668f2 movie-rest-services_movie "java -jar /app.jar" 23 minutes ago Up 23 minutes 8080/tcp movie-rest-services_movie_1
b2fa74bdb3ea movie-rest-services_movie-composite "java -jar /app.jar" 23 minutes ago Up 23 minutes 0.0.0.0:8080->8080/tcp movie-rest-services_movie-composite_1
d45062ca4e0c movie-rest-services_recommendation "java -jar /app.jar" 23 minutes ago Up 23 minutes 8080/tcp movie-rest-services_recommendation_1
a16db364e277 movie-rest-services_eureka "java -jar /app.jar" 23 minutes ago Up 23 minutes 0.0.0.0:8761->8761/tcp movie-rest-services_eureka_1
fd6b45ade9c3 rabbitmq:3.7.8-management "docker-entrypoint.s…" 23 minutes ago Up 23 minutes (healthy) 4369/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, 15671/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp movie-rest-services_rabbitmq_1
68c9e3e92256 mongo:3.6.9 "docker-entrypoint.s…" 23 minutes ago Up 23 minutes (healthy) 0.0.0.0:27017->27017/tcp movie-rest-services_mongodb_1
2ad058b543d8 mysql:5.7 "docker-entrypoint.s…" 23 minutes ago Up 23 minutes (healthy) 0.0.0.0:3306->3306/tcp, 33060/tcp movie-rest-services_mysql_1
我的所有微服务(包括复合服务)都有 spring.application.name 和 eureka 配置设置如下:
spring.application.name: movie
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
initialInstanceInfoReplicationIntervalSeconds: 5
registryFetchIntervalSeconds: 5
instance:
leaseRenewalIntervalInSeconds: 5
leaseExpirationDurationInSeconds: 5
Eureka 服务应用程序看起来像:
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
# from: https://github.com/spring-cloud-samples/eureka/blob/master/src/main/resources/application.yml
server:
waitTimeInMsWhenSyncEmpty: 0
response-cache-update-interval-ms: 5000
management.endpoints.web.exposure.include: "*"
我正在检查微服务是启动还是关闭(我将坚持使用上面描述的电影示例):
private Mono<Health> getHealth(String url) {
url += "/actuator/health";
log.info("Will call the Health API on URL: {}", url);
return getWebClient().get().uri(url).retrieve().bodyToMono(String.class)
.map(s -> new Health.Builder().up().build())
.onErrorResume(ex -> Mono.just(new Health.Builder().down(ex).build()))
.log();
}
其中 url 是:
私人最终字符串 MOVIE_SERVICE_URL = "http://movie";
这将给出输出:
movie-composite_1 | 2020-02-11 18:03:07.251 INFO 1 --- [or-http-epoll-6] c.g.m.c.m.s.MovieCompositeIntegration : Will call the Health API on URL: http://movie/actuator/health
movie-composite_1 | 2020-02-11 18:03:07.253 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.4 : onSubscribe(FluxOnErrorResume.ResumeSubscriber)
movie-composite_1 | 2020-02-11 18:03:07.253 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.4 : request(unbounded)
movie-composite_1 | 2020-02-11 18:03:07.256 INFO 1 --- [or-http-epoll-6] c.g.m.c.m.s.MovieCompositeIntegration : Will call the Health API on URL: http://recommendation/actuator/health
movie-composite_1 | 2020-02-11 18:03:07.257 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.5 : onSubscribe(FluxOnErrorResume.ResumeSubscriber)
movie-composite_1 | 2020-02-11 18:03:07.257 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.5 : request(unbounded)
movie-composite_1 | 2020-02-11 18:03:07.260 INFO 1 --- [or-http-epoll-6] c.g.m.c.m.s.MovieCompositeIntegration : Will call the Health API on URL: http://review/actuator/health
movie-composite_1 | 2020-02-11 18:03:07.261 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.6 : onSubscribe(FluxOnErrorResume.ResumeSubscriber)
movie-composite_1 | 2020-02-11 18:03:07.261 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.6 : request(unbounded)
movie-composite_1 | 2020-02-11 18:03:07.265 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.4 : onNext(DOWN {error=io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) failed: Connection refused: movie/172.21.0.8:80})
movie-composite_1 | 2020-02-11 18:03:07.266 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.4 : onComplete()
movie-composite_1 | 2020-02-11 18:03:07.266 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.5 : onNext(DOWN {error=io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) failed: Connection refused: recommendation/172.21.0.6:80})
movie-composite_1 | 2020-02-11 18:03:07.266 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.5 : onComplete()
movie-composite_1 | 2020-02-11 18:03:07.267 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.6 : onNext(DOWN {error=io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) failed: Connection refused: review/172.21.0.9:80})
movie-composite_1 | 2020-02-11 18:03:07.273 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.6 : onComplete()
你能给我一些提示吗?
所有测试都通过了,mvn clean install 也成功了。
查看您的 docker ps
结果,movie
服务似乎正在侦听端口 8080
。
在这种情况下,您需要在 http://movie:8080/actuator/health 获得该服务。其他服务也一样!
解释:
- 每个容器将能够监听它希望的任何端口,而不会干扰其他容器或主机。例如,电影和评论服务都可以在端口 8080 上监听(与同一网络中不同 machine/VM 的行为相似)
- 为了让容器相互通信,它们需要在同一个网络中,并且其他容器需要在它们正在监听的端口到达它们,例如
movie:8080
或 review:8080
- 但是,您将无法直接从主机访问这些端口上的容器,因为您的本地主机和容器不在同一网络中。为了进行通信,您需要做一些调用端口映射,就像在您的
movie-composite
服务 0.0.0.0:8080->8080/tcp
中一样,您正在映射容器正在侦听的端口 8080
本地主机的端口 8080
。因此,您可以在浏览器 http://localhost:8080/actuator/health 上打开此 link
我正在尝试为我的微服务添加 Eureka 服务,但是即使微服务 运行 并且消息传递正常工作,Eureka 也无法发现服务,因为它们已关闭?这是 http://localhost:8080/actuator/health
的输出{
"status": "DOWN",
"components": {
"binders": {
"status": "UP",
"components": {
"rabbit": {
"status": "UP",
"details": {
"version": "3.7.8"
}
}
}
},
"coreServices": {
"status": "DOWN",
"details": {
"movie": {
"status": "DOWN",
"details": {
"error": "io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) failed: Connection refused: movie/172.21.0.8:80"
}
},
"reviews": {
"status": "DOWN",
"details": {
"error": "io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) failed: Connection refused: review/172.21.0.9:80"
}
},
"recommendations": {
"status": "DOWN",
"details": {
"error": "io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) failed: Connection refused: recommendation/172.21.0.6:80"
}
}
}
},
"discoveryComposite": {
"description": "Discovery Client not initialized",
"status": "UNKNOWN",
"components": {
"discoveryClient": {
"description": "Discovery Client not initialized",
"status": "UNKNOWN"
}
}
},
"diskSpace": {
"status": "UP",
"details": {
"total": 84014424064,
"free": 28400906240,
"threshold": 10485760
}
},
"ping": {
"status": "UP"
},
"rabbit": {
"status": "UP",
"details": {
"version": "3.7.8"
}
},
"reactiveDiscoveryClients": {
"description": "Discovery Client not initialized",
"status": "UNKNOWN",
"components": {
"Simple Reactive Discovery Client": {
"description": "Discovery Client not initialized",
"status": "UNKNOWN"
}
}
}
}
}
这是为什么? by 运行 docker ps 全部可用:
(base) mat@mat-Vostro-5471:~/Projects/movie-rest-services$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
376da889ce8c movie-rest-services_review "java -jar /app.jar" 23 minutes ago Up 23 minutes 8080/tcp movie-rest-services_review_1
f4fe8c2668f2 movie-rest-services_movie "java -jar /app.jar" 23 minutes ago Up 23 minutes 8080/tcp movie-rest-services_movie_1
b2fa74bdb3ea movie-rest-services_movie-composite "java -jar /app.jar" 23 minutes ago Up 23 minutes 0.0.0.0:8080->8080/tcp movie-rest-services_movie-composite_1
d45062ca4e0c movie-rest-services_recommendation "java -jar /app.jar" 23 minutes ago Up 23 minutes 8080/tcp movie-rest-services_recommendation_1
a16db364e277 movie-rest-services_eureka "java -jar /app.jar" 23 minutes ago Up 23 minutes 0.0.0.0:8761->8761/tcp movie-rest-services_eureka_1
fd6b45ade9c3 rabbitmq:3.7.8-management "docker-entrypoint.s…" 23 minutes ago Up 23 minutes (healthy) 4369/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, 15671/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp movie-rest-services_rabbitmq_1
68c9e3e92256 mongo:3.6.9 "docker-entrypoint.s…" 23 minutes ago Up 23 minutes (healthy) 0.0.0.0:27017->27017/tcp movie-rest-services_mongodb_1
2ad058b543d8 mysql:5.7 "docker-entrypoint.s…" 23 minutes ago Up 23 minutes (healthy) 0.0.0.0:3306->3306/tcp, 33060/tcp movie-rest-services_mysql_1
我的所有微服务(包括复合服务)都有 spring.application.name 和 eureka 配置设置如下:
spring.application.name: movie
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
initialInstanceInfoReplicationIntervalSeconds: 5
registryFetchIntervalSeconds: 5
instance:
leaseRenewalIntervalInSeconds: 5
leaseExpirationDurationInSeconds: 5
Eureka 服务应用程序看起来像:
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
# from: https://github.com/spring-cloud-samples/eureka/blob/master/src/main/resources/application.yml
server:
waitTimeInMsWhenSyncEmpty: 0
response-cache-update-interval-ms: 5000
management.endpoints.web.exposure.include: "*"
我正在检查微服务是启动还是关闭(我将坚持使用上面描述的电影示例):
private Mono<Health> getHealth(String url) {
url += "/actuator/health";
log.info("Will call the Health API on URL: {}", url);
return getWebClient().get().uri(url).retrieve().bodyToMono(String.class)
.map(s -> new Health.Builder().up().build())
.onErrorResume(ex -> Mono.just(new Health.Builder().down(ex).build()))
.log();
}
其中 url 是: 私人最终字符串 MOVIE_SERVICE_URL = "http://movie";
这将给出输出:
movie-composite_1 | 2020-02-11 18:03:07.251 INFO 1 --- [or-http-epoll-6] c.g.m.c.m.s.MovieCompositeIntegration : Will call the Health API on URL: http://movie/actuator/health
movie-composite_1 | 2020-02-11 18:03:07.253 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.4 : onSubscribe(FluxOnErrorResume.ResumeSubscriber)
movie-composite_1 | 2020-02-11 18:03:07.253 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.4 : request(unbounded)
movie-composite_1 | 2020-02-11 18:03:07.256 INFO 1 --- [or-http-epoll-6] c.g.m.c.m.s.MovieCompositeIntegration : Will call the Health API on URL: http://recommendation/actuator/health
movie-composite_1 | 2020-02-11 18:03:07.257 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.5 : onSubscribe(FluxOnErrorResume.ResumeSubscriber)
movie-composite_1 | 2020-02-11 18:03:07.257 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.5 : request(unbounded)
movie-composite_1 | 2020-02-11 18:03:07.260 INFO 1 --- [or-http-epoll-6] c.g.m.c.m.s.MovieCompositeIntegration : Will call the Health API on URL: http://review/actuator/health
movie-composite_1 | 2020-02-11 18:03:07.261 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.6 : onSubscribe(FluxOnErrorResume.ResumeSubscriber)
movie-composite_1 | 2020-02-11 18:03:07.261 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.6 : request(unbounded)
movie-composite_1 | 2020-02-11 18:03:07.265 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.4 : onNext(DOWN {error=io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) failed: Connection refused: movie/172.21.0.8:80})
movie-composite_1 | 2020-02-11 18:03:07.266 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.4 : onComplete()
movie-composite_1 | 2020-02-11 18:03:07.266 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.5 : onNext(DOWN {error=io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) failed: Connection refused: recommendation/172.21.0.6:80})
movie-composite_1 | 2020-02-11 18:03:07.266 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.5 : onComplete()
movie-composite_1 | 2020-02-11 18:03:07.267 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.6 : onNext(DOWN {error=io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) failed: Connection refused: review/172.21.0.9:80})
movie-composite_1 | 2020-02-11 18:03:07.273 INFO 1 --- [or-http-epoll-6] reactor.Mono.OnErrorResume.6 : onComplete()
你能给我一些提示吗? 所有测试都通过了,mvn clean install 也成功了。
查看您的 docker ps
结果,movie
服务似乎正在侦听端口 8080
。
在这种情况下,您需要在 http://movie:8080/actuator/health 获得该服务。其他服务也一样!
解释:
- 每个容器将能够监听它希望的任何端口,而不会干扰其他容器或主机。例如,电影和评论服务都可以在端口 8080 上监听(与同一网络中不同 machine/VM 的行为相似)
- 为了让容器相互通信,它们需要在同一个网络中,并且其他容器需要在它们正在监听的端口到达它们,例如
movie:8080
或review:8080
- 但是,您将无法直接从主机访问这些端口上的容器,因为您的本地主机和容器不在同一网络中。为了进行通信,您需要做一些调用端口映射,就像在您的
movie-composite
服务0.0.0.0:8080->8080/tcp
中一样,您正在映射容器正在侦听的端口8080
本地主机的端口8080
。因此,您可以在浏览器 http://localhost:8080/actuator/health 上打开此 link