]> granicus.if.org Git - apache/commitdiff
Added examples to mod_event's AsyncRequestWorkerFactor section.
authorLuca Toscano <elukey@apache.org>
Sun, 14 Feb 2016 08:50:05 +0000 (08:50 +0000)
committerLuca Toscano <elukey@apache.org>
Sun, 14 Feb 2016 08:50:05 +0000 (08:50 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1730297 13f79535-47bb-0310-9956-ffa450edef68

docs/manual/mod/event.xml

index 6b5670df6807d0dfe8c841d9908d19fe4fca1143..9c0117111e4ee844d720b318f25340e9cf0f4baf 100644 (file)
@@ -116,7 +116,7 @@ of the <directive>AsyncRequestWorkerFactor</directive>.</p>
         thread serving the response content can flush the first bytes until <code>EWOULDBLOCK</code>
         or <code>EAGAIN</code> is returned, delegating the rest to the listener. This one in turn
         waits for an event on the socket, and delegates the work to flush the rest of the content
-        to the first idle worker thread. Meanwhile in the latter example (FCGI/CGI/proxed content)
+        to the first idle worker thread. Meanwhile in the latter example (FCGI/CGI/proxied content)
         the MPM can't predict the end of the response and a worker thread has to finish its work
         before returning the control to the listener. The only alternative is to buffer the 
         response in memory, but it wouldn't be the safest option for the sake of the
@@ -231,12 +231,15 @@ of the <directive>AsyncRequestWorkerFactor</directive>.</p>
     no worker thread is available to handle new work on established async
     connections.</p>
 
-    <p>To mitigate this problem, the event MPM does two things: Firstly, it
-    limits the number of connections accepted per process, depending on the
-    number of idle request workers. Secondly, if all workers are busy, it will
-    close connections in keep-alive state even if the keep-alive timeout has
-    not expired. This allows the respective clients to reconnect to a
-    different process which may still have worker threads available.</p>
+    <p>To mitigate this problem, the event MPM does two things:</p>
+    <ul>
+        <li>it limits the number of connections accepted per process, depending on the
+            number of idle request workers;</li>
+        <li>if all workers are busy, it will
+            close connections in keep-alive state even if the keep-alive timeout has
+            not expired. This allows the respective clients to reconnect to a
+            different process which may still have worker threads available.</li>
+    </ul>
 
     <p>This directive can be used to fine-tune the per-process connection
     limit. A process will only accept new connections if the current number of
@@ -249,13 +252,81 @@ of the <directive>AsyncRequestWorkerFactor</directive>.</p>
         <var>number of idle workers</var>)
     </strong></p>
 
-    <p>This means the absolute maximum numbers of concurrent connections is:</p>
+    <note><title>Idle connections handled by each process</title>
+    <highlight language="config">
+
+max_connections = ThreadsPerChild + (AsyncRequestWorkerFactor * idle_workers)
+
+ThreadsPerChild = idle_workers + busy_workers
+            
+max_connections = (idle_workers + busy_workers) + (AsyncRequestWorkerFactor * idle_workers)
+                = busy_workers + (AsyncRequestWorkerFactor + 1) * idle_workers 
+
+max_connections = max_idle_connections + busy_workers 
+
+max_idle_connections + busy_workers = 
+                busy_workers + (AsyncRequestWorkerFactor + 1) * idle_workers 
+
+max_idle_connections = (AsyncRequestWorkerFactor + 1) * idle_workers 
+
+    </highlight>
+    </note>
+
+    <p>The absolute maximum numbers of concurrent connections is:</p>
 
     <p class="indent"><strong>
         (<directive>AsyncRequestWorkerFactor</directive> + 1) *
         <directive module="mpm_common">MaxRequestWorkers</directive>
     </strong></p>
 
+
+    <note><title>Example 1</title>
+    <highlight language="config">
+    
+ThreadsPerChild = 10 
+ServerLimit = 4
+MaxRequestWorkers = 40
+AsyncRequestWorkerFactor = 2 
+    
+    </highlight>
+
+    <p>If all the processes have all threads idle then: </p>
+
+    <highlight language="config">idle_workers = 10</highlight>
+
+    <p>We can calculate the absolute maximum numbers of concurrent connections in two ways:</p>
+    
+    <highlight language="config">
+    
+max_connections = (ThreadsPerChild + (AsyncRequestWorkerFactor * idle_workers)) * ServerLimit 
+                = (10 + (2 * 10)) * 4 = 120
+    
+max_connections = (AsyncRequestWorkerFactor + 1) * MaxRequestWorkers 
+                = (2 + 1) * 40 = 120
+    
+    </highlight>
+    </note>
+
+    <p>The above example is only related to a theoretical maximum, let's take a look to a more common use case:</p>
+
+    <note><title>Example 2</title>
+    <highlight language="config">
+
+ThreadsPerChild = 10
+ServerLimit = 4
+AsyncRequestWorkerFactor = 2
+MaxRequestWorkers = 40
+
+idle_workers = 4 (average for all the processes to keep it simple)
+
+max_connections = (ThreadsPerChild + (AsyncRequestWorkerFactor * idle_workers)) * ServerLimit 
+                = (10 + (2 * 4)) * 4 = 72
+    
+    </highlight>
+    </note>
+
+    <p>Tuning <directive>AsyncRequestWorkerFactor</directive> requires knowledge about the traffic handled by httpd in each specific use case, so changing the default value requires extensive testing and data gathering from <module>mod_status</module>.</p>
+
     <p><directive module="mpm_common">MaxRequestWorkers</directive> was called
     <directive>MaxClients</directive> prior to version 2.3.13. The above value
     shows that the old name did not accurately describe its meaning for the event MPM.</p>