java - 如何理解 spring boot 应用程序已准备好工作?

标签 java spring docker spring-boot docker-compose

我在 spring 上有几个微服务。其中之一是配置服务器。我尝试使用 docker-compose 一起启动服务。但是有问题。微服务尝试在配置服务器初始化之前从配置服务器获取配置。我想为微服务的启动编写脚本以防止误启动。我现在必须知道如何确定我的配置服务器准备就绪的时刻。端口监听不起作用。 Docker 隐藏了有关其网络的信息。我相信有比标准输出解析更好的方法。

有人知道我如何确定 spring boot 应用程序启动的时间吗?

最佳答案

Does somebody know how i can determine time of spring boot application starting?

当它从 /health 端点返回代码 200 时,您的应用程序必须准备就绪,并带有这样的有效负载

{
  "status": "UP"
}

这意味着您的应用程序没有问题并且可以正常工作,无论如何,此端点通常由监视应用程序使用以了解您的应用程序健康状况,以便它可以维护集群,其他应用程序不常用此端点, 这个显示器一般

  • 使用该端点了解您的应用程序何时准备好接收世界请求,这样它就可以将您的应用程序注册到一个公共(public)地址
  • /health 返回 DOWN 状态时,尝试重新启动该应用程序,希望它能解决问题

看看docker healthcheck ,它使用了与spring相同的概念

要使该端点可用,您需要添加 spring actuator 依赖项,这是一个 gradle 示例

compile group: 'org.springframework.boot', name: 'spring-boot-starter-actuator', version: '1.5.10.RELEASE'

Microservices try to get configs from config server before it had been initialized ....

这里有一些要点要明确

  • 除非您使用 depends_on,否则 Docker compose 不会授予启动顺序子句,无论如何 docker 永远不会等到第一个容器完全启动(使用健康检查的事件)然后启动第二个容器
  • 如果您的微服务A依赖微服务B,那么A必须准备好处理B故障和不可用,这是一个微服务前提,因为它会在某一天甚至更糟的时候发生,在它不应该发生的意外时刻。 config-server 稍后重启会怎样?从属应用会发生什么情况?

所以我的建议是让您的应用程序在尝试从配置服务器 应用程序获取信息时失败,如果失败您可以做一些事情:

  • 做一些重试 using spring-retry例如
  • 如果你能处理一些临时的配置服务器不可用,那么我的建议是add a custom check在你的 /health 中将这些信息暴露给一些监控微服务
  • 如果您的应用程序在没有配置服务器 的情况下无法工作,那么只需调用System.exit(-1) 并让docker-compose restart your application一次又一次,直到配置服务器回答一些有用的问题

这里是一些模拟您的案例并使用 docker 解决的紧凑示例

  • 配置服务器
  • 应用-1

config-server 将比 app-1 花费更长的时间准备好,然后 app-1 将保持不健康 直到 config-server 正确响应

version: '3.4'
services:
  mg-config-server:
    image: nginx:1.10
    healthcheck:
      test: ["CMD", "bash", "-c", "sleep 15; exit 0"]
      interval: 10s
      timeout: 17s
      retries: 3
      start_period: 10s
    networks:
      - my-net
    command: bash -c "echo starting; sleep 20; nginx -g 'daemon off;'"

  mg-app-1:
    image: alpine:3.7
    healthcheck:
      test: ["CMD", "curl", "http://mg-config-server"]
      interval: 5s
      timeout: 5s
      retries: 3
      start_period: 1s
    command: sh -c 'echo starting; apk add --update curl; tail -f /dev/null'
    restart: always
    networks: 
      - my-net
    dns:
    - 8.8.8.8

networks:
  my-net:
    driver: overlay

那就开始吧

docker-compose up
docker ps | grep "mg" 

无论如何,在这种情况下使用 docker swarm 更有意义,因为它会检查健康检查端点并在不健康时重新启动容器

docker swarm init --advertise-addr <your-machine-ip>
docker stack deploy --compose-file docker-compose.yml my-stack && docker ps | grep "my-stack"

Docker 版本:18.02.0-ce

抱歉回答太长,希望对您有所帮助

关于java - 如何理解 spring boot 应用程序已准备好工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50340169/

相关文章:

java - Android API 从 27 降级到 21 后出现错误 (KOTLIN)

java - Apache Camel + RabbitMQ。端点未创建

node.js - 文件更改后 Docker Compose 容器中的 node_modules 为空

Java-Spring反射带来了类中不存在的方法

python - Docker 健康检查总是返回不健康状态

docker - 在 GCP 上的 Google 容器优化操作系统上禁用容器自动启动

Java Unicode 变量名

java - 重新排列 ArrayList 的顺序

java - Hibernate OrphanRemoval 仅从关系表中删除数据

database - 错误 Jparepository java.lang.IllegalArgumentException