Docker部署HAProxy时出现503 Service Unavailable错误求助
我是HAProxy新手,尝试通过Docker多实例运行Python FastAPI服务(服务监听8090端口),并使用HAProxy实现负载均衡。
初始正常配置
docker-compose.yml
version : '3' services: elb: image: haproxy ports: - "8100:8100" volumes: - ./haproxy:/usr/local/etc/haproxy pythonapp1: image: my-python-service:0.0.1 ports: - "8090:8090"
haproxy.cfg
# haproxy.cfg frontend http bind *:8100 mode http timeout client 10s use_backend all backend all mode http server s1 pythonapp1:8090
执行docker compose up后,访问http://localhost:8100一切正常。
添加实例后出现错误
修改后的docker-compose.yml:
version : '3' services: elb: image: haproxy ports: - "8100:8100" volumes: - ./haproxy:/usr/local/etc/haproxy pythonapp1: image: craft-text-detection-python-service:0.0.1 ports: - "8090:8090" pythonapp2: image: craft-text-detection-python-service:0.0.1 ports: - "8091:8090"
修改后的haproxy.cfg:
# haproxy.cfg frontend http bind *:8100 mode http timeout client 10s use_backend all backend all mode http server s1 pythonapp1:8090 server s2 pythonapp2:8091
执行docker compose up后,首次访问http://localhost:8100正常,再次访问则出现503 Service Unavailable错误。请问这是端口设置问题还是其他原因?
问题原因
核心错误是HAProxy后端配置的端口错误。Docker Compose服务间通信使用的是容器内部的端口,而非映射到宿主机的端口。你的FastAPI服务在容器内监听的是8090端口,所以HAProxy访问pythonapp2时应该用pythonapp2:8090,而非宿主机映射的8091。
另外,你将pythonapp1的镜像名改为craft-text-detection-python-service:0.0.1,若本地无该镜像,Docker会尝试拉取,可能导致服务启动延迟或失败,但这不是引发503的主因。
修正方案
1. 修正haproxy.cfg后端配置
添加健康检查规则,确保HAProxy只向正常服务转发请求:
# haproxy.cfg frontend http bind *:8100 mode http timeout client 10s use_backend all backend all mode http # 配置HTTP健康检查,需配合FastAPI的健康接口 option httpchk GET /health timeout server 10s server s1 pythonapp1:8090 check server s2 pythonapp2:8090 check
option httpchk GET /health:指定健康检查的接口路径check:为每个后端服务启用健康检查,自动剔除故障实例
2. 优化docker-compose.yml
服务间通信无需映射宿主机端口(除非需要单独测试实例),同时添加依赖确保HAProxy在服务启动后初始化:
version : '3' services: elb: image: haproxy ports: - "8100:8100" volumes: - ./haproxy:/usr/local/etc/haproxy depends_on: - pythonapp1 - pythonapp2 pythonapp1: image: craft-text-detection-python-service:0.0.1 pythonapp2: image: craft-text-detection-python-service:0.0.1
3. 添加FastAPI健康检查接口
在你的FastAPI代码中新增健康检查路由:
from fastapi import FastAPI app = FastAPI() @app.get("/health") async def health_check(): return {"status": "healthy"} # 你的其他业务接口...
4. 重启服务
停止现有容器并重新启动:
docker compose down docker compose up --build
完成以上修改后,HAProxy会正确将请求分发到两个正常运行的FastAPI实例,不会再出现503错误。
内容的提问来源于stack exchange,提问作者Zaryab Ali

