github.com/krum110487/go-htaccess@v0.0.0-20240316004156-60641c8e7598/tests/data/apache_2_2_34/manual/misc/perf-tuning.html.en (about) 1 <?xml version="1.0" encoding="ISO-8859-1"?> 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 3 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head> 4 <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type" /> 5 <!-- 6 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 7 This file is generated from xml source: DO NOT EDIT 8 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 9 --> 10 <title>Apache Performance Tuning - Apache HTTP Server Version 2.2</title> 11 <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" /> 12 <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" /> 13 <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="../style/css/prettify.css" /> 14 <script src="../style/scripts/prettify.min.js" type="text/javascript"> 15 </script> 16 17 <link href="../images/favicon.ico" rel="shortcut icon" /><link href="http://httpd.apache.org/docs/current/misc/perf-tuning.html" rel="canonical" /></head> 18 <body id="manual-page"><div id="page-header"> 19 <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p> 20 <p class="apache">Apache HTTP Server Version 2.2</p> 21 <img alt="" src="../images/feather.gif" /></div> 22 <div class="up"><a href="./"><img title="<-" alt="<-" src="../images/left.gif" /></a></div> 23 <div id="path"> 24 <a href="http://www.apache.org/">Apache</a> > <a href="http://httpd.apache.org/">HTTP Server</a> > <a href="http://httpd.apache.org/docs/">Documentation</a> > <a href="../">Version 2.2</a> > <a href="./">Miscellaneous Documentation</a></div><div id="page-content"><div class="retired"><h4>Please note</h4> 25 <p> This document refers to a legacy release (<strong>2.2</strong>) of Apache httpd. The active release (<strong>2.4</strong>) is documented <a href="http://httpd.apache.org/docs/current">here</a>. If you have not already upgraded, please follow <a href="http://httpd.apache.org/docs/current/upgrading.html">this link</a> for more information.</p> 26 <p>You may follow <a href="http://httpd.apache.org/docs/current/misc/perf-tuning.html">this link</a> to go to the current version of this document.</p></div><div id="preamble"><h1>Apache Performance Tuning</h1> 27 <div class="toplang"> 28 <p><span>Available Languages: </span><a href="../en/misc/perf-tuning.html" title="English"> en </a> | 29 <a href="../ko/misc/perf-tuning.html" hreflang="ko" rel="alternate" title="Korean"> ko </a> | 30 <a href="../tr/misc/perf-tuning.html" hreflang="tr" rel="alternate" title="Türkçe"> tr </a></p> 31 </div> 32 33 34 <p>Apache 2.x is a general-purpose webserver, designed to 35 provide a balance of flexibility, portability, and performance. 36 Although it has not been designed specifically to set benchmark 37 records, Apache 2.x is capable of high performance in many 38 real-world situations.</p> 39 40 <p>Compared to Apache 1.3, release 2.x contains many additional 41 optimizations to increase throughput and scalability. Most of 42 these improvements are enabled by default. However, there are 43 compile-time and run-time configuration choices that can 44 significantly affect performance. This document describes the 45 options that a server administrator can configure to tune the 46 performance of an Apache 2.x installation. Some of these 47 configuration options enable the httpd to better take advantage 48 of the capabilities of the hardware and OS, while others allow 49 the administrator to trade functionality for speed.</p> 50 51 </div> 52 <div id="quickview"><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#hardware">Hardware and Operating System Issues</a></li> 53 <li><img alt="" src="../images/down.gif" /> <a href="#runtime">Run-Time Configuration Issues</a></li> 54 <li><img alt="" src="../images/down.gif" /> <a href="#compiletime">Compile-Time Configuration Issues</a></li> 55 <li><img alt="" src="../images/down.gif" /> <a href="#trace">Appendix: Detailed Analysis of a Trace</a></li> 56 </ul><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div> 57 <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> 58 <div class="section"> 59 <h2><a name="hardware" id="hardware">Hardware and Operating System Issues</a></h2> 60 61 62 63 <p>The single biggest hardware issue affecting webserver 64 performance is RAM. A webserver should never ever have to swap, 65 as swapping increases the latency of each request beyond a point 66 that users consider "fast enough". This causes users to hit 67 stop and reload, further increasing the load. You can, and 68 should, control the <code class="directive"><a href="../mod/mpm_common.html#maxclients">MaxClients</a></code> setting so that your server 69 does not spawn so many children that it starts swapping. The procedure 70 for doing this is simple: determine the size of your average Apache 71 process, by looking at your process list via a tool such as 72 <code>top</code>, and divide this into your total available memory, 73 leaving some room for other processes.</p> 74 75 <p>Beyond that the rest is mundane: get a fast enough CPU, a 76 fast enough network card, and fast enough disks, where "fast 77 enough" is something that needs to be determined by 78 experimentation.</p> 79 80 <p>Operating system choice is largely a matter of local 81 concerns. But some guidelines that have proven generally 82 useful are:</p> 83 84 <ul> 85 <li> 86 <p>Run the latest stable release and patch level of the 87 operating system that you choose. Many OS suppliers have 88 introduced significant performance improvements to their 89 TCP stacks and thread libraries in recent years.</p> 90 </li> 91 92 <li> 93 <p>If your OS supports a <code>sendfile(2)</code> system 94 call, make sure you install the release and/or patches 95 needed to enable it. (With Linux, for example, this means 96 using Linux 2.4 or later. For early releases of Solaris 8, 97 you may need to apply a patch.) On systems where it is 98 available, <code>sendfile</code> enables Apache 2 to deliver 99 static content faster and with lower CPU utilization.</p> 100 </li> 101 </ul> 102 103 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> 104 <div class="section"> 105 <h2><a name="runtime" id="runtime">Run-Time Configuration Issues</a></h2> 106 107 108 109 <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_dir.html">mod_dir</a></code></li><li><code class="module"><a href="../mod/mpm_common.html">mpm_common</a></code></li><li><code class="module"><a href="../mod/mod_status.html">mod_status</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#allowoverride">AllowOverride</a></code></li><li><code class="directive"><a href="../mod/mod_dir.html#directoryindex">DirectoryIndex</a></code></li><li><code class="directive"><a href="../mod/core.html#hostnamelookups">HostnameLookups</a></code></li><li><code class="directive"><a href="../mod/core.html#enablemmap">EnableMMAP</a></code></li><li><code class="directive"><a href="../mod/core.html#enablesendfile">EnableSendfile</a></code></li><li><code class="directive"><a href="../mod/core.html#keepalivetimeout">KeepAliveTimeout</a></code></li><li><code class="directive"><a href="../mod/prefork.html#maxspareservers">MaxSpareServers</a></code></li><li><code class="directive"><a href="../mod/prefork.html#minspareservers">MinSpareServers</a></code></li><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/mpm_common.html#startservers">StartServers</a></code></li></ul></td></tr></table> 110 111 <h3><a name="dns" id="dns">HostnameLookups and other DNS considerations</a></h3> 112 113 114 115 <p>Prior to Apache 1.3, <code class="directive"><a href="../mod/core.html#hostnamelookups">HostnameLookups</a></code> defaulted to <code>On</code>. 116 This adds latency to every request because it requires a 117 DNS lookup to complete before the request is finished. In 118 Apache 1.3 this setting defaults to <code>Off</code>. If you need 119 to have addresses in your log files resolved to hostnames, use the 120 <code class="program"><a href="../programs/logresolve.html">logresolve</a></code> 121 program that comes with Apache, or one of the numerous log 122 reporting packages which are available.</p> 123 124 <p>It is recommended that you do this sort of postprocessing of 125 your log files on some machine other than the production web 126 server machine, in order that this activity not adversely affect 127 server performance.</p> 128 129 <p>If you use any <code><code class="directive"><a href="../mod/mod_authz_host.html#allow">Allow</a></code> from domain</code> or <code><code class="directive"><a href="../mod/mod_authz_host.html#deny">Deny</a></code> from domain</code> 130 directives (i.e., using a hostname, or a domain name, rather than 131 an IP address) then you will pay for 132 two DNS lookups (a reverse, followed by a forward lookup 133 to make sure that the reverse is not being spoofed). For best 134 performance, therefore, use IP addresses, rather than names, when 135 using these directives, if possible.</p> 136 137 <p>Note that it's possible to scope the directives, such as 138 within a <code><Location /server-status></code> section. 139 In this case the DNS lookups are only performed on requests 140 matching the criteria. Here's an example which disables lookups 141 except for <code>.html</code> and <code>.cgi</code> files:</p> 142 143 <div class="example"><p><code> 144 HostnameLookups off<br /> 145 <Files ~ "\.(html|cgi)$"><br /> 146 <span class="indent"> 147 HostnameLookups on<br /> 148 </span> 149 </Files> 150 </code></p></div> 151 152 <p>But even still, if you just need DNS names in some CGIs you 153 could consider doing the <code>gethostbyname</code> call in the 154 specific CGIs that need it.</p> 155 156 157 158 <h3><a name="symlinks" id="symlinks">FollowSymLinks and SymLinksIfOwnerMatch</a></h3> 159 160 161 162 <p>Wherever in your URL-space you do not have an <code>Options 163 FollowSymLinks</code>, or you do have an <code>Options 164 SymLinksIfOwnerMatch</code>, Apache will need to issue extra 165 system calls to check up on symlinks. (One extra call per 166 filename component.) For example, if you had:</p> 167 168 <div class="example"><p><code> 169 DocumentRoot /www/htdocs<br /> 170 <Directory /><br /> 171 <span class="indent"> 172 Options SymLinksIfOwnerMatch<br /> 173 </span> 174 </Directory> 175 </code></p></div> 176 177 <p>and a request is made for the URI <code>/index.html</code>, 178 then Apache will perform <code>lstat(2)</code> on 179 <code>/www</code>, <code>/www/htdocs</code>, and 180 <code>/www/htdocs/index.html</code>. The results of these 181 <code>lstats</code> are never cached, so they will occur on 182 every single request. If you really desire the symlinks 183 security checking, you can do something like this:</p> 184 185 <div class="example"><p><code> 186 DocumentRoot /www/htdocs<br /> 187 <Directory /><br /> 188 <span class="indent"> 189 Options FollowSymLinks<br /> 190 </span> 191 </Directory><br /> 192 <br /> 193 <Directory /www/htdocs><br /> 194 <span class="indent"> 195 Options -FollowSymLinks +SymLinksIfOwnerMatch<br /> 196 </span> 197 </Directory> 198 </code></p></div> 199 200 <p>This at least avoids the extra checks for the 201 <code class="directive"><a href="../mod/core.html#documentroot">DocumentRoot</a></code> path. 202 Note that you'll need to add similar sections if you 203 have any <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code> or 204 <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> paths 205 outside of your document root. For highest performance, 206 and no symlink protection, set <code>FollowSymLinks</code> 207 everywhere, and never set <code>SymLinksIfOwnerMatch</code>.</p> 208 209 210 211 <h3><a name="htaccess" id="htaccess">AllowOverride</a></h3> 212 213 214 215 <p>Wherever in your URL-space you allow overrides (typically 216 <code>.htaccess</code> files), Apache will attempt to open 217 <code>.htaccess</code> for each filename component. For 218 example,</p> 219 220 <div class="example"><p><code> 221 DocumentRoot /www/htdocs<br /> 222 <Directory /><br /> 223 <span class="indent"> 224 AllowOverride all<br /> 225 </span> 226 </Directory> 227 </code></p></div> 228 229 <p>and a request is made for the URI <code>/index.html</code>. 230 Then Apache will attempt to open <code>/.htaccess</code>, 231 <code>/www/.htaccess</code>, and 232 <code>/www/htdocs/.htaccess</code>. The solutions are similar 233 to the previous case of <code>Options FollowSymLinks</code>. 234 For highest performance use <code>AllowOverride None</code> 235 everywhere in your filesystem.</p> 236 237 238 239 <h3><a name="negotiation" id="negotiation">Negotiation</a></h3> 240 241 242 243 <p>If at all possible, avoid content negotiation if you're 244 really interested in every last ounce of performance. In 245 practice the benefits of negotiation outweigh the performance 246 penalties. There's one case where you can speed up the server. 247 Instead of using a wildcard such as:</p> 248 249 <div class="example"><p><code> 250 DirectoryIndex index 251 </code></p></div> 252 253 <p>Use a complete list of options:</p> 254 255 <div class="example"><p><code> 256 DirectoryIndex index.cgi index.pl index.shtml index.html 257 </code></p></div> 258 259 <p>where you list the most common choice first.</p> 260 261 <p>Also note that explicitly creating a <code>type-map</code> 262 file provides better performance than using 263 <code>MultiViews</code>, as the necessary information can be 264 determined by reading this single file, rather than having to 265 scan the directory for files.</p> 266 267 <p>If your site needs content negotiation, consider using 268 <code>type-map</code> files, rather than the <code>Options 269 MultiViews</code> directive to accomplish the negotiation. See the 270 <a href="../content-negotiation.html">Content Negotiation</a> 271 documentation for a full discussion of the methods of negotiation, 272 and instructions for creating <code>type-map</code> files.</p> 273 274 275 276 <h3>Memory-mapping</h3> 277 278 279 280 <p>In situations where Apache 2.x needs to look at the contents 281 of a file being delivered--for example, when doing server-side-include 282 processing--it normally memory-maps the file if the OS supports 283 some form of <code>mmap(2)</code>.</p> 284 285 <p>On some platforms, this memory-mapping improves performance. 286 However, there are cases where memory-mapping can hurt the performance 287 or even the stability of the httpd:</p> 288 289 <ul> 290 <li> 291 <p>On some operating systems, <code>mmap</code> does not scale 292 as well as <code>read(2)</code> when the number of CPUs increases. 293 On multiprocessor Solaris servers, for example, Apache 2.x sometimes 294 delivers server-parsed files faster when <code>mmap</code> is disabled.</p> 295 </li> 296 297 <li> 298 <p>If you memory-map a file located on an NFS-mounted filesystem 299 and a process on another NFS client machine deletes or truncates 300 the file, your process may get a bus error the next time it tries 301 to access the mapped file content.</p> 302 </li> 303 </ul> 304 305 <p>For installations where either of these factors applies, you 306 should use <code>EnableMMAP off</code> to disable the memory-mapping 307 of delivered files. (Note: This directive can be overridden on 308 a per-directory basis.)</p> 309 310 311 312 <h3>Sendfile</h3> 313 314 315 316 <p>In situations where Apache 2.x can ignore the contents of the file 317 to be delivered -- for example, when serving static file content -- 318 it normally uses the kernel sendfile support for the file if the OS 319 supports the <code>sendfile(2)</code> operation.</p> 320 321 <p>On most platforms, using sendfile improves performance by eliminating 322 separate read and send mechanics. However, there are cases where using 323 sendfile can harm the stability of the httpd:</p> 324 325 <ul> 326 <li> 327 <p>Some platforms may have broken sendfile support that the build 328 system did not detect, especially if the binaries were built on 329 another box and moved to such a machine with broken sendfile support.</p> 330 </li> 331 <li> 332 <p>With an NFS-mounted files, the kernel may be unable 333 to reliably serve the network file through it's own cache.</p> 334 </li> 335 </ul> 336 337 <p>For installations where either of these factors applies, you 338 should use <code>EnableSendfile off</code> to disable sendfile 339 delivery of file contents. (Note: This directive can be overridden 340 on a per-directory basis.)</p> 341 342 343 344 <h3><a name="process" id="process">Process Creation</a></h3> 345 346 347 348 <p>Prior to Apache 1.3 the <code class="directive"><a href="../mod/prefork.html#minspareservers">MinSpareServers</a></code>, <code class="directive"><a href="../mod/prefork.html#maxspareservers">MaxSpareServers</a></code>, and <code class="directive"><a href="../mod/mpm_common.html#startservers">StartServers</a></code> settings all had drastic effects on 349 benchmark results. In particular, Apache required a "ramp-up" 350 period in order to reach a number of children sufficient to serve 351 the load being applied. After the initial spawning of 352 <code class="directive"><a href="../mod/mpm_common.html#startservers">StartServers</a></code> children, 353 only one child per second would be created to satisfy the 354 <code class="directive"><a href="../mod/prefork.html#minspareservers">MinSpareServers</a></code> 355 setting. So a server being accessed by 100 simultaneous 356 clients, using the default <code class="directive"><a href="../mod/mpm_common.html#startservers">StartServers</a></code> of <code>5</code> would take on 357 the order of 95 seconds to spawn enough children to handle 358 the load. This works fine in practice on real-life servers 359 because they aren't restarted frequently. But it does really 360 poorly on benchmarks which might only run for ten minutes.</p> 361 362 <p>The one-per-second rule was implemented in an effort to 363 avoid swamping the machine with the startup of new children. If 364 the machine is busy spawning children, it can't service 365 requests. But it has such a drastic effect on the perceived 366 performance of Apache that it had to be replaced. As of Apache 367 1.3, the code will relax the one-per-second rule. It will spawn 368 one, wait a second, then spawn two, wait a second, then spawn 369 four, and it will continue exponentially until it is spawning 370 32 children per second. It will stop whenever it satisfies the 371 <code class="directive"><a href="../mod/prefork.html#minspareservers">MinSpareServers</a></code> 372 setting.</p> 373 374 <p>This appears to be responsive enough that it's almost 375 unnecessary to twiddle the <code class="directive"><a href="../mod/prefork.html#minspareservers">MinSpareServers</a></code>, <code class="directive"><a href="../mod/prefork.html#maxspareservers">MaxSpareServers</a></code> and <code class="directive"><a href="../mod/mpm_common.html#startservers">StartServers</a></code> knobs. When more than 4 children are 376 spawned per second, a message will be emitted to the 377 <code class="directive"><a href="../mod/core.html#errorlog">ErrorLog</a></code>. If you 378 see a lot of these errors, then consider tuning these settings. 379 Use the <code class="module"><a href="../mod/mod_status.html">mod_status</a></code> output as a guide.</p> 380 381 <p>Related to process creation is process death induced by the 382 <code class="directive"><a href="../mod/mpm_common.html#maxrequestsperchild">MaxRequestsPerChild</a></code> 383 setting. By default this is <code>0</code>, 384 which means that there is no limit to the number of requests 385 handled per child. If your configuration currently has this set 386 to some very low number, such as <code>30</code>, you may want to bump this 387 up significantly. If you are running SunOS or an old version of 388 Solaris, limit this to <code>10000</code> or so because of memory leaks.</p> 389 390 <p>When keep-alives are in use, children will be kept busy 391 doing nothing waiting for more requests on the already open 392 connection. The default <code class="directive"><a href="../mod/core.html#keepalivetimeout">KeepAliveTimeout</a></code> of <code>5</code> 393 seconds attempts to minimize this effect. The tradeoff here is 394 between network bandwidth and server resources. In no event 395 should you raise this above about <code>60</code> seconds, as <a href="http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-95-4.html"> 396 most of the benefits are lost</a>.</p> 397 398 399 400 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> 401 <div class="section"> 402 <h2><a name="compiletime" id="compiletime">Compile-Time Configuration Issues</a></h2> 403 404 405 406 <h3>Choosing an MPM</h3> 407 408 409 410 <p>Apache 2.x supports pluggable concurrency models, called 411 <a href="../mpm.html">Multi-Processing Modules</a> (MPMs). 412 When building Apache, you must choose an MPM to use. There 413 are platform-specific MPMs for some platforms: 414 <code class="module"><a href="../mod/beos.html">beos</a></code>, <code class="module"><a href="../mod/mpm_netware.html">mpm_netware</a></code>, 415 <code class="module"><a href="../mod/mpmt_os2.html">mpmt_os2</a></code>, and <code class="module"><a href="../mod/mpm_winnt.html">mpm_winnt</a></code>. For 416 general Unix-type systems, there are several MPMs from which 417 to choose. The choice of MPM can affect the speed and scalability 418 of the httpd:</p> 419 420 <ul> 421 422 <li>The <code class="module"><a href="../mod/worker.html">worker</a></code> MPM uses multiple child 423 processes with many threads each. Each thread handles 424 one connection at a time. Worker generally is a good 425 choice for high-traffic servers because it has a smaller 426 memory footprint than the prefork MPM.</li> 427 428 <li>The <code class="module"><a href="../mod/prefork.html">prefork</a></code> MPM uses multiple child 429 processes with one thread each. Each process handles 430 one connection at a time. On many systems, prefork is 431 comparable in speed to worker, but it uses more memory. 432 Prefork's threadless design has advantages over worker 433 in some situations: it can be used with non-thread-safe 434 third-party modules, and it is easier to debug on platforms 435 with poor thread debugging support.</li> 436 437 </ul> 438 439 <p>For more information on these and other MPMs, please 440 see the MPM <a href="../mpm.html">documentation</a>.</p> 441 442 443 444 <h3><a name="modules" id="modules">Modules</a></h3> 445 446 447 448 <p>Since memory usage is such an important consideration in 449 performance, you should attempt to eliminate modules that you are 450 not actually using. If you have built the modules as <a href="../dso.html">DSOs</a>, eliminating modules is a simple 451 matter of commenting out the associated <code class="directive"><a href="../mod/mod_so.html#loadmodule">LoadModule</a></code> directive for that module. 452 This allows you to experiment with removing modules and seeing 453 if your site still functions in their absense.</p> 454 455 <p>If, on the other hand, you have modules statically linked 456 into your Apache binary, you will need to recompile Apache in 457 order to remove unwanted modules.</p> 458 459 <p>An associated question that arises here is, of course, what 460 modules you need, and which ones you don't. The answer here 461 will, of course, vary from one web site to another. However, the 462 <em>minimal</em> list of modules which you can get by with tends 463 to include <code class="module"><a href="../mod/mod_mime.html">mod_mime</a></code>, <code class="module"><a href="../mod/mod_dir.html">mod_dir</a></code>, 464 and <code class="module"><a href="../mod/mod_log_config.html">mod_log_config</a></code>. <code>mod_log_config</code> is, 465 of course, optional, as you can run a web site without log 466 files. This is, however, not recommended.</p> 467 468 469 470 <h3>Atomic Operations</h3> 471 472 473 474 <p>Some modules, such as <code class="module"><a href="../mod/mod_cache.html">mod_cache</a></code> and 475 recent development builds of the worker MPM, use APR's 476 atomic API. This API provides atomic operations that can 477 be used for lightweight thread synchronization.</p> 478 479 <p>By default, APR implements these operations using the 480 most efficient mechanism available on each target 481 OS/CPU platform. Many modern CPUs, for example, have 482 an instruction that does an atomic compare-and-swap (CAS) 483 operation in hardware. On some platforms, however, APR 484 defaults to a slower, mutex-based implementation of the 485 atomic API in order to ensure compatibility with older 486 CPU models that lack such instructions. If you are 487 building Apache for one of these platforms, and you plan 488 to run only on newer CPUs, you can select a faster atomic 489 implementation at build time by configuring Apache with 490 the <code>--enable-nonportable-atomics</code> option:</p> 491 492 <div class="example"><p><code> 493 ./buildconf<br /> 494 ./configure --with-mpm=worker --enable-nonportable-atomics=yes 495 </code></p></div> 496 497 <p>The <code>--enable-nonportable-atomics</code> option is 498 relevant for the following platforms:</p> 499 500 <ul> 501 502 <li>Solaris on SPARC<br /> 503 By default, APR uses mutex-based atomics on Solaris/SPARC. 504 If you configure with <code>--enable-nonportable-atomics</code>, 505 however, APR generates code that uses a SPARC v8plus opcode for 506 fast hardware compare-and-swap. If you configure Apache with 507 this option, the atomic operations will be more efficient 508 (allowing for lower CPU utilization and higher concurrency), 509 but the resulting executable will run only on UltraSPARC 510 chips. 511 </li> 512 513 <li>Linux on x86<br /> 514 By default, APR uses mutex-based atomics on Linux. If you 515 configure with <code>--enable-nonportable-atomics</code>, 516 however, APR generates code that uses a 486 opcode for fast 517 hardware compare-and-swap. This will result in more efficient 518 atomic operations, but the resulting executable will run only 519 on 486 and later chips (and not on 386). 520 </li> 521 522 </ul> 523 524 525 526 <h3>mod_status and ExtendedStatus On</h3> 527 528 529 530 <p>If you include <code class="module"><a href="../mod/mod_status.html">mod_status</a></code> and you also set 531 <code>ExtendedStatus On</code> when building and running 532 Apache, then on every request Apache will perform two calls to 533 <code>gettimeofday(2)</code> (or <code>times(2)</code> 534 depending on your operating system), and (pre-1.3) several 535 extra calls to <code>time(2)</code>. This is all done so that 536 the status report contains timing indications. For highest 537 performance, set <code>ExtendedStatus off</code> (which is the 538 default).</p> 539 540 541 542 <h3>accept Serialization - Multiple Sockets</h3> 543 544 545 546 <div class="warning"><h3>Warning:</h3> 547 <p>This section has not been fully updated 548 to take into account changes made in the 2.x version of the 549 Apache HTTP Server. Some of the information may still be 550 relevant, but please use it with care.</p> 551 </div> 552 553 <p>This discusses a shortcoming in the Unix socket API. Suppose 554 your web server uses multiple <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code> statements to listen on either multiple 555 ports or multiple addresses. In order to test each socket 556 to see if a connection is ready, Apache uses 557 <code>select(2)</code>. <code>select(2)</code> indicates that a 558 socket has <em>zero</em> or <em>at least one</em> connection 559 waiting on it. Apache's model includes multiple children, and 560 all the idle ones test for new connections at the same time. A 561 naive implementation looks something like this (these examples 562 do not match the code, they're contrived for pedagogical 563 purposes):</p> 564 565 <div class="example"><p><code> 566 for (;;) {<br /> 567 <span class="indent"> 568 for (;;) {<br /> 569 <span class="indent"> 570 fd_set accept_fds;<br /> 571 <br /> 572 FD_ZERO (&accept_fds);<br /> 573 for (i = first_socket; i <= last_socket; ++i) {<br /> 574 <span class="indent"> 575 FD_SET (i, &accept_fds);<br /> 576 </span> 577 }<br /> 578 rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);<br /> 579 if (rc < 1) continue;<br /> 580 new_connection = -1;<br /> 581 for (i = first_socket; i <= last_socket; ++i) {<br /> 582 <span class="indent"> 583 if (FD_ISSET (i, &accept_fds)) {<br /> 584 <span class="indent"> 585 new_connection = accept (i, NULL, NULL);<br /> 586 if (new_connection != -1) break;<br /> 587 </span> 588 }<br /> 589 </span> 590 }<br /> 591 if (new_connection != -1) break;<br /> 592 </span> 593 }<br /> 594 process the new_connection;<br /> 595 </span> 596 } 597 </code></p></div> 598 599 <p>But this naive implementation has a serious starvation problem. 600 Recall that multiple children execute this loop at the same 601 time, and so multiple children will block at 602 <code>select</code> when they are in between requests. All 603 those blocked children will awaken and return from 604 <code>select</code> when a single request appears on any socket. 605 (The number of children which awaken varies depending on the 606 operating system and timing issues.) They will all then fall 607 down into the loop and try to <code>accept</code> the 608 connection. But only one will succeed (assuming there's still 609 only one connection ready). The rest will be <em>blocked</em> 610 in <code>accept</code>. This effectively locks those children 611 into serving requests from that one socket and no other 612 sockets, and they'll be stuck there until enough new requests 613 appear on that socket to wake them all up. This starvation 614 problem was first documented in <a href="http://bugs.apache.org/index/full/467">PR#467</a>. There 615 are at least two solutions.</p> 616 617 <p>One solution is to make the sockets non-blocking. In this 618 case the <code>accept</code> won't block the children, and they 619 will be allowed to continue immediately. But this wastes CPU 620 time. Suppose you have ten idle children in 621 <code>select</code>, and one connection arrives. Then nine of 622 those children will wake up, try to <code>accept</code> the 623 connection, fail, and loop back into <code>select</code>, 624 accomplishing nothing. Meanwhile none of those children are 625 servicing requests that occurred on other sockets until they 626 get back up to the <code>select</code> again. Overall this 627 solution does not seem very fruitful unless you have as many 628 idle CPUs (in a multiprocessor box) as you have idle children 629 (not a very likely situation).</p> 630 631 <p>Another solution, the one used by Apache, is to serialize 632 entry into the inner loop. The loop looks like this 633 (differences highlighted):</p> 634 635 <div class="example"><p><code> 636 for (;;) {<br /> 637 <span class="indent"> 638 <strong>accept_mutex_on ();</strong><br /> 639 for (;;) {<br /> 640 <span class="indent"> 641 fd_set accept_fds;<br /> 642 <br /> 643 FD_ZERO (&accept_fds);<br /> 644 for (i = first_socket; i <= last_socket; ++i) {<br /> 645 <span class="indent"> 646 FD_SET (i, &accept_fds);<br /> 647 </span> 648 }<br /> 649 rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);<br /> 650 if (rc < 1) continue;<br /> 651 new_connection = -1;<br /> 652 for (i = first_socket; i <= last_socket; ++i) {<br /> 653 <span class="indent"> 654 if (FD_ISSET (i, &accept_fds)) {<br /> 655 <span class="indent"> 656 new_connection = accept (i, NULL, NULL);<br /> 657 if (new_connection != -1) break;<br /> 658 </span> 659 }<br /> 660 </span> 661 }<br /> 662 if (new_connection != -1) break;<br /> 663 </span> 664 }<br /> 665 <strong>accept_mutex_off ();</strong><br /> 666 process the new_connection;<br /> 667 </span> 668 } 669 </code></p></div> 670 671 <p><a id="serialize" name="serialize">The functions</a> 672 <code>accept_mutex_on</code> and <code>accept_mutex_off</code> 673 implement a mutual exclusion semaphore. Only one child can have 674 the mutex at any time. There are several choices for 675 implementing these mutexes. The choice is defined in 676 <code>src/conf.h</code> (pre-1.3) or 677 <code>src/include/ap_config.h</code> (1.3 or later). Some 678 architectures do not have any locking choice made, on these 679 architectures it is unsafe to use multiple 680 <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code> 681 directives.</p> 682 683 <p>The directive <code class="directive"><a href="../mod/mpm_common.html#acceptmutex">AcceptMutex</a></code> can be used to 684 change the selected mutex implementation at run-time.</p> 685 686 <dl> 687 <dt><code>AcceptMutex flock</code></dt> 688 689 <dd> 690 <p>This method uses the <code>flock(2)</code> system call to 691 lock a lock file (located by the <code class="directive"><a href="../mod/mpm_common.html#lockfile">LockFile</a></code> directive).</p> 692 </dd> 693 694 <dt><code>AcceptMutex fcntl</code></dt> 695 696 <dd> 697 <p>This method uses the <code>fcntl(2)</code> system call to 698 lock a lock file (located by the <code class="directive"><a href="../mod/mpm_common.html#lockfile">LockFile</a></code> directive).</p> 699 </dd> 700 701 <dt><code>AcceptMutex sysvsem</code></dt> 702 703 <dd> 704 <p>(1.3 or later) This method uses SysV-style semaphores to 705 implement the mutex. Unfortunately SysV-style semaphores have 706 some bad side-effects. One is that it's possible Apache will 707 die without cleaning up the semaphore (see the 708 <code>ipcs(8)</code> man page). The other is that the 709 semaphore API allows for a denial of service attack by any 710 CGIs running under the same uid as the webserver 711 (<em>i.e.</em>, all CGIs, unless you use something like 712 <code class="program"><a href="../programs/suexec.html">suexec</a></code> or <code>cgiwrapper</code>). For these 713 reasons this method is not used on any architecture except 714 IRIX (where the previous two are prohibitively expensive 715 on most IRIX boxes).</p> 716 </dd> 717 718 <dt><code>AcceptMutex pthread</code></dt> 719 720 <dd> 721 <p>(1.3 or later) This method uses POSIX mutexes and should 722 work on any architecture implementing the full POSIX threads 723 specification, however appears to only work on Solaris (2.5 724 or later), and even then only in certain configurations. If 725 you experiment with this you should watch out for your server 726 hanging and not responding. Static content only servers may 727 work just fine.</p> 728 </dd> 729 730 <dt><code>AcceptMutex posixsem</code></dt> 731 732 <dd> 733 <p>(2.0 or later) This method uses POSIX semaphores. The 734 semaphore ownership is not recovered if a thread in the process 735 holding the mutex segfaults, resulting in a hang of the web 736 server.</p> 737 </dd> 738 739 </dl> 740 741 <p>If your system has another method of serialization which 742 isn't in the above list then it may be worthwhile adding code 743 for it to APR.</p> 744 745 <p>Another solution that has been considered but never 746 implemented is to partially serialize the loop -- that is, let 747 in a certain number of processes. This would only be of interest 748 on multiprocessor boxes where it's possible that multiple 749 children could run simultaneously, and the serialization 750 actually doesn't take advantage of the full bandwidth. This is 751 a possible area of future investigation, but priority remains 752 low because highly parallel web servers are not the norm.</p> 753 754 <p>Ideally you should run servers without multiple 755 <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code> 756 statements if you want the highest performance. 757 But read on.</p> 758 759 760 761 <h3>accept Serialization - Single Socket</h3> 762 763 764 765 <p>The above is fine and dandy for multiple socket servers, but 766 what about single socket servers? In theory they shouldn't 767 experience any of these same problems because all children can 768 just block in <code>accept(2)</code> until a connection 769 arrives, and no starvation results. In practice this hides 770 almost the same "spinning" behavior discussed above in the 771 non-blocking solution. The way that most TCP stacks are 772 implemented, the kernel actually wakes up all processes blocked 773 in <code>accept</code> when a single connection arrives. One of 774 those processes gets the connection and returns to user-space. 775 The rest spin in the kernel and go back to sleep when they 776 discover there's no connection for them. This spinning is 777 hidden from the user-land code, but it's there nonetheless. 778 This can result in the same load-spiking wasteful behavior 779 that a non-blocking solution to the multiple sockets case 780 can.</p> 781 782 <p>For this reason we have found that many architectures behave 783 more "nicely" if we serialize even the single socket case. So 784 this is actually the default in almost all cases. Crude 785 experiments under Linux (2.0.30 on a dual Pentium pro 166 786 w/128Mb RAM) have shown that the serialization of the single 787 socket case causes less than a 3% decrease in requests per 788 second over unserialized single-socket. But unserialized 789 single-socket showed an extra 100ms latency on each request. 790 This latency is probably a wash on long haul lines, and only an 791 issue on LANs. If you want to override the single socket 792 serialization, you can define 793 <code>SINGLE_LISTEN_UNSERIALIZED_ACCEPT</code>, and then 794 single-socket servers will not serialize at all.</p> 795 796 797 798 <h3>Lingering Close</h3> 799 800 801 802 <p>As discussed in <a href="http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-connection-00.txt"> 803 draft-ietf-http-connection-00.txt</a> section 8, in order for 804 an HTTP server to <strong>reliably</strong> implement the 805 protocol, it needs to shut down each direction of the 806 communication independently. (Recall that a TCP connection is 807 bi-directional. Each half is independent of the other.) This 808 fact is often overlooked by other servers, but is correctly 809 implemented in Apache as of 1.2.</p> 810 811 <p>When this feature was added to Apache, it caused a flurry of 812 problems on various versions of Unix because of shortsightedness. 813 The TCP specification does not state that the <code>FIN_WAIT_2</code> 814 state has a timeout, but it doesn't prohibit it. 815 On systems without the timeout, Apache 1.2 induces many sockets 816 stuck forever in the <code>FIN_WAIT_2</code> state. In many cases this 817 can be avoided by simply upgrading to the latest TCP/IP patches 818 supplied by the vendor. In cases where the vendor has never 819 released patches (<em>i.e.</em>, SunOS4 -- although folks with 820 a source license can patch it themselves), we have decided to 821 disable this feature.</p> 822 823 <p>There are two ways to accomplish this. One is the socket 824 option <code>SO_LINGER</code>. But as fate would have it, this 825 has never been implemented properly in most TCP/IP stacks. Even 826 on those stacks with a proper implementation (<em>i.e.</em>, 827 Linux 2.0.31), this method proves to be more expensive (cputime) 828 than the next solution.</p> 829 830 <p>For the most part, Apache implements this in a function 831 called <code>lingering_close</code> (in 832 <code>http_main.c</code>). The function looks roughly like 833 this:</p> 834 835 <div class="example"><p><code> 836 void lingering_close (int s)<br /> 837 {<br /> 838 <span class="indent"> 839 char junk_buffer[2048];<br /> 840 <br /> 841 /* shutdown the sending side */<br /> 842 shutdown (s, 1);<br /> 843 <br /> 844 signal (SIGALRM, lingering_death);<br /> 845 alarm (30);<br /> 846 <br /> 847 for (;;) {<br /> 848 <span class="indent"> 849 select (s for reading, 2 second timeout);<br /> 850 if (error) break;<br /> 851 if (s is ready for reading) {<br /> 852 <span class="indent"> 853 if (read (s, junk_buffer, sizeof (junk_buffer)) <= 0) {<br /> 854 <span class="indent"> 855 break;<br /> 856 </span> 857 }<br /> 858 /* just toss away whatever is here */<br /> 859 </span> 860 }<br /> 861 </span> 862 }<br /> 863 <br /> 864 close (s);<br /> 865 </span> 866 } 867 </code></p></div> 868 869 <p>This naturally adds some expense at the end of a connection, 870 but it is required for a reliable implementation. As HTTP/1.1 871 becomes more prevalent, and all connections are persistent, 872 this expense will be amortized over more requests. If you want 873 to play with fire and disable this feature, you can define 874 <code>NO_LINGCLOSE</code>, but this is not recommended at all. 875 In particular, as HTTP/1.1 pipelined persistent connections 876 come into use, <code>lingering_close</code> is an absolute 877 necessity (and <a href="http://www.w3.org/Protocols/HTTP/Performance/Pipeline.html"> 878 pipelined connections are faster</a>, so you want to support 879 them).</p> 880 881 882 883 <h3>Scoreboard File</h3> 884 885 886 887 <p>Apache's parent and children communicate with each other 888 through something called the scoreboard. Ideally this should be 889 implemented in shared memory. For those operating systems that 890 we either have access to, or have been given detailed ports 891 for, it typically is implemented using shared memory. The rest 892 default to using an on-disk file. The on-disk file is not only 893 slow, but it is unreliable (and less featured). Peruse the 894 <code>src/main/conf.h</code> file for your architecture, and 895 look for either <code>USE_MMAP_SCOREBOARD</code> or 896 <code>USE_SHMGET_SCOREBOARD</code>. Defining one of those two 897 (as well as their companions <code>HAVE_MMAP</code> and 898 <code>HAVE_SHMGET</code> respectively) enables the supplied 899 shared memory code. If your system has another type of shared 900 memory, edit the file <code>src/main/http_main.c</code> and add 901 the hooks necessary to use it in Apache. (Send us back a patch 902 too, please.)</p> 903 904 <div class="note">Historical note: The Linux port of Apache didn't start to 905 use shared memory until version 1.2 of Apache. This oversight 906 resulted in really poor and unreliable behavior of earlier 907 versions of Apache on Linux.</div> 908 909 910 911 <h3>DYNAMIC_MODULE_LIMIT</h3> 912 913 914 915 <p>If you have no intention of using dynamically loaded modules 916 (you probably don't if you're reading this and tuning your 917 server for every last ounce of performance), then you should add 918 <code>-DDYNAMIC_MODULE_LIMIT=0</code> when building your 919 server. This will save RAM that's allocated only for supporting 920 dynamically loaded modules.</p> 921 922 923 924 </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> 925 <div class="section"> 926 <h2><a name="trace" id="trace">Appendix: Detailed Analysis of a Trace</a></h2> 927 928 929 930 <p>Here is a system call trace of Apache 2.0.38 with the worker MPM 931 on Solaris 8. This trace was collected using:</p> 932 933 <div class="example"><p><code> 934 truss -l -p <var>httpd_child_pid</var>. 935 </code></p></div> 936 937 <p>The <code>-l</code> option tells truss to log the ID of the 938 LWP (lightweight process--Solaris's form of kernel-level thread) 939 that invokes each system call.</p> 940 941 <p>Other systems may have different system call tracing utilities 942 such as <code>strace</code>, <code>ktrace</code>, or <code>par</code>. 943 They all produce similar output.</p> 944 945 <p>In this trace, a client has requested a 10KB static file 946 from the httpd. Traces of non-static requests or requests 947 with content negotiation look wildly different (and quite ugly 948 in some cases).</p> 949 950 <div class="example"><pre>/67: accept(3, 0x00200BEC, 0x00200C0C, 1) (sleeping...) 951 /67: accept(3, 0x00200BEC, 0x00200C0C, 1) = 9</pre></div> 952 953 <p>In this trace, the listener thread is running within LWP #67.</p> 954 955 <div class="note">Note the lack of <code>accept(2)</code> serialization. On this 956 particular platform, the worker MPM uses an unserialized accept by 957 default unless it is listening on multiple ports.</div> 958 959 <div class="example"><pre>/65: lwp_park(0x00000000, 0) = 0 960 /67: lwp_unpark(65, 1) = 0</pre></div> 961 962 <p>Upon accepting the connection, the listener thread wakes up 963 a worker thread to do the request processing. In this trace, 964 the worker thread that handles the request is mapped to LWP #65.</p> 965 966 <div class="example"><pre>/65: getsockname(9, 0x00200BA4, 0x00200BC4, 1) = 0</pre></div> 967 968 <p>In order to implement virtual hosts, Apache needs to know 969 the local socket address used to accept the connection. It 970 is possible to eliminate this call in many situations (such 971 as when there are no virtual hosts, or when 972 <code class="directive"><a href="../mod/mpm_common.html#listen">Listen</a></code> directives 973 are used which do not have wildcard addresses). But 974 no effort has yet been made to do these optimizations. </p> 975 976 <div class="example"><pre>/65: brk(0x002170E8) = 0 977 /65: brk(0x002190E8) = 0</pre></div> 978 979 <p>The <code>brk(2)</code> calls allocate memory from the heap. 980 It is rare to see these in a system call trace, because the httpd 981 uses custom memory allocators (<code>apr_pool</code> and 982 <code>apr_bucket_alloc</code>) for most request processing. 983 In this trace, the httpd has just been started, so it must 984 call <code>malloc(3)</code> to get the blocks of raw memory 985 with which to create the custom memory allocators.</p> 986 987 <div class="example"><pre>/65: fcntl(9, F_GETFL, 0x00000000) = 2 988 /65: fstat64(9, 0xFAF7B818) = 0 989 /65: getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B910, 2190656) = 0 990 /65: fstat64(9, 0xFAF7B818) = 0 991 /65: getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B914, 2190656) = 0 992 /65: setsockopt(9, 65535, 8192, 0xFAF7B918, 4, 2190656) = 0 993 /65: fcntl(9, F_SETFL, 0x00000082) = 0</pre></div> 994 995 <p>Next, the worker thread puts the connection to the client (file 996 descriptor 9) in non-blocking mode. The <code>setsockopt(2)</code> 997 and <code>getsockopt(2)</code> calls are a side-effect of how 998 Solaris's libc handles <code>fcntl(2)</code> on sockets.</p> 999 1000 <div class="example"><pre>/65: read(9, " G E T / 1 0 k . h t m".., 8000) = 97</pre></div> 1001 1002 <p>The worker thread reads the request from the client.</p> 1003 1004 <div class="example"><pre>/65: stat("/var/httpd/apache/httpd-8999/htdocs/10k.html", 0xFAF7B978) = 0 1005 /65: open("/var/httpd/apache/httpd-8999/htdocs/10k.html", O_RDONLY) = 10</pre></div> 1006 1007 <p>This httpd has been configured with <code>Options FollowSymLinks</code> 1008 and <code>AllowOverride None</code>. Thus it doesn't need to 1009 <code>lstat(2)</code> each directory in the path leading up to the 1010 requested file, nor check for <code>.htaccess</code> files. 1011 It simply calls <code>stat(2)</code> to verify that the file: 1012 1) exists, and 2) is a regular file, not a directory.</p> 1013 1014 <div class="example"><pre>/65: sendfilev(0, 9, 0x00200F90, 2, 0xFAF7B53C) = 10269</pre></div> 1015 1016 <p>In this example, the httpd is able to send the HTTP response 1017 header and the requested file with a single <code>sendfilev(2)</code> 1018 system call. Sendfile semantics vary among operating systems. On some other 1019 systems, it is necessary to do a <code>write(2)</code> or 1020 <code>writev(2)</code> call to send the headers before calling 1021 <code>sendfile(2)</code>.</p> 1022 1023 <div class="example"><pre>/65: write(4, " 1 2 7 . 0 . 0 . 1 - ".., 78) = 78</pre></div> 1024 1025 <p>This <code>write(2)</code> call records the request in the 1026 access log. Note that one thing missing from this trace is a 1027 <code>time(2)</code> call. Unlike Apache 1.3, Apache 2.x uses 1028 <code>gettimeofday(3)</code> to look up the time. On some operating 1029 systems, like Linux or Solaris, <code>gettimeofday</code> has an 1030 optimized implementation that doesn't require as much overhead 1031 as a typical system call.</p> 1032 1033 <div class="example"><pre>/65: shutdown(9, 1, 1) = 0 1034 /65: poll(0xFAF7B980, 1, 2000) = 1 1035 /65: read(9, 0xFAF7BC20, 512) = 0 1036 /65: close(9) = 0</pre></div> 1037 1038 <p>The worker thread does a lingering close of the connection.</p> 1039 1040 <div class="example"><pre>/65: close(10) = 0 1041 /65: lwp_park(0x00000000, 0) (sleeping...)</pre></div> 1042 1043 <p>Finally the worker thread closes the file that it has just delivered 1044 and blocks until the listener assigns it another connection.</p> 1045 1046 <div class="example"><pre>/67: accept(3, 0x001FEB74, 0x001FEB94, 1) (sleeping...)</pre></div> 1047 1048 <p>Meanwhile, the listener thread is able to accept another connection 1049 as soon as it has dispatched this connection to a worker thread (subject 1050 to some flow-control logic in the worker MPM that throttles the listener 1051 if all the available workers are busy). Though it isn't apparent from 1052 this trace, the next <code>accept(2)</code> can (and usually does, under 1053 high load conditions) occur in parallel with the worker thread's handling 1054 of the just-accepted connection.</p> 1055 1056 </div></div> 1057 <div class="bottomlang"> 1058 <p><span>Available Languages: </span><a href="../en/misc/perf-tuning.html" title="English"> en </a> | 1059 <a href="../ko/misc/perf-tuning.html" hreflang="ko" rel="alternate" title="Korean"> ko </a> | 1060 <a href="../tr/misc/perf-tuning.html" hreflang="tr" rel="alternate" title="Türkçe"> tr </a></p> 1061 </div><div class="top"><a href="#page-header"><img src="../images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed again by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Freenode, or sent to our <a href="http://httpd.apache.org/lists.html">mailing lists</a>.</div> 1062 <script type="text/javascript"><!--//--><![CDATA[//><!-- 1063 var comments_shortname = 'httpd'; 1064 var comments_identifier = 'http://httpd.apache.org/docs/2.2/misc/perf-tuning.html'; 1065 (function(w, d) { 1066 if (w.location.hostname.toLowerCase() == "httpd.apache.org") { 1067 d.write('<div id="comments_thread"><\/div>'); 1068 var s = d.createElement('script'); 1069 s.type = 'text/javascript'; 1070 s.async = true; 1071 s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier; 1072 (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s); 1073 } 1074 else { 1075 d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>'); 1076 } 1077 })(window, document); 1078 //--><!]]></script></div><div id="footer"> 1079 <p class="apache">Copyright 2017 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p> 1080 <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!-- 1081 if (typeof(prettyPrint) !== 'undefined') { 1082 prettyPrint(); 1083 } 1084 //--><!]]></script> 1085 </body></html>