把无状态服务扩到多实例
docker compose 可以用缩放参数把无状态服务扩到多实例,一条命令就让服务从一份变成多份。前提有两个:服务不能绑定固定的宿主端口,否则第二个实例直接端口冲突;Compose 本身不提供负载均衡,多实例的流量分发要交给外部代理或服务发现来完成。
基本信息
| 命令 | docker compose up -d --scale 服务名=数量 |
|---|---|
| 实例命名 | 带序号,例如 web-1、web-2、web-3 |
| 端口前提 | 去掉宿主端口发布,或把流量交给上层代理转发 |
| 负载均衡 | 需外部代理或依赖容器网络的 DNS 轮询 |
| 缩容方式 | 改小数字再执行 up,多余实例被回收 |
| 不适用对象 | 有状态服务如数据库不要缩放 |
典型使用场景
- 本地验证多实例行为,暴露共享状态与并发问题
- 压测时临时扩容,测试水平伸缩能力
- 无状态 Web 服务水平扩容以承接更高流量
- 与外部反向代理配合,验证负载分发是否符合预期
- 缩容验证优雅停止与连接回收是否正常
使用示例
使用示例
docker compose up -d --scale web=3 # 扩到 3 个实例
docker compose ps web # 查看实例与状态
docker compose logs --tail 20 web-2 # 看指定实例的日志
docker compose up -d --scale web=1 # 缩容,多余实例被回收
docker compose ps -a # 确认没有残留实例前提与检查
| 前提 | 检查方式 | 不满足的后果 |
|---|---|---|
| 不绑定宿主端口 | 看服务定义里是否写了端口映射 | 第二个实例直接启动失败 |
| 服务无状态 | 确认服务不写本地数据 | 多实例各写各的,数据分叉 |
| 共享数据挂卷 | 需要共享的内容挂到同一卷 | 实例间数据不一致 |
| 有流量分发 | 存在外部代理或服务发现 | 只有一个实例真正承载流量 |
| 下游容量充足 | 检查连接池与配额 | 扩容后把下游压垮 |
缩容只需改小数字再执行 up:多余实例会被回收。有状态服务(数据库、消息队列)不要缩放,多实例各写各的卷会造成不可逆的数据分叉,恢复时无从对齐。
带宿主端口映射的服务无法缩放:第二个实例启动时会因端口被占用直接失败。报错信息指向端口占用,容易被误判为宿主资源或环境问题,实际原因在服务定义里。