Apache Python 集成 #
WSGI 概述 #
什么是 WSGI? #
text
┌─────────────────────────────────────────────────────────────┐
│ WSGI 概念 │
├─────────────────────────────────────────────────────────────┤
│ │
│ WSGI (Web Server Gateway Interface) │
│ Python Web 应用的标准接口 │
│ │
│ 作用: │
│ ├── 统一 Web 服务器与 Python 应用的通信 │
│ ├── 解耦服务器和应用框架 │
│ └── 支持多种框架(Django、Flask 等) │
│ │
│ 架构: │
│ ┌─────────┐ WSGI ┌─────────────┐ │
│ │ Apache │ ◄──────────► │ Python 应用 │ │
│ │mod_wsgi │ │ Django/Flask│ │
│ └─────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
mod_wsgi 模式 #
text
┌─────────────────────────────────────────────────────────────┐
│ mod_wsgi 运行模式 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Embedded Mode(嵌入式) │
│ ├── Python 解释器嵌入 Apache 进程 │
│ ├── 性能较好 │
│ ├── 共享 Apache 进程 │
│ └── 适合简单应用 │
│ │
│ Daemon Mode(守护进程) │
│ ├── 独立的 Python 进程 │
│ ├── 进程隔离 │
│ ├── 可配置进程数量 │
│ ├── 支持不同用户权限 │
│ └── 推荐用于生产环境 │
│ │
└─────────────────────────────────────────────────────────────┘
安装 mod_wsgi #
Ubuntu/Debian #
bash
# 安装 mod_wsgi
sudo apt install libapache2-mod-wsgi-py3
# 启用模块
sudo a2enmod wsgi
sudo systemctl restart apache2
# 验证安装
apache2ctl -M | grep wsgi
CentOS/RHEL #
bash
# 安装 mod_wsgi
sudo yum install mod_wsgi
# 重启 Apache
sudo systemctl restart httpd
# 验证安装
httpd -M | grep wsgi
使用 pip 安装 #
bash
# 安装 mod_wsgi
pip install mod_wsgi
# 查看配置
mod_wsgi-express module-config
# 输出示例
# LoadModule wsgi_module "/usr/local/lib/python3.10/site-packages/mod_wsgi/server/mod_wsgi-py310.cpython-310-x86_64-linux-gnu.so"
# WSGIPythonHome "/usr/local"
基础 WSGI 配置 #
简单 WSGI 应用 #
python
# /var/www/wsgi/app.wsgi
def application(environ, start_response):
status = '200 OK'
output = b'Hello, World from WSGI!'
response_headers = [
('Content-type', 'text/plain'),
('Content-Length', str(len(output)))
]
start_response(status, response_headers)
return [output]
Apache 配置 #
apache
# ============================================
# 基础 WSGI 配置
# ============================================
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/wsgi
# WSGI 脚本别名
WSGIScriptAlias / /var/www/wsgi/app.wsgi
# WSGI 脚本目录权限
<Directory /var/www/wsgi>
Require all granted
</Directory>
# 日志
ErrorLog ${APACHE_LOG_DIR}/wsgi-error.log
CustomLog ${APACHE_LOG_DIR}/wsgi-access.log combined
</VirtualHost>
Daemon 模式配置 #
基础 Daemon 配置 #
apache
# ============================================
# WSGI Daemon 模式配置
# ============================================
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/app
# 配置守护进程组
WSGIDaemonProcess myapp \
python-path=/var/www/app \
python-home=/var/www/app/venv \
processes=2 \
threads=15 \
maximum-requests=10000 \
user=www-data \
group=www-data
# 将应用分配到守护进程组
WSGIProcessGroup myapp
# WSGI 脚本
WSGIScriptAlias / /var/www/app/app.wsgi
<Directory /var/www/app>
WSGIProcessGroup myapp
WSGIApplicationGroup %{GLOBAL}
Require all granted
</Directory>
</VirtualHost>
WSGIDaemonProcess 参数 #
text
┌─────────────────────────────────────────────────────────────┐
│ WSGIDaemonProcess 参数 │
├─────────────────────────────────────────────────────────────┤
│ │
│ processes=N 进程数量 │
│ threads=N 每个进程的线程数 │
│ maximum-requests=N 请求上限后重启进程 │
│ user=USER 运行用户 │
│ group=GROUP 运行组 │
│ python-path=PATH Python 模块搜索路径 │
│ python-home=PATH Python 虚拟环境路径 │
│ socket-user=USER Unix 套接字用户 │
│ socket-group=GROUP Unix 套接字组 │
│ socket-mode=MODE Unix 套接字权限 │
│ display-name=NAME 进程显示名称 │
│ inactivity-timeout=N 空闲超时(秒) │
│ deadlock-timeout=N 死锁超时(秒) │
│ graceful-timeout=N 优雅关闭超时(秒) │
│ queue-timeout=N 队列超时(秒) │
│ request-timeout=N 请求超时(秒) │
│ │
└─────────────────────────────────────────────────────────────┘
Flask 应用部署 #
Flask 应用结构 #
text
/var/www/flaskapp/
├── app/
│ ├── __init__.py
│ ├── views.py
│ └── models.py
├── venv/
├── app.wsgi
└── requirements.txt
Flask 应用代码 #
python
# /var/www/flaskapp/app/__init__.py
from flask import Flask
app = Flask(__name__)
from app import views
python
# /var/www/flaskapp/app/views.py
from app import app
@app.route('/')
def index():
return 'Hello, Flask!'
@app.route('/api/data')
def data():
return {'message': 'Hello, API!'}
WSGI 入口文件 #
python
# /var/www/flaskapp/app.wsgi
import sys
import os
# 添加应用路径
sys.path.insert(0, '/var/www/flaskapp')
# 激活虚拟环境
activate_this = '/var/www/flaskapp/venv/bin/activate_this.py'
with open(activate_this) as file_:
exec(file_.read(), dict(__file__=activate_this))
# 导入应用
from app import app as application
Apache 配置 #
apache
# ============================================
# Flask 应用配置
# ============================================
<VirtualHost *:80>
ServerName flaskapp.example.com
DocumentRoot /var/www/flaskapp
# WSGI 守护进程
WSGIDaemonProcess flaskapp \
python-path=/var/www/flaskapp \
python-home=/var/www/flaskapp/venv \
processes=2 \
threads=15 \
user=www-data \
group=www-data
WSGIProcessGroup flaskapp
WSGIScriptAlias / /var/www/flaskapp/app.wsgi
<Directory /var/www/flaskapp>
WSGIProcessGroup flaskapp
WSGIApplicationGroup %{GLOBAL}
Require all granted
</Directory>
# 静态文件
Alias /static /var/www/flaskapp/app/static
<Directory /var/www/flaskapp/app/static>
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/flaskapp-error.log
CustomLog ${APACHE_LOG_DIR}/flaskapp-access.log combined
</VirtualHost>
Django 应用部署 #
Django 应用结构 #
text
/var/www/djangoapp/
├── myproject/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── myapp/
├── static/
├── media/
├── venv/
└── requirements.txt
Django WSGI 配置 #
python
# /var/www/djangoapp/myproject/wsgi.py
import os
import sys
from django.core.wsgi import get_wsgi_application
# 添加项目路径
sys.path.insert(0, '/var/www/djangoapp')
# 设置 Django 配置模块
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
application = get_wsgi_application()
Apache 配置 #
apache
# ============================================
# Django 应用配置
# ============================================
<VirtualHost *:80>
ServerName djangoapp.example.com
ServerAdmin webmaster@example.com
# WSGI 守护进程
WSGIDaemonProcess djangoapp \
python-path=/var/www/djangoapp:/var/www/djangoapp/venv/lib/python3.10/site-packages \
python-home=/var/www/djangoapp/venv \
processes=2 \
threads=15 \
maximum-requests=5000 \
user=www-data \
group=www-data
WSGIProcessGroup djangoapp
WSGIScriptAlias / /var/www/djangoapp/myproject/wsgi.py
# WSGI 脚本目录
<Directory /var/www/djangoapp/myproject>
WSGIProcessGroup djangoapp
WSGIApplicationGroup %{GLOBAL}
<Files wsgi.py>
Require all granted
</Files>
</Directory>
# 静态文件
Alias /static/ /var/www/djangoapp/static/
<Directory /var/www/djangoapp/static>
Require all granted
</Directory>
# 媒体文件
Alias /media/ /var/www/djangoapp/media/
<Directory /var/www/djangoapp/media>
Require all granted
</Directory>
# 日志
ErrorLog ${APACHE_LOG_DIR}/djangoapp-error.log
CustomLog ${APACHE_LOG_DIR}/djangoapp-access.log combined
</VirtualHost>
Django settings.py 配置 #
python
# /var/www/djangoapp/myproject/settings.py
# 允许的主机
ALLOWED_HOSTS = ['djangoapp.example.com', 'localhost']
# 静态文件
STATIC_URL = '/static/'
STATIC_ROOT = '/var/www/djangoapp/static/'
# 媒体文件
MEDIA_URL = '/media/'
MEDIA_ROOT = '/var/www/djangoapp/media/'
# 调试模式(生产环境关闭)
DEBUG = False
# 安全设置
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = 'DENY'
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
多应用配置 #
多个 WSGI 应用 #
apache
# ============================================
# 多个 WSGI 应用配置
# ============================================
<VirtualHost *:80>
ServerName example.com
# 应用 1
WSGIDaemonProcess app1 python-path=/var/www/app1 processes=2 threads=10
WSGIScriptAlias /app1 /var/www/app1/app.wsgi
<Location /app1>
WSGIProcessGroup app1
</Location>
# 应用 2
WSGIDaemonProcess app2 python-path=/var/www/app2 processes=2 threads=10
WSGIScriptAlias /app2 /var/www/app2/app.wsgi
<Location /app2>
WSGIProcessGroup app2
</Location>
<Directory /var/www/app1>
Require all granted
</Directory>
<Directory /var/www/app2>
Require all granted
</Directory>
</VirtualHost>
性能优化 #
进程和线程配置 #
apache
# ============================================
# 性能优化配置
# ============================================
# 高并发配置
WSGIDaemonProcess myapp \
processes=4 \
threads=25 \
maximum-requests=10000 \
deadlock-timeout=60 \
inactivity-timeout=300
# 低内存配置
WSGIDaemonProcess myapp \
processes=2 \
threads=10 \
maximum-requests=5000
# CPU 密集型
WSGIDaemonProcess myapp \
processes=8 \
threads=5 \
maximum-requests=5000
# I/O 密集型
WSGIDaemonProcess myapp \
processes=2 \
threads=50 \
maximum-requests=10000
守护进程组共享 #
apache
# 共享守护进程组
WSGIDaemonProcess shared processes=2 threads=15
<VirtualHost *:80>
ServerName app1.example.com
WSGIProcessGroup shared
WSGIScriptAlias / /var/www/app1/app.wsgi
</VirtualHost>
<VirtualHost *:80>
ServerName app2.example.com
WSGIProcessGroup shared
WSGIScriptAlias / /var/www/app2/app.wsgi
</VirtualHost>
调试技巧 #
启用调试日志 #
apache
# 启用 WSGI 调试日志
LogLevel wsgi:trace3
# 在 WSGI 脚本中
import logging
logging.basicConfig(filename='/var/log/wsgi-debug.log', level=logging.DEBUG)
常见问题 #
text
┌─────────────────────────────────────────────────────────────┐
│ 常见问题 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 模块导入错误 │
│ 检查 python-path 配置 │
│ 确认虚拟环境路径 │
│ │
│ 2. 权限问题 │
│ 检查 user/group 配置 │
│ 确认文件权限 │
│ │
│ 3. 静态文件 404 │
│ 检查 Alias 配置 │
│ 确认目录权限 │
│ │
│ 4. 内存泄漏 │
│ 设置 maximum-requests │
│ 监控进程内存 │
│ │
│ 5. 超时问题 │
│ 调整 request-timeout │
│ 检查应用性能 │
│ │
└─────────────────────────────────────────────────────────────┘
下一步 #
掌握了 Python 集成后,继续学习 Docker 部署,了解如何使用 Docker 部署 Apache!
最后更新:2026-03-29