Limiting memory and CPU usage per httpd.worker, with apache/mod-wsgi

apache-2.2mod-wsgi

Upon running certain functions within a web application, the 'top' command sometimes shows CPU usage for a particular httpd.worker going up to 100%; also, the memory use per worker sometimes gets high enough to be of concern. The wsgi configuration is pretty standard, and looks like this:

...
MaxSpareThreads 3
MinSpareThreads 1
MaxRequestsPerChild 500
ServerLimit 1
SetEnvIf X-Forwarded-SSL on HTTPS=1
ThreadsPerChild 5
WSGIDaemonProcess w2p processes=5 python-path=/home/[...]/python2.7 threads=1
...

Is there a way to limit the CPU use per worker, such that it doesn't go above a certain percentage of CPU, and to restart a worker once its memory usage exceeds a certain limit?

Best Answer

Given you are already limiting the number of requests per child to 500, I would be looking for a memory leak in your code.

To limit memory you can use ulimit in the script that starts apache. Set it to a limit as a little larger than you expect the worker threads to use. If a thread tries to grow larger than the specified size, the operating system will kill the worker. Apache will re-spawn a new process to replace the killed worker. If you enable core dumps, you can analyze them to see what the memory is being used for. This will catch most processes that don't handle failed memory requests and crash. Some processes may catch the failure and gracefully exit with or without a core dump.

If you have a multi-core processor, I would not be concerned about a worker using 100% of CPU. Even on a single core process, I would not be concerned if other processes are not suffering. However, it may indicate that you have some code that is inefficient.

Load average tends to be a good indicator if the CPU is getting overloaded. If it is frequently at or above your core count, then CPU is becoming a bottleneck.

If you have long running high CPU requests, there are programs that will nice (lower the CPU priority) the offending process allowing other processes to get CPU time. For scheduled code, it may be worth looking at changing it into an application that can be run with CPU niced.

Related Topic