# 多实例与负载均衡 :::tip 说明 当单台服务器无法满足性能需求时,需要通过多实例部署和负载均衡来提升系统吞吐量。本文介绍本项目的水平扩展方案。 ::: ## Gunicorn 多 Worker 配置 ### Worker 数量计算 ```python # gunicorn.conf.py import multiprocessing # 推荐公式:CPU 核心数 * 2 + 1 workers = multiprocessing.cpu_count() * 2 + 1 # Worker 类型 worker_class = 'gevent' # 异步 Worker,适合 I/O 密集型 # 超时时间 timeout = 120 # 最大请求数(防止内存泄漏) max_requests = 1000 max_requests_jitter = 50 # 绑定地址 bind = '127.0.0.1:8000' ``` ### Worker 类型选择 | 类型 | 说明 | 适用场景 | |------|------|---------| | `sync` | 同步 Worker(默认) | CPU 密集型 | | `gevent` | 异步 Worker | I/O 密集型(推荐) | | `uvicorn` | ASGI Worker | 异步框架 | ## Nginx 负载均衡 ### 基础配置 ```nginx http { upstream djangoadmin { # 轮询策略(默认) server 127.0.0.1:8001; server 127.0.0.1:8002; server 127.0.0.1:8003; } server { listen 80; server_name your-domain.com; # 前端静态文件 root /opt/project/ui/dist; index index.html; location / { try_files $uri $uri/ /index.html; } # 后端 API 负载均衡 location /api/ { proxy_pass http://djangoadmin; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } } ``` ### 负载均衡策略 | 策略 | 配置 | 说明 | |------|------|------| | 轮询 | 默认 | 依次分配请求 | | 权重 | `weight=3` | 按权重分配 | | IP Hash | `ip_hash` | 同一 IP 固定到同一后端 | | 最少连接 | `least_conn` | 分配到连接数最少的后端 | ```nginx upstream djangoadmin { # 权重策略:服务器配置不同按权重分配 server 127.0.0.1:8001 weight=3; server 127.0.0.1:8002 weight=2; server 127.0.0.1:8003 weight=1; # IP Hash:需要 Session 粘性时使用 # ip_hash; # 最少连接 # least_conn; # 健康检查 server 127.0.0.1:8001 max_fails=3 fail_timeout=30s; } ``` ## JWT 无状态认证 项目使用 JWT 认证,天然支持多实例部署: ``` 用户请求 → Nginx → 任意后端实例 → 验证 JWT → 返回响应 ``` ### 为什么 JWT 适合多实例 ``` 1. 无状态:Token 自包含用户信息,无需服务端 Session 2. 无需共享存储:不需要 Redis 共享 Session 3. 任意路由:请求可以发到任意后端实例 4. 水平扩展:增加实例即可提升性能 ``` :::warning Token 黑名单 退出登录时 Token 加入 Redis 黑名单。多实例部署时,所有实例必须连接同一个 Redis,否则 Token 黑名单不生效。 ::: ## 文件存储共享 多实例部署时,上传的文件需要所有实例都能访问: ### 方案 1:NFS 共享存储 ```bash # 服务器挂载 NFS mount -t nfs storage-server:/data/uploads /opt/project/public/uploads ``` ### 方案 2:对象存储(推荐) 使用 OSS/S3/MinIO 等对象存储: ```python # 配置对象存储 DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' AWS_STORAGE_BUCKET_NAME = 'djangoadmin' AWS_S3_ENDPOINT_URL = 'http://minio:9000' ``` ### 方案 3:分布式文件系统 使用 Ceph、GlusterFS 等分布式文件系统。 ## Redis 高可用 多实例部署时,Redis 是关键的共享存储: ### Redis Sentinel ```python # 配置 Redis Sentinel CACHES = { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', 'LOCATION': 'redis://sentinel1:26379;redis://sentinel2:26379;redis://sentinel3:26379', 'OPTIONS': { 'CLIENT_CLASS': 'django_redis.client.SentinelClient', 'SENTINEL_KWARGS': {'sentinel_kwargs': {'password': 'sentinel_password'}}, 'PASSWORD': 'redis_password', } } } ``` ### Redis Cluster ```python # 配置 Redis Cluster CACHES = { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', 'LOCATION': [ 'redis://node1:6379', 'redis://node2:6379', 'redis://node3:6379', ], 'OPTIONS': { 'CLIENT_CLASS': 'django_redis.client.ClusterClient', } } } ``` ## 数据库读写分离 ### Django 配置 ```python # application/settings.py DATABASES = { 'default': { # 主库(写) 'ENGINE': 'django.db.backends.mysql', 'HOST': 'master-db', 'PORT': 3306, 'NAME': 'djangoadmin', 'USER': 'root', 'PASSWORD': 'password', }, 'replica': { # 从库(读) 'ENGINE': 'django.db.backends.mysql', 'HOST': 'replica-db', 'PORT': 3306, 'NAME': 'djangoadmin', 'USER': 'root', 'PASSWORD': 'password', }, } # 数据库路由 DATABASE_ROUTERS = ['config.db_router.MasterSlaveRouter'] ``` ### 数据库路由 ```python # config/db_router.py class MasterSlaveRouter: """主从数据库路由""" def db_for_read(self, model, **hints): return 'replica' def db_for_write(self, model, **hints): return 'default' def allow_relation(self, obj1, obj2, **hints): return True def allow_migrate(self, db, app_label, model_name=None, **hints): return db == 'default' ``` ## Supervisor 多实例配置 ```ini ; /etc/supervisor/conf.d/djangoadmin.conf [program:djangoadmin-1] command=/opt/venv/bin/gunicorn application.wsgi:application -c gunicorn.conf.py -b 127.0.0.1:8001 directory=/opt/project user=www-data autostart=true autorestart=true stdout_logfile=/var/log/djangoadmin/worker-1.log [program:djangoadmin-2] command=/opt/venv/bin/gunicorn application.wsgi:application -c gunicorn.conf.py -b 127.0.0.1:8002 directory=/opt/project user=www-data autostart=true autorestart=true stdout_logfile=/var/log/djangoadmin/worker-2.log [program:djangoadmin-3] command=/opt/venv/bin/gunicorn application.wsgi:application -c gunicorn.conf.py -b 127.0.0.1:8003 directory=/opt/project user=www-data autostart=true autorestart=true stdout_logfile=/var/log/djangoadmin/worker-3.log [group:djangoadmin] programs=djangoadmin-1,djangoadmin-2,djangoadmin-3 ``` ## 健康检查 Nginx 负载均衡需要健康检查来自动剔除故障节点: ```nginx upstream djangoadmin { server 127.0.0.1:8001 max_fails=3 fail_timeout=30s; server 127.0.0.1:8002 max_fails=3 fail_timeout=30s; server 127.0.0.1:8003 max_fails=3 fail_timeout=30s; } ``` ### 健康检查端点 ```python # application/health/views.py def health_check(request): """健康检查端点""" try: with connection.cursor() as cursor: cursor.execute("SELECT 1") return JsonResponse({"status": "healthy"}) except Exception as e: return JsonResponse({"status": "unhealthy", "error": str(e)}, status=503) ``` ## 总结 多实例与负载均衡方案涵盖 Gunicorn 多 Worker、Nginx 负载均衡、JWT 无状态认证、文件存储共享、Redis 高可用、数据库读写分离、Supervisor 多实例配置、健康检查等方面。核心原则:无状态应用 + 共享存储 + 负载均衡。