如果对你有帮助希望点赞收藏~
转载请注明出处~
欢迎批评、指点、讨论~
https://blog.csdn.net/L_Open2021/article/details/129901741
1.问题描述
在微服务项目中,多容器之间存在相关依赖的关系。
B容器启动时会调用A容器部分接口,所以存在B容器会由于A容器而启动失败的情况
2.问题解决
方法1:通过 **depends_on **结合 **healthcheck **实现容器顺序启动(强烈推荐!)
例:webB容器依赖了webA容器
先来看docker-compose
services:
webA:
restart: always
environment:
MYSQL_PWD: 123456
container_name: webA
image: webA
healthcheck:
# http://localhost:4000/health 为webA容器指定的健康检查接口
test: ["CMD", "curl", "-f", "http://localhost:4000/health"]
# 健康检查的间隔,默认为 30 秒,单位(h/m/s);
interval: 30s
# 健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,单位(h/m/s);
timeout: 20s
# 当连续失败指定次数后,则将容器状态视为 unhealthy。
retries: 5
webB:
restart: always
environment:
MYSQL_PWD: 123456
container_name: webB
image: webB
# webA容器之后启动,并且webA容器的健康状态为healthy
depends_on:
webA:
condition: service_healthy
webB容器启动前会根据webA容器的健康状态来判断是否启动,而webA容器的健康状态根据设定的healthcheck中指定的心跳监测接口来确定
服务调用关系是 **webA **-> webB,我们的服务由于存在token校验机制,就算服务启动成功了,直接调用 [ip:端口]还是会失败【curl: (22) The requested URL returned error: 424】
所以在webA服务中增加了一个开放的可以绕过token校验的接口用于服务心跳监测,从而判断健康状态
当webA服务启动时会自动监测健康状态,直到确认为unhealthy时,bgi服务会启动失败
实际案例(顺序 upms -> bgi -> thingsboard):
失败时:
等待状态:
成功状态:
方案2:shell脚本弹窗被依赖(较复杂)
思路:在容器启动命令执行之前,跑一个shell脚本,通过shell nc 端口探测被依赖容器来确定被依赖的容器是否ready,随后再去启动后者。
1. 直接手写shell脚本,通过 nc 端口探测。
2. github上的一个开源项目 wait-for-it,拆箱即用
方案3:通过Docker file 设置延时启动(不推荐,伪顺序)
思路:根据服务实际启动时间,对每个服务进行合理的延时时间分配
版权归原作者 孤卷者 所有, 如有侵权,请联系我们删除。