解决 WebAPI 在容器中的启动初始化问题
source link: https://www.51cto.com/article/760450.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
解决 WebAPI 在容器中的启动初始化问题
在产品或项目的部署中,如果和下面场景类似,那么本文可能对您有所帮助。
- WebAPI 和 MySql 数据部署在同一服务器(通常是测试环境)。
- WebAPI 和 MySql 使用 docker-compose 进行部署。
- WebAPI 启动时有一些初始化的操作要做,而初始化需要从 MySql 中获取数据。
- 第一次部署,执行 docker-compose up -d 后,WebAPI 不能正常启动。
- 断电、或其他原因导致的服务器重启或 docker 重启,WebAPI 不能正常启动。
- docker 容器启动时,WebAPI 程序启动的速度比 MySql 快,导致程序去连接 MySql 时,MySql 服务器还没有启动完成,自然是连不上。
在 docker-compose.yml 文件中可以添加 depends_on 来设置依赖,如下:
api:
restart: always
image: netapi
ports:
- "5000:5000"
environment:
- TZ=Asia/Shanghai
depends_on:
- mysql
networks:
s2_net:
ipv4_address: 172.66.9.5
在 api 的 depends_on 设置 mysql ,表示 api 依赖 mysql ,只有当 mysql 启动后,api 才会启动。
但很可惜,这里的 mysql 启动指的是 mysql 的容器是否启动了,而不是 mysql 的服务是否启动。所以,这种配置只能控制容器的启动顺序,并不能解决问题。
要解决这个问题,有两种方式:
- 在 WebAPI 项目中使用 Polly 库,它是一个 .NET 的弹性和瞬态故障处理库,可以实现重试、断路器、超时等策略来处理网络请求失败的情况。可以使用 Polly 来尝试连接 mysql 服务,并在失败时进行重试或等待。
- 优化 depends_on 配置。
本文着重介绍的是第二种方式,进行 depends_on 配置的优化。
- mysql 服务添加 healthcheck 检查,用来判断 mysql 的服务是否正常启动。
- api 服务的 depends_on 监听这个检查,只有当 mysql 服务正常启动后,api 才会启动。
完整 docker-compose.yml
version: "3"
networks:
s2_net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.66.9.0/24
services:
mysql:
restart: always
image: mysql/mysql-server:latest
ports:
- "3306:3306"
environment:
- TZ=Asia/Shanghai
- MYSQL_ROOT_PASSWORD=123456
healthcheck:
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "root", "--password=123456"]
interval: 3s
timeout: 5s
retries: 3
start_period: 5s
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --default-authentication-plugin=mysql_native_password
networks:
s2_net:
ipv4_address: 172.66.9.2
api:
restart: always
image: netapi
ports:
- "5000:5000"
environment:
- TZ=Asia/Shanghai
depends_on:
mysql:
condition: service_healthy
networks:
s2_net:
ipv4_address: 172.66.9.5
mysql 服务中添加 healthcheck 属性,子属性解释如下:
- test:设置健康检查的命令。
- interval:定义健康检查的间隔时间,上面配置为间隔 3 秒。
- timeout:健康检查的超时时间。
- retries:定义了健康检查失败后的重试次数。
- start_period:默认值为 0 秒,表示容器启动后立即进行健康检查。如果将 start_period 设置为非零值,则 Docker 会在容器启动后先等待一段时间,然后再开始进行健康检查。
api 服务的配置为固定写法。
如果您的 docker-compose 安装的是 1.27 以下的版本,需要升级到 1.27 或以上版本。
因为 docker-compose 3 不支持 depends_on 的条件设置, 但从 1.27.0 开始,2.x 和 3.x 与 COMPOSE_SPEC 架构合并,版本现在是兼容的。
可以使用下面命令进行 docker-compose 版本的查看:
docker-compose -v
安装 docker-compose 可以使用下面命令:
curl -L https://github.com/docker/compose/releases/download/1.28.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
升级到 1.28.0 后,执行 docker-compose 的命令时可能会出现错误,错误提示如下:
[29250] Error loading Python lib '/tmp/_MEIYmY20a/libpython3.9.so.1.0': dlopen: /lib64/libc.so.6: version `GLIBC_2.28' not found (required by /tmp/_MEIYmY20a/libpython3.9.so.1.0)
按照提示 google 下,会有很多方式解决,或者直接参考这个链接:https://blog.csdn.net/wangying202/article/details/113178159。
在 docker-compose 中进行设置是一种偷懒的做法,适用于测试环境,因为生产环境程序和数据库通常在不同的服务器。
最好的方式还是应该在 WebAPI 程序中进行处理。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK