7.3 多服务部署实战:网关、应用与数据库的一次交付


7.3 多服务部署实战:网关、应用与数据库的一次交付

本节摘要:实战课。把网关(nginx)、应用(自建镜像)、数据库(postgres)三服务组成可交付的项目:写文件、处理启动竞态、跑通健康检查、执行滚动重建与数据迁移演练。全流程只敲 compose 命令,前六部的词条在本节完成一次总集结。

实战背景交代清楚再动手:交付目标是单机上的订单演示系统——nginx 做网关转发请求,应用容器跑业务逻辑,postgres 存数据。硬性要求有三项:数据库端口不暴露到宿主机(陆部纪律)、数据在 down 之后保留(伍部纪律)、应用必须等数据库真正就绪再启动(本节新学)。三项要求分别对应文件里的一组配置,一边写一边对号。

部署拓扑:谁连谁,谁暴露谁

部署拓扑:谁连谁,谁暴露谁

交付单:完整文件与逐条对账

services: web: image: nginx:1.25 ports: - "8080:80" volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro depends_on: - api api: build: ./api environment: - DB_HOST=db - DB_PASSWORD=secret depends_on: db: condition: service_healthy db: image: postgres:16 environment: - POSTGRES_PASSWORD=secret volumes: - pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 3s retries: 6 volumes: pgdata:

对账:ports 只出现在 web(唯一出口);api 连 db 用服务名(陆部 DNS);db 数据挂命名卷(伍部);api 对 db 的依赖带 service_healthy(7.1 的就绪组合)。网关转发的目标写的也是服务名 api——Compose 网络里它可解析。

施工现场:起、验、改、收

$ docker compose up -d --build [+] Building 34.2s (12/12) FINISHED ✔ Network ordershop_default Created ✔ Volume "ordershop_pgdata" Created ✔ Container ordershop-db-1 Healthy ✔ Container ordershop-api-1 Started ✔ Container ordershop-web-1 Started $ curl -s localhost:8080/api/orders {"orders": []}

输出里 Healthy 一行是关键剧情:db 先跑完健康检查,api 才被放行——没有这层等待,api 连库必然失败,重试日志刷屏。curl 拿到空订单列表,链路(网关到应用到库)全程贯通。验证数据持久性:

$ docker compose exec api sh -c 'wget -qO- --post-data="{\"city\":\"hangzhou\"}" \ --header="Content-Type: application/json" localhost:9000/api/orders' >/dev/null $ docker compose down $ docker compose up -d $ curl -s localhost:8080/api/orders {"orders": [{"city": "hangzhou"}]}

down 再 up,刚录的订单还在——pgdata 卷的功劳,伍部词条在实战里的第一次验货。改版本上线的滚动流程:

$ sed -i 's/RETURN city/RETURN city, id/' api/query.py $ docker compose up -d --build ✔ Container ordershop-api-1 Recreated ✔ Container ordershop-web-1 Running

只有 api 被 Recreated,网关与数据库全程无感——增量重建让"改应用不动基建"成为默认行为。要是这次改动引入了坏配置,服务起不来怎么办?ps 看状态、logs 看死因、修好再 up,命令都是旧熟人;实在要回滚,改回文件再 up 即可,声明式的回滚就是"声明改回去"。

⚠️ 常见坑:healthcheck 的 interval 与 retries 要给数据库冷启动留足时间——postgres 首次初始化要建目录建用户,配得过紧(如重试后再短间隔)会让 api 在 db 尚未就绪时就被判失败。演示项目每五秒探一次、允许六次失败是稳妥起点,生产按真实冷启动耗时放大。

延伸现场:只动一个服务与看全局

多服务项目的日常操作很少全量重来,精确制导才是常态:

$ docker compose ps NAME SERVICE STATUS ordershop-web-1 web Running ordershop-api-1 api Running ordershop-db-1 db Running (healthy) $ docker compose restart api $ docker compose up -d --build api

compose ps 自带服务归属与健康态,名字短、口径与项目一致,比裸 docker ps 顺手;restart 单独揉某个服务;up 指定服务名则只重建它(依赖关系照常满足)。看日志同理:logs -f api 只跟应用流,比全项目日志混流清爽——排错先锁服务、再锁时间窗,是柒部日志功夫的基本功。

交付前的最后一遍对账交给 config:

$ docker compose config --quiet && echo OK OK

--quiet 只验不显,配合 shell 的 && 正好接进发布脚本:解析不过就地停下,解析过了才放行后续步骤。三条硬性要求、一套起验改收、两招精确制导,多服务部署的现场动作至此齐备。

本节要点回顾

  • 唯一出口原则:ports 只给网关,其余服务全靠网内名字互访。
  • 就绪靠组合拳:healthcheck 声明加 service_healthy 依赖,根治"应用比库先起"。
  • down 不删卷:一个轮回后数据仍在,交付演示与真实运维共享这条纪律。
  • 增量重建是日常发布:改谁重建谁,回滚就是把声明改回去。
  • 三条硬性要求各有一组配置:交付前逐条对账,比事后排查便宜得多。

到这里,单机上的容器工程已经闭环。但生产现场总有意外——捌部排错与治理部,专治各种不服。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U