解决 WebAPI 在容器中的启动初始化问题(不是最佳方案)

在产品或项目的部署中,如果和下面场景类似,那么本文可能对您有所帮助。
场景
1、WebAPI 和 MySql 数据部署在同一服务器(通常是测试环境);
2、WebAPI 和 MySql 使用 docker-compose 进行部署;
3、WebAPI 启动时有一些初始化的操作要做,而初始化需要从 MySql 中获取数据。
问题
1、第一次部署,执行 docker-compose up -d 后,WebAPI 不能正常启动;
2、断电、或其他原因导致的服务器重启或 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 的服务是否启动。所以,这种配置只能控制容器的启动顺序,并不能解决问题。
解决
要解决这个问题,有两种方式:
1、在 WebAPI 项目中使用 Polly 库,它是一个 .NET 的弹性和瞬态故障处理库,可以实现重试、断路器、超时等策略来处理网络请求失败的情况。可以使用 Polly 来尝试连接 mysql 服务,并在失败时进行重试或等待。
2、优化 depends_on 配置。
本文着重介绍的是第二种方式,进行 depends_on 配置的优化。
优化思路
1、mysql 服务添加 healthcheck 检查,用来判断 mysql 的服务是否正常启动;
2、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/Shangha解决 WebAPI 在容器中的启动初始化问题(不是最佳方案)
声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。如若本站内容侵犯了原著者的合法权益,可联系本站删除。



