Django 项目生产部署
Django 项目在生产环境的部署涉及多个步骤:
- 配置 Django 设置
- 使用 WSGI/ASGI 应用服务器
- 配置 Nginx
- 启用 HTTPS
- 使用生产数据库
- 管理服务。
使用以上一般步骤来确保项目可以正常地运行在生产环境中。
项目结构
project/
│
├── backend/ # 后端代码目录
│ ├── backend/ # 后端同名应用
│ │ ├── __init__.py
│ │ ├── asgi.py
│ │ ├── settings.py
│ │ ├── urls.py
│ │ ├── wsgi.py
│ │ └── ...
│ ├── app/ # 后端应用代码
│ │ ├── migrations/ # 数据库迁移文件
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── models.py
│ │ ├── urls.py
│ │ ├── views.py
│ │ ├── tasks.py
│ │ └── ...
│ ├── conf/ # 后端配置文件
│ │ ├── cert/ # SSL 证书
│ │ ├── supervisor/ # supervisor 配置文件
│ │ ├── uwsgi.ini # uWSGI 配置文件
│ │ └── ...
│ ├── settings/ # 不同环境配置文件
│ │ └── common.py # 基础配置模块
│ │ └── development.py # 开发环境配置
│ │ └── production.py # 生成环境配置
│ ├── static/ # 静态资源
│ │ └── ...
│ ├── requirements.txt # Python 依赖文件
│ ├── Dockerfile # 后端 Dockerfile
│ ├── manage.py # Django 管理脚本
│ └── ...
│
├── docs/ # 项目文档
│ ├── architecture.md # 架构文档
│ └── ...
│
├── .gitignore # Git 忽略文件
├── docker-compose.yml # Docker Compose 配置文件
└── README.md # 项目说明文件
本例 Django 项目中,前端页面使用的是 Django 渲染模板,主要涉及后端内容的部署。
上线环境配置
使用 settings.py
分环境模块
将 settings.py
拆分为多个文件,例如 common.py
、development.py
和 production.py
,并在每个环境配置文件中配置不同内容。
settings/common.py
定义在开发和生产之间共同的基本设置。settings/development.py
定义开发环境的配置内容。settings/production.py
定义生产环境的配置内容。
参考: https://developer.mozilla.org/zh-CN/docs/Learn/Server-side/Django/Deployment
DEBUG
设置
确保在生产环境中 DEBUG
为 False
,以避免泄露调试信息。
DEBUG = False
ALLOWED_HOSTS
设置
使用 *
允许所有主机名访问,但在生产环境中最好指定具体的主机名或 IP 地址。
ALLOWED_HOSTS = ['*']
或
ALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com']
安全配置
# HSTS 确保浏览器只通过 HTTPS 连接到项目网站
SECURE_HSTS_SECONDS = 3600
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
# SSL 重定向,自动将所有 HTTP 请求重定向到 HTTPS
SECURE_SSL_REDIRECT = True
# 防止浏览器对相应内容类型嗅探
SECURE_CONTENT_TYPE_NOSNIFF = True
# 启用浏览器 XXS 过滤器
SECURE_BROWSER_XSS_FILTER = True
# 启用安全 Cookie 确保仅通过 HTTPS 传输
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
# 点击劫持保护
X_FRAME_OPTIONS = 'DENY'
settings.py
相关cookie
和ssl
安全设置会迫使http
请求重定向到https
。HSTS(HTTP Strict Transport Security)
配置根据需求,可以将SECURE_HSTS_SECONDS
设置更长时间(例如一年)。X_FRAME_OPTIONS
:点击劫持保护,禁止其他网站通过iframe
嵌入自己的项目网页,防止点击劫持攻击。
敏感信息
在 Django 项目中使用 .env
文件来集中管理环境变量,并通过 python-dotenv
库将其加载到环境中。
生成密钥 SECRET_KEY
:
首先,为确保 SECRET_KEY
密钥的安全性,使用如下 Python 脚本生成随机且唯一的密钥:
import secrets
def generate_secret_key(length=50):
return secrets.token_urlsafe(length)
print(generate_secret_key())
安装 python-dotenv
:
pipenv install python-dotenv
创建 .env
文件:
将所有敏感信息存储在环境变量中,避免硬编码。例如配置安全密钥、数据库用户名和密码等。
# .env file
## 使用 python-dotenv 包读取环境变量
## DJANGOSETTINGSMODULE 设置为 settings.development 或 settings.production
# 调试开发环境
DJANGO_SETTINGS_MODULE='settings.development'
## 部署生产环境
#DJANGOSETTINGSMODULE='settings.production'
# 使用根目录的 utils.py 中的 getenv 函数生成密钥粘贴此处
SECRET_KEY='gPi5ie7KAYhR5s7YuemgJHIKMgA5p9jxnG_VuUS32H5-JylowuXbXXtz4K179pcUCyg'
# 数据库用户名和密码
DB_USER='xxx'
DB_PASS='123456'
注意:
.env
文件不被上传到版本控制系统(如 Git),通常通过.gitignore
忽略。
加载 .env
文件:
在项目的 settings
文件(本例 settings/production.py
)中加载 .env
存储的环境变量:
import os
from dotenv import load_dotenv
# 加载 .env 文件中的环境变量
load_dotenv()
# 从环境变量中获取配置
SECRET_KEY = os.getenv('SECRET_KEY')
DB_USER = os.getenv('DB_USER')
DB_PASS = os.getenv('DB_PASS')
REDIS_AUTH = os.getenv('REDIS_AUTH')
if not SECRET_KEY or not DB_USER or not DB_PASS or not REDIS_AUTH:
raise ValueError('Missing one or more required environment variables.')
注意:使用环境变量时应小心敏感信息的泄露,确保环境变量的访问权限是受保护的。
安全管理
应避免将环境变量文件或敏感信息上传到版本控制系统(如 Git)中。在 .gitignore
中添加如下内容:
.env
database/db.sqlite3
logs/nginx/*
logs/uwsgi/*
!logs/nginx/.gitkeep
!logs/uwsgi/.gitkeep
安全测试
运行命令检查,以确保没有遗漏的安全设置。
python manage.py check --deploy
静态文件配置项
Django 项目有一些 CSS、JavaScript 等静态文件分散在项目的各个应用中,为了方便让 Nginx 处理对这些静态文件的请求,把项目中的全部静态文件收集到一个统一的目录,即项目的根目录,命名为 static
。
# 其他配置...
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_ROOT
是用于生产环境,指定了collectstatic
命令将静态文件集中到的目录。STATICFILES_DIRS
是用于开发环境,指定了额外的静态文件目录供 Django 查找。
为了在开发和生产环境中使用不同的 settings.py
配置文件,接下来更新 manage.py
和 uwsgi.py
文件内容。
manage.py
项目管理
动态加载 Django 配置,提供一个易于管理的项目入口点,以支持不同环境(开发、生产)使用不同的配置。
from dotenv import load_dotenv
# 加载 .env 文件中的环境变量
load_dotenv()
settings_module = os.getenv('DJANGO_SETTINGS_MODULE')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', settings_module)
# 其他代码
backend/wsgi.py
设置环境
一个 WSGI 兼容的 Web 服务器网关接口文件。用于将 Django 项目运行在 WSGI 兼容 Web 服务器上,如 Apache、Nginx 等。
在后端项目同名应用下的 wsgi.py
接口文件中更新配置:通过 dotenv
加载 .env
文件中的环境变量,动态配置 Django 项目的 DJANGO_SETTINGS_MODULE
环境变量。
from dotenv import load_dotenv
# 加载 .env 文件中的环境变量
load_dotenv()
settings_module = os.getenv('DJANGO_SETTINGS_MODULE')
# os.environ.setdefault('DJANGOSETTINGSMODULE', 'backend.settings')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', settings_module)
# 其他代码
安装 MySQL
开发环境调试使用的是 Django 框架自带的的 SQLite3,生产环境使用 MySQL 关系数据库。
要安装MySQL需要先到MySQL官方网站下载对应的RPM文件,选择适合项目和系统的版本。
本例,为兼容项目和 CentOS 9 系统使用 MySQL 版本:8.0.39
。
MySQL 数据库解压,安装需要的组件:
rpm -ivh mysql-community-common-8.0.39-1.el9.x86_64.rpm && \
rpm -ivh mysql-community-libs-8.0.39-1.el9.x86_64.rpm && \
rpm -ivh mysql-community-debuginfo-8.0.39-1.el9.x86_64.rpm && \
rpm -ivh mysql-community-client-debuginfo-8.0.39-1.el9.x86_64.rpm && \
rpm -ivh mysql-community-client-plugins-8.0.39-1.el9.x86_64.rpm && \
rpm -ivh mysql-community-client-8.0.39-1.el9.x86_64.rpm && \
rpm -ivh mysql-community-icu-data-files-8.0.39-1.el9.x86_64.rpm && \
rpm -ivh mysql-community-server-8.0.39-1.el9.x86_64.rpm && \
rpm -ivh mysql-community-devel-8.0.39-1.el9.x86_64.rpm
启动数据库服务,进入数据库中,创建项目使用的数据库用户信息:
CREATE USER '用户名'@'%' IDENTIFIED BY '密码';
Django 项目安装三方库:
pipenv install mysqlclient
Django 中配置数据库连接:
DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'database', 'db.sqlite3'),
# }
'default': {
# 数据库引擎配置
'ENGINE': 'django.db.backends.mysql',
# 数据库的名称
'NAME': 'blog',
# 数据库服务器的 IP 地址(如果是本机,可以配置成 localhost 或 127.0.0.1)
'HOST': '101.34.xxx.xxx',
# 启动 MySQL 服务的端口号
'PORT': 3306,
# 数据库用户名和口令
'USER': DB_USER,
'PASSWORD': DB_PASS,
# 数据库使用的字符集
'CHARSET': 'utf8mb4',
# 数据库时间日期的时区设定
'TIME_ZONE': 'Asia/Chongqing',
# 设置连接最大存活时间(例如 600 秒,0 表示无连接池,None 表示永久连接)
'CONN_MAX_AGE': 600,
}
}
若使用购买的云服务器,可能需要开启 3306 端口(若数据库部署与项目程序不在同一主机上,还需要管控 IP 地址)。
安装 Python
如果需要清除旧版本的安装,删除对应的安装的文件夹即可。
rm -rf /usr/local/python38/
下载:
wget https://www.python.org/ftp/python/3.9.13/Python-3.9.13.tar.xz
参考 [[../../Linux/Python 源码编译安装|Python 源码编译安装]]
部署代码
安装 pipenv
:
pip3 install pipenv
注意:通过
pipenv shell
激活虚拟环境,然后执行操作。
获取 pipenv
虚拟环境路径:
# pipenv --venv
/root/.local/share/virtualenvs/backend-2ZtQ7vfC
拉取远程仓库:
git clone git@github.com:littlekj/helloBlog.git
进入项目根目录,安装项目依赖:
pipenv install --deploy --ignore-pipfile
--deploy
表示“部署”模式,在此模式下,pipenv
只根据Pipfile.lock
文件安装依赖。如果Pipfile.lock
文件不匹配或丢失,安装将失败。--ignore-pipfile
表示pipenv
忽略Pipfile
,只根据Pipfile.lock
安装依赖。
检查环境:
为 Pipfile.lock
文件存在且是最新的,如果更新 Pipfile.lock
,运行命令:
pipenv lock
进入后端项目根目录,进行数据库迁移:
pipenv run python manage.py migrate
创建管理员账户:
pipenv run python manage.py createsuperuser
收集静态文件:
# 收集静态文件
pipenv run python manage.py collectstatic
Django 框架项目使用 Python Manager.py runserver
启动服务用于开发测试,不建议用于生产环境。所以,生产环境的应用使用 WSGI 服务器托管启动。
配置应用服务器
在 Django 项目部署中,WSGI(Web Server Gateway Interface)是常用的接口标准。它定义了 Web 服务器与 Web 应用之间的通信方式,提供了一种将 Web 应用与服务器或中间件连接起来处理请求的规范。
uWSGI 是一个高性能的 WSGI 应用服务器,常用于托管 Python Web 应用程序,专门处理动态内容(应用的逻辑)。它支持多种应用程序协议、服务模型和部署选项。
uWSGI 配置文件可以是用 INI
文件格式,通常文件扩展名为 .ini
。配置文件包含了服务器的运行时配置选项,如应用路径、端口、进程数等。
安装 uWSGI:
pipenv install uwsgi
项目 uWSGI 配置文件:
在后端项目中编辑 uWSGI 配置文件 conf/uwsgi.ini
:
[uwsgi]
# 配置前导路径,通常是项目的根目录
base=/usr/local/share/helloBlog/backend
# 项目名称,用于指代应用
name=backend
# 指定 uWSGI 启动时的工作目录
chdir=%(base)
# 指定 WSGI 应用模块,格式为’模块名:应用名‘
module=%(name).wsgi:application
# 启动守护进程模式,将 uWSGI 置于后台运行
master=true
# 设置进程数,通常 CPU 核心数的 2 到 4倍
processes=4
# 指定 PID 文件的位置,便于进程管理
pidfile=/run/uwsgi.pid
# 退出时自动清理 Unix 套接字和 PID 文件
vacuum=true
# 设置每个工作进程处理的最大请求数,超过会重启该进程
max-requests=5000
# 启用 thunder lock,优化多进程环境下的锁性能
thunder-lock = true
# 启用线程支持,如果应用程序依赖线程则需要启用
enable-threads = true
# 指定监听队列的长度
listen = 120
# 处理更大的请求数据块
buffer-size = 32768 # 增加缓冲区大小
harakiri = 60 # 设置超时时间
post-buffering = 4096 # 处理较大 POST 数据块
# 使用非 root 用户运行 uWSGI,提高安全性
#uid=www-data
#gid=www-data
# 设置 Python 虚拟环境的路径
pythonhome=/root/.local/share/virtualenvs/backend-2ZtQ7vfC
# 指定通信的地址和端口,格式为‘IP:端口’
# 如果使用 Unix 套接字,格式为‘socket=/tmp/uwsgi.sock’
socket=127.0.0.1:8000
# 将日志输出到指定文件
logto=%(base)/logs/uwsgi/uwsgi.log
# 或让 uWSGI 进程在后台运行并记录日志
#daemonize=%(base)/logs/uwsgi/uwsgi-daemon.log
- 设置监听队列,uWSGI 文档
- 设置缓冲区大小以处理更大的请求数据块。
- 可以使用其他用户
www-data
以安全的方式运行,赋予权限:
chown -R www-data:www-data /path/to/your/project
chown www-data:www-data /path/to/your/uwsgi.sock
chown www-data:www-data /path/to/your/logs
启动 uWSGI 服务器
可略过,后续使用 Supervisor 管理服务进程。
安装 nohup 工具:
yum install coreutils
启动服务器:
进入后端项目根目录执行:
nohup uwsgi --ini conf/uwsgi.ini -b 65535 > logs/uwsgi.log 2>&1 &
nohup
是一个工具,用于在后台运行命令并忽略挂起信息。nohup
允许uWSGI
进程在用户注销或中断关闭后继续运行,适用于生产环境。-b 65535
设置请求的缓冲区大小。> uwsgi.log 2>&1
将标准输出和标准错误重定向到uwsgi.log
文件。不指定输出文件,nohup
默认输出重定向到nohup.out
。- 使用
&
符号将进程放到后台运行。
参考 uWSGI 文档、如何使用 WSGI 部署 Django 项目
配置 Web 服务器
在现代 Web 架构中,Nginx 作为反向代理服务器代表后端应用服务器处理客户端请求,它位于目标服务器的前端,处理客户端发来的请求,并将请求转发给相应的内部服务器。
uWSGI 和 Nginx 实现项目的动静分离,Nginx 可以处理静态文件请求,动态请求则转发给 uWSGI。Nginx 和 uWSGI 通过 uWSGI 协议或 HTTP 协议进行高效的通信,分离职责,可以最大化性能。
Nginx 和 uWSGI 之间常用 uWSGI 协议或 HTTP 协议。uWSGI 协议比 HTTP 更高效,是推荐的选择。
安装 Nginx
yum install nginx
配置 Nginx
修改全局配置文件(/etc/nginx/nginx.conf
):
# 配置用户
user nginx;
# 工作进程数(建议跟CPU的核数量一致)
worker_processes auto;
# 错误日志
error_log /var/log/nginx/error.log;
# 进程文件
pid /run/nginx.pid;
# 加载动态模块配置
include /usr/share/nginx/modules/*.conf;
# 工作模式(多路IO复用方式)和连接上限
events {
use epoll; # `epoll` 是一种 I/O 事件通知机制,提供处理高并发请求的效率
worker_connections 1024;
}
# HTTP服务器相关配置
http {
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 访问日志
access_log /var/log/nginx/access.log main;
# 开启高效文件传输模式
sendfile on;
# 用sendfile传输文件时有利于改善性能
tcp_nopush on;
# 禁用Nagle来解决交互性问题
tcp_nodelay on;
# 客户端保持连接时间
keepalive_timeout 65;
# MIME类型配置的最大哈希大小
types_hash_max_size 4096;
# 包含MIME类型的配置
include /etc/nginx/mime.types;
# 默认使用二进制流格式
default_type application/octet-stream;
# 加载模块化配置
include /etc/nginx/conf.d/*.conf;
# 包含项目的Nginx配置文件
#include /usr/local/share/helloBlog/backend/conf/*.conf;
client_header_buffer_size 2k;
large_client_header_buffers 4 8k;
client_max_body_size 2m;
# HTTP 服务器配置
server {
listen 80;
listen [::]:80;
server_name example.com 101.34.xxx.xxx; # 指定处理请求的域名或 IP 地址,建议使用域名
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
# 处理主页面请求
location / {# 匹配所有请求路径
include uwsgi_params;
uwsgi_pass 127.0.0.1:8000; # uWSGI socket 地址
}
# 处理静态文件请求
location /static/ {
alias /usr/local/share/helloBlog/backend/static/; # 静态文件存储路径
expires 30d; # 缓存静态文件 30 天
}
# 日志文件配置
access_log /usr/local/share/helloBlog/backend/logs/nginx/access.log;
error_log /usr/local/share/helloBlog/backend/logs/nginx/error.log;
}
# 将 HTTP 请求重定向到 HTTPS
#location / {
# return 301 https://$host$request_uri;
#}
# HTTPS 服务器配置
server {
listen 443 ssl http2; # 在 HTTPS 中启用 HTTP/2,以提高性能
listen [::]:443 ssl http2;
server_name example.com 101.34.xxx.xxx; # 指定处理请求的域名或 IP 地址
# SSL 配置
ssl_certificate /usr/local/share/helloBlog/backend/conf/cert/zone.example.com_bundle.crt;
ssl_certificate_key /usr/local/share/helloBlog/backend/conf/cert/zone.example.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384';
ssl_prefer_server_ciphers on;
include /etc/nginx/default.d/*.conf;
# 处理所有路径的请求
location / {
include uwsgi_params; # 包含与 uWSGI 服务器通信所需的标准参数
uwsgi_pass 127.0.0.1:8000; # uWSGI socket 地址
}
# 处理静态文件请求
location /static/ {
alias /usr/local/share/helloBlog/backend/static/; # 静态文件存储路径
expires 30d; # 缓存静态文件 30 天
}
# 日志文件配置
access_log /usr/local/share/helloBlog/backend/logs/nginx/access.log;
error_log /usr/local/share/helloBlog/backend/logs/nginx/error.log;
}
}
说明:
server_name
可以指定域名或公网 IP,让所有来自该域名或 IP 地址的请求被 Nginx 服务处理。location /
:是 Nginx 配置的规则,/
是通用匹配所有以/
开头的请求路径。include uwsgi_params;
: 包含了与 uWSGI 服务器通信所需的标准参数。uwsgi_params
包括了与 uWSGI 服务器进行交互所需的 HTTP 请求头和参数。uwsgi_pass 127.0.0.1:8000;
将请求转发到127.0.0.1:8000
,即本地回环地址上的 uWSGI 服务器。- Nginx 中使用回环地址将请求转发到本机上的 uWSGI 实例。它是安全的,避免外部访问直接到 uWSGI 的端口,使所有请求都必须经过 Nginx,从而运行 Nginx 进行额外的处理和安全控制。
- 相应地,如果 uWSGI 服务器仅绑定在
127.0.0.1
上,并且没有绑定到外部接口(如0.0.0.0
),那么外部用户将无法直接访问这个端口。它只能监听本地 Nginx 访问。
location /static/
:这个块处理所有以/static/
开头的 URL 请求。- 浏览器请求,Nginx 接收请求,匹配
location /static/
块。 - Nginx 在配置参数
alias
对应路径上寻找静态资源。Nginx 将其返回给浏览器,完成静态资源的加载访问。 - Nginx 直接处理静态文件的请求,而不经过 Web 应用服务器,从而减轻其负担,并加速静态资源的传输。
- 浏览器请求,Nginx 接收请求,匹配
确保已创建自定义日志路径:
mkdir -p /usr/local/share/helloBlog/backend/logs/nginx
mkdir -p /usr/local/share/helloBlog/backend/logs/uwsgi
HTTPS 加密配置
网站部署建议使用 HTTPS 加密访问,可以到相关网站申请域名,国内服务器需要备案;然后使用 openssl
自签名配置 SSL 证书,或在域名网站生成 SSL 证书,存放在 Nginx 配置文件指定的路径。
网站访问
公网 IP(Public IP)是指你在互联网上的唯一地址,它允许其他设备或服务从全球范围内访问你的服务器或计算机。
在 Linux 系统下,公网 IP 可以通过 curl
命令获取。
获取公网 IPv4
# curl -s https://ipinfo.io/ip
101.34.xxx.xxx
注意:若开启了代理服务,获取的公网 IP 一般会有变化。
防火墙设置
确保服务器的防火墙允许相关端口的流量:HTTP (80)、HTTPS (443) 和 MySQL (3306) 等。
负载均衡
当服务器性能不佳时,可以部署多个后端应用服务器,使用 Nginx 的负载均衡器,将请求分发到指定的后端应用服务器,并根据权重进行负载均衡。
修改 nginx.conf
配置(未验证):
# 配置用户
user nginx;
# 工作进程数(建议跟CPU的核数量一致)
worker_processes auto;
# 错误日志
error_log /var/log/nginx/error.log;
# 进程文件
pid /run/nginx.pid;
# 包含其他的配置
include /usr/share/nginx/modules/*.conf;
# 工作模式(多路IO复用方式)和连接上限
events {
use epoll; # `epoll` 是一种 I/O 事件通知机制,提供处理高并发请求的效率
worker_connections 1024;
}
# HTTP服务器相关配置
http {
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 访问日志
access_log /var/log/nginx/access.log main;
# 开启高效文件传输模式
sendfile on;
# 用sendfile传输文件时有利于改善性能
tcp_nopush on;
# 禁用Nagle来解决交互性问题
tcp_nodelay on;
# 客户端保持连接时间
keepalive_timeout 65;
# MIME类型配置的最大哈希大小
types_hash_max_size 4096;
# 包含MIME类型的配置
include /etc/nginx/mime.types;
# 默认使用二进制流格式
default_type application/octet-stream;
# 包含其他配置文件
include /etc/nginx/conf.d/*.conf;
# 包含项目的Nginx配置文件
#include /usr/local/share/helloBlog/backend/conf/*.conf;
# 负载均衡配置
upstream backend {
server 192.168.1.100 weight=2; # 后端应用服务器 1,权重为 2
server 192.168.1.101 weight=1; # 后端应用服务器 2,权重为 1
server 192.168.1.102 weight=1; # 后端应用服务器 3,权重为 1
}
# HTTP 服务器配置
server {
listen 80;
server_name 101.34.xxx.xxx example.com; # 指定处理请求的IP地址或域名
# 将 HTTP 请求重定向到 HTTPS
location / {
return 301 https://$host$request_uri;
}
}
# HTTPS 服务器配置
server {
listen 443 ssl http2; # 在 HTTPS 中启用 HTTP/2,以提高性能
server_name 101.34.xxx.xxx example.com; # 指定处理请求的域名或 IP 地址
# SSL 配置
ssl_certificate /usr/local/share/helloBlog/backend/conf/cert/cert.pem;
ssl_certificate_key /usr/local/share/helloBlog/backend/conf/cert/key.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384';
ssl_prefer_server_ciphers on;
# 日志文件配置
access_log /usr/local/share/helloBlog/backend/logs/access.log;
error_log /usr/local/share/helloBlog/backend/logs/error.log;
# 处理主页面请求
location / {
include uwsgi_params;
uwsgi_pass http://backend; # 使用负载均衡池
}
# 处理静态文件请求
location /static/ {
alias /usr/local/share/helloBlog/backend/static/; # 静态文件存储路径
expires 30d; # 缓存静态文件 30 天
}
}
}
说明:
- 负载均衡配置:在
http
部分添加upstream backend
,定义了负载均衡池backend
。server
指令用于指定后端服务器静态 IP 地址或 DNS 名称及其权重。 - HTTPS 服务器中更新
uwsgi_pass
为http://backend
,将请求转发到负载均衡池。这样,HTTPS 请求将通过负载均衡池转发到不同的后端服务器。
管理服务进程
Supervisor 是一个进程控制系统,用于在 Unix-like
系统中启动、停止和管理进程。利用 supervisorctl
,可以方便地管理进程,确保相关服务可以在控制系统启动时自动启动,并且在崩溃时自动重启。
虚拟环境中安装:
pipenv install supervisor
Supervisor 配置:
Supervisor 的主配置文件通常位于 /etc/supervisord.conf
。
Pip 方式安装的默认配置文件不存在,通过以下命令生成一个默认配置文件:
echo_supervisord_conf > /etc/supervisord.conf
编辑 /etc/supervisord.conf
,设置 include
目录以包含自定义的 .ini
配置文件。
例如:
vim /etc/supervisord.conf
[include]
;files = relative/directory/*.ini
files = supervisord.d/*.ini
创建程序配置文件:
在 /etc/supervisord.d
目录下创建程序自定义配置文件,例如, /etc/supervisord.d/myapp.ini
:
[program:uwsgi]
command=/root/.local/share/virtualenvs/backend-2ZtQ7vfC/bin/uwsgi --ini /usr/local/share/helloBlog/backend/conf/uwsgi.ini
stopsignal=QUIT
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/supervisor/supervisor.log
[program:elasticsearch]
command=/opt/elasticsearch/bin/elasticsearch
autostart=true
autorestart=true
stderr_logfile=/var/log/supervisor/elasticsearch.err.log
stdout_logfile=/var/log/supervisor/elasticsearch.out.log
user=elasticuser
[program:uwsgi]
定义了一个名为uwsgi
的程序块。使用supervisorctl
命令来管理这个进程。- 运行
uwsgi
以启动 Web 项目应用服务器,使用指定的uwsgi.ini
配置文件。 stopsignal=QUIT
指定发送给进程的信号以停止程序。autostart=true
表示 Supervisor 启动时会自动启动此程序。autorestart=true
表示程序如果崩溃,Supervisor 会自动重启它。redirect_stderr=true
表示将标准错误输出重定向到标准输出日志文件中。将错误和输出日志合并到一个文件。stderr_logfile
指定错误日志文件的路径。如果redirect_stderr=true
,这个设置通常不会被使用。stdout_logfile
指定标准输出日志文件的路径。如果redirect_stderr=true
,错误日志会被合并到这个文件中。
- 运行
启动 Supervisor 服务:
如果添加了 systemd
服务单元,可以通过如下命令启动:
systemctl start supervisord
或者直接运行程序命令启动:
supervisord -c /etc/supervisord.conf
启动 Supervisor 服务后,会默认启动管理在
/etc/supervisord.conf
中设置的所有进程。
使用 Supervisor 控制进程:
启动所有程序:
supervisorctl start all
- 停止进程:
stop
,查看状态:status
,重启进程:restart
。
管理多个服务程序:
# supervisorctl
elasticsearch RUNNING pid 1836532, uptime 22:58:41
uwsgi RUNNING pid 1836533, uptime 22:58:41
supervisor> status
elasticsearch RUNNING pid 1836532, uptime 22:59:15
uwsgi RUNNING pid 1836533, uptime 22:59:15
supervisor> stop uwsgi
uwsgi: stopped
supervisor> status
elasticsearch RUNNING pid 1836532, uptime 23:00:10
uwsgi STOPPED Nov 23 08:27 PM
supervisor> start uwsgi
uwsgi: started
supervisor>
站点访问
一切准备就绪后,启动 Web 服务器、应用服务器、数据库及相关服务进程,即可通过域名访问站点内容。