Docker + Nginx 实现反向代理、负载均衡
具体实现步骤:实现 web 应用,可以是 java 或者是其它,为了方便,我这里选择 Python Flask,创建多个后端服务实例(比如 Flask 应用),一个 Nginx 容器作为负载均衡器
项目目录结构
load-balance-demo/
├── app/
│ ├── app.py # Flask 应用代码
│ └── Dockerfile # Flask 服务 Dockerfile
├── nginx/
│ ├── nginx.conf # Nginx 配置文件
│ └── Dockerfile # Nginx Dockerfile
└── docker-compose.yml # Docker Compose 配置文件
编写后端服务代码,app/app.py
from flask import Flask
import os
import logging
app = Flask(__name__)
// 添加日志 好进行请求检索
logging.basicConfig(level=logging.INFO)
@app.route('/')
def hello():
hostname = os.getenv('HOSTNAME', 'unknown')
logging.info(f"Request handled by {hostname}")
return f"Hello from {hostname}!\n"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
app/Dockerfile
FROM python:3.9-slim
WORKDIR /app
COPY app.py .
RUN pip install flask
ENV HOSTNAME=unknown
EXPOSE 5000
CMD ["python", "app.py"]
配置 Nginx,nginx/nginx.conf
upstream backend {
least_conn; # 使用最少连接数算法实现负载均衡
server app1:5000;
server app2:5000;
server app3:5000;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
nginx/Dockerfile
FROM nginx:latest
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
配置 Docker Compose,docker-compose.yml
version: "3"
services:
app1:
build: ./app
environment:
- HOSTNAME=app1
expose:
- "5000"
app2:
build: ./app
environment:
- HOSTNAME=app2
expose:
- "5000"
app3:
build: ./app
environment:
- HOSTNAME=app3
expose:
- "5000"
nginx:
build: ./nginx
ports:
- "80:80"
depends_on:
- app1
- app2
- app3
启动服务:docker-compose up --build -d
查看 docker 状态 docker ps
模拟发送并发请求
收集日志
可以看到还是很均衡的,符合 least_conn
改为轮训
ip hash 负载均衡需要多个客户端,感兴趣自己尝试
upstream backend {
ip_hash; # 使用 ip_hash 策略
server app1:5000;
server app2:5000;
server app3:5000;
}
权重负载均衡
upstream backend {
server app1:5000 weight=3; # app1 权重为 3
server app2:5000 weight=2; # app2 权重为 2
server app3:5000 weight=1; # app3 权重为 1
}