WINNT Apache MPM "ThreadsPerChild" configuration on Windows Server 2008 R2

11,916

Solution 1

The thread configuration of the multi-processing module (mpm) on any system is bound to certain restrictions, system limitations, and compiled fail-safe settings as described in the article Apache MPM Common Directives

ThreadsPerChild Directive

This directive sets the number of threads created by each child process. The child creates these threads at startup and never creates more. If using an MPM like mpm_winnt, where there is only one child process, this number should be high enough to handle the entire load of the server. If using an MPM like worker, where there are multiple child processes, the total number of threads should be high enough to handle the common load on the server.

ThreadLimit Directive

Special care must be taken when using this directive. If ThreadLimit is set to a value much higher than ThreadsPerChild, extra unused shared memory will be allocated. If both ThreadLimit and ThreadsPerChild are set to values higher than the system can handle, Apache httpd may not start or the system may become unstable. Do not set the value of this directive any higher than your greatest predicted setting of ThreadsPerChild for the current run of Apache httpd.

And they also point out that...

The default value for ThreadLimit is 1920 when used with mpm_winnt and 64 when used with the others.

There is also a hard-coded compiled limit which you can circumvent by recompiling the code as explained here:

There is a hard limit of ThreadLimit 20000 (or ThreadLimit 100000 with event, ThreadLimit 15000 with mpm_winnt) compiled into the server. This is intended to avoid nasty effects caused by typos. To increase it even further past this limit, you will need to modify the value of MAX_THREAD_LIMIT in the mpm source file and rebuild the server.

ThreadStackSize Directive

The ThreadStackSize directive sets the size of the stack (for autodata) of threads which handle client connections and call modules to help process those connections. In most cases the operating system default for stack size is reasonable, but there are some conditions where it may need to be adjusted:

Which are...

It is recommended to not reduce ThreadStackSize unless a high number of threads per child process is needed. On some platforms (including Linux), a setting of 128000 is already too low and causes crashes with some common modules.

Solution

If you are going to increase the ThreadsPerChild directive, then you will have to align the ThreadLimit directive to the same value or only slightly higher, while additionally reducing the ThreadStackSize directive to a lower value than default, while still maintaining a stable system.

A possible solution would be:

<IfModule mpm_winnt_module>
    ThreadStackSize  6291456
    ThreadsPerChild      200
    ThreadLimit          200
    MaxRequestsPerChild    0
    #Win32DisableAcceptEx
</IfModule>

You will have to play around a bit with these values to determine the setting that will allow you to run a stable system with the max possible ThreadsPerChild setting.

Solution 2

This person says that by using 64bit Windows and Apache they were able to maximize their ThreadsPerChild.

https://www.apachelounge.com/viewtopic.php?t=5754

Today I've tried the same configuration as described above but using x64 system:
Windows Server 2012 (x64)
Apache 2.4.7 VC11 64bit
mod_fcgid 2.3.9
PHP 5.4.24 VC11 Non-thread-safe

However, on a 64bit system two problems went away:
1. mpm ThreadsPerChild can now be set to 15000

Share:
11,916

Related videos on Youtube

user3162662
Author by

user3162662

Updated on September 18, 2022

Comments

  • user3162662
    user3162662 almost 2 years

    I am getting error and unable to start Apache when I set my ThreadPerChild to 200 , although I still have 60% free RAM. Server is Windows Server 2008 R2 With 4GB RAM. How to utilize more RAM to apache in this case?

    My Apache MPM Configuration:

    # WinNT MPM
    # ThreadsPerChild: constant number of worker threads in the server process
    # MaxRequestsPerChild: maximum  number of requests a server process serves
    # Win32DisableAcceptEx: Use accept() rather than AcceptEx() to accept network connections
    <IfModule mpm_winnt_module>
       ThreadStackSize 8388608
        ThreadsPerChild      170
        MaxRequestsPerChild    0
        #Win32DisableAcceptEx
    </IfModule>
    

    What I get in apache's error_log:

    [Thu Dec 01 18:23:04.459113 2016] [mpm_winnt:notice] [pid 3396:tid 288] AH00354: Child: Starting 200 worker threads.

    [Thu Dec 01 18:23:04.459113 2016] [mpm_winnt:crit] [pid 3396:tid 288] (OS 8)Not enough storage is available to process this command. : AH00355: Child: CreateThread failed. Unable to create all worker threads. Created 190 of the 200 threads requested with the ThreadsPerChild configuration directive.

    [Thu Dec 01 18:23:04.474714 2016] [mpm_winnt:notice] [pid 3644:tid 380] AH00422: Parent: Received shutdown signal --

    EDIT: 9 Dec 2016:

    Followed this page https://support.microsoft.com/en-us/kb/106167 to change the IRPStackSize in Registry to 20 and 25. Still failed to start Apache server.

    Thanks.

    • Admin
      Admin over 7 years
      Are you using a 64bit Apache? - what is the effect of lowering the Threads per child below 190? - it looks like memory over commit off the bat
    • Admin
      Admin over 7 years
      Did you try to decrease ThreadStackSize (eg. to 4000000)?
    • Admin
      Admin over 7 years
      @kay27 I had to use 8MB ThreadStackSize because if not the PHP OpCache module will crash. stackoverflow.com/questions/5058845/…
    • Admin
      Admin over 7 years
      I don't even need to know why you increased it - probably it's not a problem. I wonder if you imagine 200 threads with own 8 MB stack for each of them. Then multiply it by number of request workers and you'll find out that with 4 GB RAM you'll have maximum 4096 / (8 * 200) = 2 request workers - not a big number for the common case. Default MaxRequestWorkers value is based on ServerLimit httpd.apache.org/docs/current/mod/… . I suppose you don't see 100% because of its dynamic allocation. Maybe I wrong, but if you temporarily decrease this value-you'll see
  • Chloe
    Chloe over 7 years
    How is that a solution? You just copied from the documentation and reiterated their configuration. The default ThreadLimit is 1920 which is already more than 200 so how is setting it to 200 going to help? 200 x 8388608 = 1.7GB which is much less than their RAM, so why did you set ThreadStackSize to 6291456? How did you come up with 6.3MB?
  • Chloe
    Chloe over 7 years
    If that doesn't work, I would use a previous version of Apache. It sounds like a bug.
  • John K. N.
    John K. N. over 7 years
    I didn't point out a direct solution as there is none. It depends on a lot of factors that I can not determine from here. My steps are a guideline to finding the correct values. You can keep stepping up the ThreadLimit and ThreadsPerChild as long as it still works. If it stops working then you have to either reduce those parameters again or reduce the ThreadStackSize.