Flask应用迁移至Apache WSGI后无法启用多进程的问题求助
Hey there! Let's break down how to get your Flask app running with multiple processes under Apache mod_wsgi, and tackle those CPU overload issues you're facing.
The most likely reason you're stuck with a single process is using Apache's embedded mode for mod_wsgi, which ties your app directly to Apache's own worker processes and limits scaling control. Instead, use daemon mode—this lets you explicitly configure how many processes/threads your app uses, independent of Apache's core settings.
Update your VirtualHost configuration like this:
<VirtualHost *:80> ServerName your-domain.com # Define the daemon process pool WSGIDaemonProcess myapp user=www-data group=www-data processes=8 # Match your 8-core CPU for full hardware utilization threads=15 # Adjust based on your app's I/O vs CPU balance; 10-20 is typical python-path=/var/www/app-server:/path/to/your/virtualenv/lib/pythonX.X/site-packages # Tell Apache to use this daemon pool for your app WSGIProcessGroup myapp # Point to your WSGI file WSGIScriptAlias / /var/www/app-server/APPNAME.wsgi <Directory /var/www/app-server> Require all granted </Directory> # Optional: Serve static files directly from Apache (faster than Flask) Alias /static /var/www/app-server/static <Directory /var/www/app-server/static> Require all granted </Directory> </VirtualHost>
processes=8: Since you have an 8-core CPU, setting this to match your core count will let you fully leverage your hardware—critical for CPU-heavy workloads like your parsing app.python-path: Include your app directory and virtual environment's site-packages (if used) to avoid import errors.
If you prefer not to use daemon mode (not recommended for CPU-heavy Python apps), adjust Apache's Multi-Processing Module (MPM) settings to spawn more worker processes:
- Check which MPM you're using:
apache2ctl -M | grep mpm - If using
mpm_prefork(common for embedded mode), edit/etc/apache2/mods-available/mpm_prefork.conf:
These settings ensure Apache starts with 8 processes (matching your cores) and scales up as needed.StartServers 8 MinSpareServers 8 MaxSpareServers 16 MaxRequestWorkers 128 MaxConnectionsPerChild 0
Note: Daemon mode is still better for Python apps—it isolates your app from Apache's core processes and avoids GIL-related bottlenecks with threads.
Permissions often prevent mod_wsgi from spawning multiple processes or accessing app resources:
- Ensure your app directory and files are owned by the user/group specified in
WSGIDaemonProcess(e.g.,www-data:www-data):chown -R www-data:www-data /var/www/app-server chmod -R 755 /var/www/app-server chmod 644 /var/www/app-server/*.py /var/www/app-server/APPNAME.wsgi - Confirm the
www-datauser has read/write access to any external resources your app uses (databases, files, APIs, etc.).
- Disable Debug Mode: Make sure
app.debug = Falsein your code—Werkzeug's debug mode explicitly blocks multi-process setups for security reasons. - Lazy Initialization: Each process initializes its own Flask app instance, so avoid heavy one-time setup (like loading large parsing models) in the global scope. Initialize these resources inside route functions or use lazy loading to avoid redundant work across processes.
- Avoid Shared State: Multi-process apps don't share memory, so don't rely on global variables for user data or cache. Use an external cache (like Redis) or database instead.
After updating configs, restart Apache:
sudo systemctl restart apache2
Then:
- Check for multiple mod_wsgi daemon processes:
You should see 8 processes matching yourps aux | grep mod_wsgiprocessessetting. - Monitor Apache logs for errors:
Look for permission errors, import issues, or configuration typos.tail -f /var/log/apache2/error.log - Test with traffic: Use tools like
ab(Apache Bench) to simulate high load and confirm CPU usage is distributed across all cores, and your app stops stalling.
内容的提问来源于stack exchange,提问作者Sergey Kireyev

