Sep 15

1) Added or make sure your machine has two or more ip’s
2) Open a command prompt
3) Type netsh
4) Type http
5) Type sho iplisten. It should be blank
6) Type add iplisten ipaddress=192.168.0.90
You should get IP address successfully added
7) Type sho iplisten again
It should sho 192.168.0.90 in the list
8) Type exit to get out of netsh
9) Type type netstat -an. See if you notice 192.168.0.90:80 in the list. If you see 0.0.0.0:80, do an iisreset
10) Download and install Apache ( I did it with 2.2.4)
http://mirror.nyi.net/apache/httpd/binaries/win32/apache_2.2.4-win32-x86…
11) Do a default install,
12) Open httpd.conf and adjust the ip listen to 192.168.0.91:80

# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, instead of the default. See also the
# directive.
#
# Change this to Listen on specific IP addresses as shown below to
# prevent Apache from glomming onto all bound IP addresses (0.0.0.0)
#
#Listen 12.34.56.78:80
#Was 80
#Change to

Listen 192.168.0.91:80

12) Restart the Apache service. (for some reason the start / stop thing didn’t work for me, I used net stop apache2 net start apache2.)
13) Type netstat -an
14) You should see 192.168.0.90:80 and 192.168.0.91:80. Open a browser and test both IP’s to see if IIS7 and Apache come up.
15) Test restarting Apache service to see if it works after that.
16) Turn off Apache, browse IIS, turn of IIS, browse Apache. Test it every which way to see if it works.

Tagged with:
Nov 17

Linux, Apache, MySQL and PHP (or Perl) is the basis for many Web applications – from to-do list to blog, then e-commerce site.  WordPress and Pligg are two high-capacity Web site to support a common package.  This architecture referred to as LAMP.  Almost every Linux release contains Apache, MySQL, PHP and Perl, so installing LAMP software is very easy.

Install the misleading simplicity of the software run smoothly on their own, but it is not the case.  Finally, application load will exceed the set comes with back-end server processing power, application performance will be reduced.  LAMP installation requires constant monitoring, tuning and evaluation.

System tuning for different people have different meanings.  This series focuses on components of LAMP (Linux, Apache, MySQL and PHP) tuning.  On tuning the application itself is another complex issue. Back-end server applications, and there is a symbiotic relationship: the server not properly tuned or even the best application would collapse under the load, and tuning with fully, completely avoid the very bad writing application makes the server slow as an ox. Fortunately, the proper system tuning and monitoring can be pointed out that the application in question.

LAMP Architecture

Tuning of any system is the first step in understanding how it works. According to the most simple form, LAMP-based application is written in scripting languages like PHP, they are running on a Linux host part of the Apache Web server running.

PHP applications through the request URL, all the form data and session information has been captured by any access to information from the client to determine what action should be performed.  If necessary, from the MySQL database server (also running on Linux) access to information, some of this information with the Hypertext Markup Language (HTML) templates together, and returns the results to the client. When the user navigate in the application, this process is repeated; when multiple users access the system, this process will be conducted concurrently.  However, the data flow is not unidirectional, because you can use the information from the user to update the database, including session data, statistical data (including voting), and user submitted content (like comments or site update). In addition to dynamic elements, there are static elements, such as images, JavaScript code and Cascading Style Sheets (CSS).

LAMP system in the study at the request stream, take a look at where performance bottlenecks can occur. Provides a number of dynamic information database, the database query response delay will be reflected in the client machine. Web server must be able to quickly execute the script, but also be able to handle multiple concurrent requests. Finally, the underlying operating system must be in good condition to support the application.  Through the network to share files between different servers in other settings may also become a bottleneck.

Performance metrics

Continuous measure of the performance of help in two ways.  First, the performance metrics can help us understand trends, including trends in both good and bad.  As a simple way to look at the Web server central processing unit (CPU) usage, CPU can understand is overloaded.  Also, see the total bandwidth used in the past and to infer future changes that can help determine when the need for network upgrades. The best measure of integration with other measurements and observations to consider.  For example, when users complain about slow application, you can check the disk operation is reaching maximum capacity.

The second use of performance metrics is to determine system performance tuning is a help, or make it worse.  Comparison of change is measured before and after results. However, to make a valid comparison, each should only modify a set of appropriate indicators and then compared to determine the effect of changes. Set a time to modify a reason should be obvious: while the two changes made are likely to affect each other. Selected for comparison of more subtle indicators.

The indicators selected reflect the application user must be able to feel the response. If a revised goal is to reduce the memory footprint of the database, then the cancellation of various buffer will certainly help, but at the expense of query speed and application performance. Therefore, we should select the application response time such indicators, which makes tuning in the right direction, not just for the database memory usage.

Can be measured in many ways the application response time. The easiest way might be to use curl command, as shown in Listing 1.

Listing 1. Using cURL measure the response time of Web site            
$ Curl-o / dev / null-s-w% {time_connect}:% {time_starttransfer}:% {time_total} \
        http://www.test.com

0.081:0.272:0.779

Table 1. curl to use the timer

Timer                           Description

time_connect               TCP connection to the server’s time spent

time_starttransfer        After the request, Web server returns the first byte of the data used in the time

time_total                    The time spent to complete the request

These timers are relative to the transaction start time, or even first in the Domain Name Service (DNS) query.  Therefore, after the request, Web server processes the request and sends back data starting time used 0.272 – 0.081 = 0.191 seconds. Download data from the server the client’s time is used by 0.779 – 0.272 = 0.507 seconds.

By observing the curl data and trends over time, one can see the site’s responsiveness to users.

Of course, Web sites not only by the pages. It also has images, JavaScript code, CSS and cookie to deal with. curl is very suitable for understanding the response time of a single element, but sometimes need to understand the entire page loading speed.

For the Tamper Data Firefox browser extensions (see Resources section for a link) can be recorded in the log for each Web browser sends a request, and displays each request with download time. Method is to use this extension, select Tools> Tamper Data to open the Ongoing requests window. To visit the page loaded, and then the browser will see the status of each request sent and the load time spent for each element.  Figure 1 shows the results of loading developerWorks home page.

Figure 1. DeveloperWorks home page used to load the request of a breakdown

Each line describes one element of the load situation. The data displayed includes the request time, loading time used, size, and results.  Load Duration column lists the time used by the elements themselves, Total Duration column lists all of the time used by child elements.  In Figure 1, the main page loading time is used in 516 milliseconds (ms), but everything loads and displays the time used by the entire page is 5101 ms.

Tamper Data extension there is a useful model, the output of the page to load data into the graphics rendering.  Ongoing requests window, right-click anywhere in the upper part, and select the Graph all. Figure 1 Figure 2 shows a graphical view of data.

Figure 2. DeveloperWorks home page used to load a graphical view of the request

In Figure 2, the duration of each request is displayed as dark blue, and relative to the start time loading the page display.  So, you can see which requests the entire page load slower.

Although the focus is on the page load times and user experience, but do not ignore the core system indicators, such as disk, memory, and network.  There are many utilities to capture this information; which may be the most helpful sar , vmstat and iostat . For more information about these tools, see the Resources section.


Adjust the basic system

The system in Apache, PHP and MySQL tuning components, you should take some time to ensure that components of the underlying Linux operating normally.  It should also be running services on the reduction, only those services required for the operation. This is not only a good security practice, but it will save memory and CPU time.

Kernel tuning some quick measures

Most Linux distributions are defined in the appropriate buffers and other Transmission Control Protocol (TCP) parameters. These parameters can be modified to allocate more memory, thus improving network performance. Set the kernel parameters is through proc interface, that is, through reading and writing /proc values. Fortunately, sysctl can read /etc/sysctl.conf in the value and need to fill under the /proc , so it can more easily manage these parameters.  Listing 2 shows the Internet server Internet server used in some of the more radical of the network settings.

Listing 2. Contains more radical network settings / etc / sysctl.conf    
# Use TCP syncookies when needed
net.ipv4.tcp_syncookies = 1
# Enable TCP window scaling
net.ipv4.tcp_window_scaling: = 1
# Increase TCP max buffer size
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
# Increase Linux autotuning TCP buffer limits
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# Increase number of ports available
net.ipv4.ip_local_port_range = 1024 65000

These settings will be added to /etc/sysctl.conf existing content. The first setting enables TCP SYN cookie.  Sent from the client when a new TCP connection, the SYN packet bit is set, the server connection for the half-open to create an entry, and with a SYN-ACK packet response.  In normal operation, the remote client machine responds with an ACK packet, which will convert the half-open connection to fully open. There is a known as SYN flood (SYN flood) attacks on the network, it can not return the ACK packet, causes the server to run out of memory space, can not handle incoming connections. SYN cookie feature can identify this situation and elegant way to use a reserved space in the queue (for details see reference section). Most systems have this feature enabled by default, but make sure to configure this feature and more reliable.

Enable TCP window stretching to the client to download data at higher speeds.  TCP is not allowed to receive confirmation from the remote end of the case to send multiple packets, the default setting is up to 64 KB, and delay in large remote clients to communicate in this setting may not be enough.  Retractable window will enable more in the first place, thereby increasing the window size.

Four configuration options increase the TCP after sending and receiving buffer. This allows applications to quickly lose its data, so as to request another service. You can also strengthen the remote client when the server is busy sending data.

Finally, a configuration to increase the number of available local port, so that services can increase the maximum number of connections.

The next boot, or the next time you run sysctl -p /etc/sysctl.conf , these settings will take effect.

 Configure disk to improve performance

Disk in the LAMP architecture plays an important role. Static files, templates, and code from disk, composed of the database tables and indexes are from the disk.  Many of the tuning disk (especially for the database) to focus on avoiding disk access, because the disk access latency is quite high.  Therefore, spend some time on the disk hardware optimization is meaningful.

The first step is to ensure that the file system to disable atime logging features.  atime is the time to access files recently, when accessing the file, the underlying file system must record the time stamp. Rarely used because the system administrator atime , disable it can reduce disk access time. This feature is disabled in /etc/fstab to add the fourth column noatime option.  Listing 3 shows an example configuration.

Listing 3. Demonstrates how to enable noatime in fstab example

/dev/VolGroup00/LogVol00 /         ext3    defaults,noatime 1 1
LABEL=/boot             /boot      ext3    defaults,noatime 1 2 
devpts                  /dev/pts   devpts  gid=5,mode=620   0 0
tmpfs                   /dev/shm   tmpfs   defaults         0 0
proc                    /proc      proc    defaults         0 0
sysfs                   /sys       sysfs   defaults         0 0
LABEL=SWAP-hdb2         swap       swap    defaults         0 0
LABEL=SWAP-hda3         swap       swap    defaults         0 0
 
 In Listing 3, only modified the ext3 file system, because the noatime only 
reside on disk file system helpful.  To make the changes to take effect, 
do not need to reboot; just re-mount each file system.  For example, 
to re-mount the root file system, run the mount / -o remount.

Combination of a variety of disk hardware and Linux to access the disk may not be able to detect the best way.  Can use the hdparm command to identify and set the method used to access IDE disks.  hdparm -t /path/to/device speed test, the results of this test can be used as performance benchmarks.  To make the results as accurate as possible, run this command in the system should be idle. Listing 4 shows the hda speed test on the results.

Listing 4. In the /dev/hd speed test performed on

# Hdparm-t / dev / hda
/dev/hda: / Dev / hda:
Timing buffered disk reads:  182 MB in  3.02 seconds =  60.31 MB/sec 
This test shows that in the read data on the disk per second speed is about 60MB.
 

Tuning in to try some disk option, you must pay attention to a problem.  Wrong setting could damage the file system.  Sometimes there will be a warning that this option is not compatible with the hardware; However, sometimes there is no warning message. Therefore, the system into production, you must thoroughly test the settings.  All servers are standard hardware would also help.

Table 2 lists some of the more common options.

Table 2. hdparm common options

Options             Description

-vi –Vi               It supports to set the disk check, and it is set.

-c –C                 hdparm -c 1 /dev/hda enable this setting.

-m –M               uery / set the interrupt for each multi-sector model.  If set greater than zero, set the value is the maximum that can be transmitted for each interrupt number of sectors.

-d 1 -X -D 1-X  Enable Direct Memory Access (DMA) transfer and set the IDE transfer mode. hdparm man page for details in the -X can be set behind the figures. Only in -vi that is not currently the fastest mode of use cases, only the need for this setting.

Unfortunately, for the Fiber Channel and Small Computer Systems Interface (SCSI) system, tuning depends on the specific drive.

Settings must be added to help start the script, such as rc.local .

Network File System tuning

Network File System (NFS) is a network shared disk method.  NFS can help ensure that each host has the same copy of the data and to ensure changes are reflected in all nodes. However, by default, NFS is not configured for high-capacity disk.

Each client should use rsize=32768,wsize=32768,intr,noatime mount remote file system to ensure that:

  • Use of large read / write block (number specifies the maximum block size, in this example is 32KB).
  • When the pending NFS operations can be interrupted.
  • Not continuously updated atime .

These settings can be placed in /etc/fstab in, see Listing 3 .  If you use the automatic mounting device, you should apply these settings in the appropriate /etc/auto.* files.

On the server side, we must ensure that adequate NFS kernel threads to handle all clients. By default, only start a thread, but Red Hat and Fedora system will start 8 threads. For a busy NFS server, this number should be increased, such as 32 or 64.  Can nfsstat -rc command client assessment to see whether the phenomenon of blocking, the command displays the client remote procedure call (RPC) statistics. 

Listing 5 shows a Web server, client statistics.

Listing 5. Display NFS client RPC statistics          
# nfsstat -rc # Nfsstat-rc
Client rpc stats: Client rpc stats:
calls      retrans    authrefrsh calls retrans authrefrsh
1465903813   0          0 146590381300      

The second column retrans is zero, which means that since the last reboot from no need to re-transfer situation.  If this number is relatively large, they should consider increasing the NFS kernel threads.  Setting method is to pass the required number of threads rpc.nfsd , such as rpc.nfsd 128 starts 128 threads. Any time for such settings.  Thread will be needed to start or destroyed. Similarly, this setting should be placed in the startup script, especially in the NFS system to enable scripting.

On the NFS, the last thing to note: if possible, should be avoided NFSv2, because the performance NFSv2 much less than the v3 and v4.  In the modern Linux distributions should not be a problem in that, but you can check on the server nfsstat the output to see if there are any NFSv2 call.

Tagged with:
Mar 15

With the release of Apache 2.2.12, we can now configure multiple SSL sites in one IP address. It is available of you have Server Name Indication (SNI) extension for OpenSSL. Visit TechRepublic’s post on “Configure Apache to support multiple SSL sites on a single IP address” for details and vhost sample configuration. And for complete reference please refer to this page “SSL with Virtual Hosts Using SNI” and Apache mod_ssl documentation.

We’ll try this on our server and hopefully offer this to our shared hosting clients who wants SSL but not interested in paying extra for a dedicated ip address

Tagged with:
Mar 12

With the release of Apache 2.2.12, we can now configure multiple SSL sites in one IP address. It is available of you have Server Name Indication (SNI) extension for OpenSSL. Visit TechRepublic’s post on “Configure Apache to support multiple SSL sites on a single IP address” for details and vhost sample configuration. And for complete reference please refer to this page “SSL with Virtual Hosts Using SNI” and Apache mod_ssl documentation.

We’ll try this on our server and hopefully offer this to our shared hosting clients who wants SSL but not interested in paying extra for a dedicated ip address.

Tagged with:
Feb 22

Many of our readers are asking what KeepAliveTimeout setting should be used for Apache config. We usually select 2 to 5 seconds as it provides best performance for sites with medium visitors and prefer to use Nginx or any other front-end proxy to better manage thousands of multiple concurrent users.

Tagged with:
Nov 30

Close Etag for Apache:

FileETag none

If you want to close Last-Modified keyword, you need load header module and modified httpd.conf.

LoadModule headers_module modules/mod_headers.so

<FilesMatch "\.(gif|jpg|png)">
Header unset Last-Modified
</FilesMatch>

Tagged with:
Sep 10

Description: How to disable the HTTP TRACE method on recent apache versions.

Most vulnerability scanners (like the popular nessus, but commercial ones also) will complain (normally as a low thread or warning level) about TRACE method being enabled on the web server tested.

Normally you will have this enabled by default, but if you want to test if it is really enabled on your server you just have to telnet on the port your web server is running and request for “TRACE / HTTP/1.0” if you get a positive reply it means TRACE is enabled on your system. The output of a server with TRACE enabled will look like:

telnet 127.0.0.1 80 Trying 127.0.0.1… Connected to 127.0.0.1. Escape character is ‘^]’.
TRACE / HTTP/1.0 Host: foo Any text entered here will be echoed back in the response <- ENTER twice to finish HTTP/1.1 200 OK
Date: Wed, 10 Sep 2009 22:19:36 GMT
Server: Apache/2.2.6 (Debian) PHP/4.4.4-9 mod_ruby/1.2.6 Ruby/1.8.6(2007-06-07)
Connection: close
Content-Type: message/http TRACE / HTTP/1.0
Host: foo Any text entered here will be echoed back in the response Connection closed by foreign host.

Traditionally experts will suggest to disable this using some rewrite rules like:

RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^TRACE
RewriteRule .* - [F]

(this needs to be added somewhere in your main apache config file outside of any vhost or directory config).

Still this has the disadvantage that you need to have mod_rewrite enabled on the server just to mention one. But for apache versions newer than 1.3.34 for the legacy branch, and 2.0.55 (or newer) for apache2 this can be done very easily because there is a new apache variable that controls if TRACE method is enabled or not:
TraceEnable off
This needs to be added in the main server config and the default is enabled (on). TraceEnable off causes apache to return a 403 FORBIDDEN error to the client.

After setting this and reloading the apache config the same server as above shows:

telnet 127.0.0.1 80
Trying 127.0.0.1… Connected to 127.0.0.1.
Escape character is ‘^]’.
TRACE / HTTP/1.0 Host: foo testing… <- ENTER twice HTTP/1.1 403 Forbidden
Date: Wed, 20 Sep 2009 22:28:31 GMT
Server: Apache/2.2.6 (Debian) PHP/4.4.4-9 mod_ruby/1.2.6 Ruby/1.8.6(2007-06-07)
Content-Length: 320 Connection: close
Content-Type: text/html;
charset=iso-8859-1
<!DOCTYPE HTML(link) PUBLIC "-//IETF//DTD HTML(link) 2.0//EN">
<html>
<head>
<title>403 Forbidden</title>
</head>
<body>
<h1>Forbidden</h1>
<p>You don’t have permission to access / on this server.</p>
<hr> <address>Apache/2.2.6 (Debian) PHP/4.4.4-9 mod_ruby/1.2.6 Ruby/1.8.6(2007-06-07) Server at foo Port 80</address>
</body>
</html>
Connection closed by foreign host.

Tagged with:
Jul 14

This document covers stopping and restarting Apache on Unix only.

You will notice many httpd executables running on your system, but you should not send signals to any of them except the parent, whose pid is in the PidFile. That is to say you shouldn’t ever need to send signals to any process except the parent. There are three signals that you can send the parent: TERM, HUP, and USR1, which will be described in a moment.

To send a signal to the parent you should issue a command such as:

    kill -TERM `cat /usr/local/apache/logs/httpd.pid`

You can read about its progress by issuing:

    tail -f /usr/local/apache/logs/error_log

Modify those examples to match your ServerRoot and PidFile settings.

As of Apache 1.3 we provide a script called apachectl which can be used to start, stop, and restart Apache. It may need a little customization for your system, see the comments at the top of the script.

TERM Signal: stop now

Sending the TERM signal to the parent causes it to immediately attempt to kill off all of its children. It may take it several seconds to complete killing off its children. Then the parent itself exits. Any requests in progress are terminated, and no further requests are served.

HUP Signal: restart now

Sending the HUP signal to the parent causes it to kill off its children like in TERM but the parent doesn’t exit. It re-reads its configuration files, and re-opens any log files. Then it spawns a new set of children and continues serving hits.

Users of the status module will notice that the server statistics are set to zero when a HUP is sent.

Note: If your configuration file has errors in it when you issue a restart then your parent will not restart, it will exit with an error. See below for a method of avoiding this.

USR1 Signal: graceful restart

Note: prior to release 1.2b9 this code is quite unstable and shouldn’t be used at all.

The USR1 signal causes the parent process to advise the children to exit after their current request (or to exit immediately if they’re not serving anything). The parent re-reads its configuration files and re-opens its log files. As each child dies off the parent replaces it with a child from the new generation of the configuration, which begins serving new requests immediately.

This code is designed to always respect the MaxClients, MinSpareServers, and MaxSpareServers settings. Furthermore, it respects StartServers in the following manner: if after one second at least StartServers new children have not been created, then create enough to pick up the slack. This is to say that the code tries to maintain both the number of children appropriate for the current load on the server, and respect your wishes with the StartServers parameter.

Users of the status module will notice that the server statistics are not set to zero when a USR1 is sent. The code was written to both minimize the time in which the server is unable to serve new requests (they will be queued up by the operating system, so they’re not lost in any event) and to respect your tuning parameters. In order to do this it has to keep the scoreboard used to keep track of all children across generations.

The status module will also use a G to indicate those children which are still serving requests started before the graceful restart was given.

At present there is no way for a log rotation script using USR1 to know for certain that all children writing the pre-restart log have finished. We suggest that you use a suitable delay after sending the USR1 signal before you do anything with the old log. For example if most of your hits take less than 10 minutes to complete for users on low bandwidth links then you could wait 15 minutes before doing anything with the old log.

Note: If your configuration file has errors in it when you issue a restart then your parent will not restart, it will exit with an error. In the case of graceful restarts it will also leave children running when it exits. (These are the children which are "gracefully exiting" by handling their last request.) This will cause problems if you attempt to restart the server — it will not be able to bind to its listening ports. Before doing a restart, you can check the syntax of the configuration files with the -t command line argument. This still will not guarantee that the server will restart correctly. To check the semantics of the configuration files as well as the syntax, you can try starting httpd as a non-root user. If there are no errors it will attempt to open its sockets and logs and fail because it’s not root (or because the currently running httpd already has those ports bound). If it fails for any other reason then it’s probably a config file error and the error should be fixed before issuing the graceful restart.

Appendix: signals and race conditions

Prior to Apache 1.2b9 there were several race conditions involving the restart and die signals (a simple description of race condition is: a time-sensitive problem, as in if something happens at just the wrong time it won’t behave as expected). For those architectures that have the "right" feature set we have eliminated as many as we can. But it should be noted that there still do exist race conditions on certain architectures.

Architectures that use an on disk ScoreBoardFile have the potential to corrupt their scoreboards. This can result in the "bind: Address already in use" (after HUP) or "long lost child came home!" (after USR1). The former is a fatal error, while the latter just causes the server to lose a scoreboard slot. So it might be advisable to use graceful restarts, with an occasional hard restart. These problems are very difficult to work around, but fortunately most architectures do not require a scoreboard file. See the ScoreBoardFile documentation for a architecture uses it.

NEXT and MACHTEN (68k only) have small race conditions which can cause a restart/die signal to be lost, but should not cause the server to do anything otherwise problematic.

All architectures have a small race condition in each child involving the second and subsequent requests on a persistent HTTP connection (KeepAlive). It may exit after reading the request line but before reading any of the request headers. There is a fix that was discovered too late to make 1.2. In theory this isn’t an issue because the KeepAlive client has to expect these events because of network latencies and server timeouts. In practice it doesn’t seem to affect anything either — in a test case the server was restarted twenty times per second and clients successfully browsed the site without getting broken images or empty documents.

Tagged with:
Jul 06

Linux, Apache, MySQL, and PHP (or Perl) form the basis of the LAMP architecture for Web applications. Many open source packages based on LAMP components are available to solve a variety of problems. As the load on an application increases, the bottlenecks in the underlying infrastructure become more apparent in the form of slow response to user requests. The previous article showed you how to tune the Linux system and covered the basics of LAMP and performance measurement. This article focuses on the Web server components, Apache and PHP.

Tuning Apache

Apache is a highly configurable piece of software. It has a lot of features, but each one comes at a price. Tuning Apache is partially an exercise in proper allocation of resources, and involves stripping down the configuration to only what’s needed.

Configuring the MPM

Apache is modular in that you can add and remove features easily. Multi-Processing Modules (MPMs) provide this modular functionality at the core of Apache — managing the network connections and dispatching the requests. MPMs let you use threads or even move Apache to a different operating system.

Only one MPM can be active at one time, and it must be compiled in statically with --with-mpm=(worker|prefork|event).

The traditional model of one process per request is called prefork. A newer, threaded, model is called worker, which uses multiple processes, each with multiple threads to get better performance with lower overhead. The final, event MPM is an experimental module that keeps separate pools of threads for different tasks. To determine which MPM you’re currently using, execute httpd -l.

Choosing the MPM to use depends on many factors. Setting aside the event MPM until it leaves experimental status, it’s a choice between threads or no threads. On the surface, threading sounds better than forking, if all the underlying modules are thread safe, including all the libraries used by PHP. Prefork is the safer choice; you should do careful testing if you choose worker. The performance gains also depend on the libraries that come with your distribution and your hardware.

Regardless of which MPM you choose, you must configure it appropriately. In general, configuring an MPM involves telling Apache how to control how many workers are running, whether they’re threads or processes. The important configuration options for the prefork MPM are shown in Listing 1.

Listing 1. Configuration of the prefork MPM

StartServers       50
MinSpareServers   15
MaxSpareServers   30
MaxClients       225
MaxRequestsPerChild  4000

In the prefork model, a new process is created per request. Spare processes are kept idle to handle incoming requests, which reduces the start-up latency. The previous configuration starts 50 processes as soon as the Web server comes up and tries to keep between 10 and 20 idle servers running. The hard limit on processes is dictated by MaxClients. Even though a process can handle many consecutive requests, Apache kills off processes after 4,000 connections, which mitigates the risk of memory leaks.

Configuring the threaded MPMs is similar, except that you must determine how many threads and processes are to be used. The Apache documentation explains all the parameters and calculations necessary.

Choosing the values to use involves some trial and error. The most important value is MaxClients. The goal is to allow enough worker processes or threads to run without causing your server to swap excessively. If more requests come in than can be handled, then at least those that made it through get service; the others are blocked.

If MaxClients is too high, then all clients experience poor service because the Web server tries to swap out one process to allow another one to run. Too low a setting means you may deny services unnecessarily. Checking the number of processes running at high loads and the resulting memory footprint of all the Apache processes gives you a good idea of how to set this value. If you go over 256 MaxClients, you must also set ServerLimit to the same number; read the MPM’s documentation carefully for the associated caveats.

Tuning the number of servers to start and keep spare depends on the role of the server. If the server runs only Apache, you can use modest values as shown in Listing 1, because you’re able to make full use of the machine. If the system is shared with a database or other server, then you should limit the number of spare servers being run.

Using options and overrides efficiently

Each request that Apache processes goes through a complicated set of rules that dictates any restrictions or special instructions the Web server must follow. Access to a folder can be restricted by IP address to a certain folder, or a username and password can be configured. These options also include the handling of certain files, such as if a directory listing is provided, how certain filetypes are to be handled, or whether the output should be compressed.

These configurations take the form of containers in httpd.conf such as <Directory> to specify that the configuration to follow refers to a location on disk, or <Location> to indicate that the reference is to a path in the URL. Listing 2 shows a Directory container in action.

Listing 2. A Directory container being applied to the root directory

<Directory />
    AllowOverride None
    Options FollowSymLinks
</Directory>

In Listing 2, the configuration enclosed in the Directory and /Directory tags is applied to the given directory and everything under it — in this case, the root directory. Here, the AllowOverride tag dictates that users aren’t allowed to override any options (more on this later). The FollowSymLinks option is enabled, which lets Apache look past symlinks to serve the request, even if the file is outside the directory containing Web files. This means that if a file in your Web directory is a symlink to /etc/passwd, the Web server happily serves the file if asked. With -FollowSymLinks used instead, this feature is disabled, and the same request causes an error to be returned to the client.

This last scenario is a cause for concern on two fronts. The first is a performance matter. If FollowSymLinks is disabled, then Apache must check each component of the filename (directories and the file itself) to make sure they’re not symbolic links. This incurs extra overhead in the form of disk activity. A companion option called FollowSymLinksIfOwnerMatch follows the symbolic link if the owner of the file is the same as that of the link. This has the same performance hit as disabling following of symlinks. For best performance, use the options in Listing 2.

Security-conscious readers should be alert by now. Security is always a trade-off between functionality and risk. In this case, the functionality is speed, and the risk is allowing unauthorized access to files on the system. One of the mitigations is that LAMP application servers are generally dedicated to a particular function, and users can’t create the potentially dangerous symbolic links. If it’s vital to have symbolic link-checking enabled, you can restrict it to a particular area of the file system, as in Listing 3.

Listing 3. Restricting FollowSymLinks to a user’s directory

<Directory />
   Options FollowSymLinks
</Directory>

<Directory /home/*/public_html>
   Options -FollowSymLinks
</Directory>

In Listing 3, any public_html directory in a user’s home directory has the FollowSymLinks option removed for it and any child directories.

As you’ve seen, options can be configured on a per-directory basis through the main server configuration. Users can override this server configuration themselves (if permitted by the administrator by the AllowOverrides statement) by dropping a file called .htaccess into a directory. This file contains additional server directives that are loaded and followed on each request to the directory where the .htaccess file resides. Despite the earlier discussion about not having users on the system, many LAMP applications use this functionality to control access and for URL rewriting, so it’s wise to understand how it works.

Even though the AllowOverrides statement prevents users from doing anything you don’t want them to, Apache must still look for the .htaccess file to see if there is any work to be done. A parent directory can specify directives that are to be processed by requests from child directories, which means Apache must also search each component of the directory tree leading to the requested file. Understandably, this causes a great deal of disk activity on each request.

The easiest solution is to not allow any overrides, which eliminates the need for Apache to check for .htaccess. Any special configurations are then placed directly in httpd.conf. Listing 4 shows the additions to httpd.conf to enable password checking for a user’s project directory, rather than putting in a .htaccess file and relying on AllowOverrides.

Listing 4. Moving .htaccess configuration into httpd.conf

<Directory /home/user/public_html/project/>
  AuthUserFile /home/user/.htpasswd
  AuthName "uber secret project"
  AuthType basic
  Require valid-user
</Directory>

If the configuration is moved into httpd.conf and AllowOverrides is disabled, disk usage can be reduced. A user’s project may not attract many hits, but consider how powerful this technique is when applied to a busy site.

Sometimes it’s not possible to eliminate use of .htaccess files. For example, in Listing 5, where an option is restricted to a certain part of the file system, overrides can also be scoped.

Listing 5. Scoping .htaccess checking

<Directory />
  AllowOverrides None
</Directory>

<Directory /home/*/public_html>
  AllowOverrides AuthConfig
</Directory>

After you implement Listing 5, Apache still looks for .htaccess files in the parent directories, but it stops in the public_html directory because the rest of the file system has the functionality disabled. For example, if a file that maps to /home/user/public_html/project/notes.html is requested, only the public_html and project directories are searched.

One final note about per-directory configurations is in order. Any document about tuning Apache will tell you to disable DNS lookups through the HostnameLookups off directive because trying to reverse-resolve every IP address connecting to your server is a waste of resources. However, any limitations based on hostname force the Web server to perform a reverse lookup on the client’s IP address and a forward lookup on the result of that to verify the authenticity of the name. Therefore, it’s wise to avoid using access controls based on the client’s hostname and to scope them as described when they’re necessary.

Persistent connections

When a client connects to a Web server, it’s allowed to issue multiple requests over the same TCP connection, which reduces the latency associated with multiple connections. This is useful when a Web page refers to several images: The client can request the page and then all the images over one connection. The downside is that the worker process on the server has to wait for the session to be closed by the client before it can move on to the next request.

Apache lets you configure how persistent connections, called keepalives, are handled. KeepAlive 5 at the global level of httpd.conf allows the server to handle 5 requests on a connection before forcing the connection closed. Setting this number to 0 disables the use of persistent connections. KeepAliveTimeout, also at the global level, determines how long Apache will wait for another request before closing the session.

Handling persistent connections isn’t a one-size-fits-all configuration. Some Web sites fare better with keepalives disabled (KeepAlive 0), and some experience a tremendous benefit by having them on. The only solution is to try both and see for yourself. It’s advisable, though, to use a low timeout such as 2 seconds with KeepAliveTimeout 2 if you enable keepalives. This ensures that any client wishing to make another request has ample time, and that worker processes aren’t idling while waiting for another request that may never come.

Compression

The Web server can compress the output before it’s sent back to the client. This results in a smaller page being sent over the Internet at the expense of CPU cycles on the Web server. For those servers that can afford the CPU overhead, this is an excellent way of making pages download faster — it isn’t unheard of for pages to be a third of their size after compression.

Images are generally already compressed, so compression should be limited to text output. Apache provides compression through mod_deflate. Although mod_deflate can be simple to turn on, it includes many complexities that the manual is eager to explain. This article doesn’t cover the configuration of compression except to provide a link to the appropriate documentation (see the Resources section.)

Tuning PHP

PHP is the engine that runs the application code. You should install only the modules you plan to use and have your Web server configured to use PHP only for script files (usually those ending in .php) and not all static files.

Opcode caching

When a PHP script is requested, PHP reads the script and compiles it into what’s called Zend opcode, a binary representation of the code to be executed. This opcode is then executed by the PHP engine and thrown away. An opcode cache saves this compiled opcode and reuses it the next time the page is called. This saves a considerable amount of time. Several opcode caches are available; I’ve had a great deal of success with eAccelerator.

Installing eAccelerator requires the PHP development libraries on your computer. Because different Linux distributions place files in difference places, it’s best to get the installation instructions directly from the eAccelerator Web site (see the Resources section for a link). It’s also possible that your distribution has already packaged an opcode cache, and you just have to install it.

Regardless of how you get eAccelerator on your system, there are a few configuration options to look at. The configuration file is usually /etc/php.d/eaccelerator.ini. eaccelerator.shm_size defines the size of the shared memory cache, which is where the compiled scripts are stored. The value is in megabytes. Determining the proper size depends on your application. eAccelerator provides a script to show the status of the cache, which includes the memory usage; 64 megabytes is a good start (eaccelerator.shm_size="64"). You may also have to tweak your kernel’s maximum shared memory size if the value you choose isn’t accepted. Add kernel.shmmax=67108864 to /etc/sysctl.conf, and run sysctl -p to make the setting take effect. The value for kernel.shmmax is in bytes.

If the shared memory allocation is exceeded, eAccelerator must purge old scripts from memory. By default, this is disabled; eaccelerator.shm_ttl = "60" specifies that when eAccelerator runs out of shared memory, any script that hasn’t been accessed in 60 seconds should be purged.

Another popular alternative to eAccelerator is the Alternative PHP Cache (APC). The makers of Zend also have a commercial opcode cache that includes an optimizer to further increase efficiency.

php.ini

You configure PHP in php.ini. Four important settings control how much system resources PHP can consume, as listed in Table 1.

Table 1. Resource related settings in php.ini

Setting Description Recommended value
max_execution_time How many CPU-seconds a script can consume 30
max_input_time How long (seconds) a script can wait for input data 60
memory_limit How much memory (bytes) a script can consume before being killed 32M
output_buffering How much data (bytes) to buffer before sending out to the client 4096

These numbers depend mostly on your application. If you accept large files from users, then max_input_time may have to be increased, either in php.ini or by overriding it in code. Similarly, a CPU- or memory-heavy program may need larger settings. The purpose is to mitigate the effect of a runaway program, so disabling these settings globally isn’t recommended. Another note on max_execution_time: This refers to the CPU time of the process, not the absolute time. Thus a program that does lots of I/O and few calculations may run for much longer than max_execution_time. It’s also how max_input_time can be greater than max_execution_time

The amount of logging that PHP can do is configurable. In a production environment, disabling all but the most critical logs saves disk writes. If logs are needed to troubleshoot a problem, you can turn up logging as needed. error_reporting = E_COMPILE_ERROR|E_ERROR|E_CORE_ERROR turns on enough logging to spot problems but eliminates a lot of chatter from scripts.


Summary

This article focused on tuning the Web server, both Apache and PHP. With Apache, the general idea is to eliminate extra checks the Web server must do, such as processing the .htaccess file. You must also tune the Multi-Processing Module you’re using to balance the system resources used with the availability of idle workers for incoming requests. The best thing you can do for PHP is to install an opcode cache. Keeping your eye on a few resource settings also ensures that scripts don’t hog resources and make the system slow for everyone else.

The next and final article in this series will look at tuning the MySQL database. Stay tuned!

Tagged with:
Jun 28

There are many important points before you begin compiling Apache. See Using Apache with Microsoft Windows before you begin.

Compiling Apache requires Microsoft Visual C++ 5.0 or 6.0 to be properly installed. It can be built with command-line tools, or within the Visual Studio environment. Consult the VC++ manual to determine how to install them. Be especially aware that the vcvars32.bat file from the Program Files/DevStudio/VC/bin folder, and the setenv.bat file from the Platform SDK, may be required to prepare the command-line tools for command-line builds (e.g. using nmake). To install apache with the Makefile.win or the InstallBin project in the Visual Studio IDE, the awk utility is also required.

First, you should install awk.exe where it can be found in the path and the DevStudio environment, if you plan to use the IDE. There are many versions of awk available for Windows; the easiest to install is available from Brian Kernighan’s http://cm.bell-labs.com/cm/cs/who/bwk/ site. When downloading http://cm.bell-labs.com/cm/cs/who/bwk/awk95.exe from this site, you must save it with the name awk.exe rather than awk95.exe.

Note that DevStudio will only find awk.exe if its location is listed under the Tools menu Options… Directories settings for the Executable files. Add the path for awk.exe to this list, as needed.

Then unpack the Apache distribution into an appropriate directory. Open a command-line prompt, and change to the src subdirectory of the Apache distribution.

The master Apache makefile instructions are contained in the Makefile.win file. To compile Apache on Windows NT, simply use one of the following commands:

  • nmake /f Makefile.win _apacher (release build)
  • nmake /f Makefile.win _apached (debug build)

These will both compile Apache. The latter will include debugging information in the resulting files, making it easier to find bugs and track down problems.

If you get an error such as "the name specified is not recognized…" then you need to run vcvars32.bat first. Enter the following command;

  "c:\Program Files\DevStudio\VC\Bin\VCVARS32.BAT"

(you will need to adjust this command so it matches the directory where your VC was installed.)

If you are a Visual C++ 5.0 user, and have installed a recent Platform SDK, you may also need to enter the following command (adjusted for the install directory of the Platform SDK update);

  "c:\Program Files\Platform SDK\SETENV.BAT"

Then try the nmake command again.

Note that the Windows Platform SDK update is required to enable all supported mod_isapi features. The SDK files distributed with Microsoft Visual C++ 5.0 are out of date. Without a recent update, Apache will issue warnings under MSVC++ 5.0 that some mod_isapi features will be disabled. Look for the update at http://msdn.microsoft.com/downloads/sdks/platform/platform.asp.

Apache can also be compiled using VC++’s Visual Studio development environment. To simplify this process, a Visual Studio workspace, Apache.dsw, is provided in the src folder. This workspace exposes the entire list of working .dsp projects that are required for the complete Apache binary release. It includes dependencies between the projects to assure that they are built in the appropriate order. InstallBin is the top-level project that will build all other projects, and install the compiled files into their proper locations.

These .dsp project files are distributed in Visual C++ 6.0 format. Visual C++ 5.0 (97) will recognize them with the single exception of the /ZI flag, which corresponds to the VC 5.0 /Zi flag for debugging symbols. To quickly prepare the .dsp files for the Visual Studio 5.0 (97), you can use the perl scripts distributed in the src\helpers folder:

  cd src\helpers
  cvstodsp5.pl

This command assumes you have a Perl interpreter installed and registered for files of type .pl. The list of converted .dsp project files will be displayed as they are converted. If you contribute back a patch that offers revised project files, please convert them back with the script dsp5tocvs.pl, which puts the projects back to Visual Studio 6.0 format.

The core .dsp projects built by Apache.dsw and makefile.win are:

  1. os\win32\ApacheOS.dsp
  2. os\win32\Win9xConHook.dsp
  3. regex\regex.dsp
  4. ap\ap.dsp
  5. lib\expat-lite\xmltok.dsp
  6. lib\expat-lite\xmlparse.dsp requires xmltok
  7. lib\sdbm.dsp
  8. main\gen_uri_delims.dsp
  9. main\gen_test_char.dsp
  10. ApacheCore.dsp requires all of the above
  11. Apache.dsp requires ApacheCore

In addition, the os\win32 subdirectory contains project files for the optional modules, all of which require ApacheCore.

  1. os\win32\mod_auth_anon.dsp
  2. os\win32\mod_auth_dbm.dsp also requires sdbm
  3. os\win32\mod_auth_digest.dsp
  4. os\win32\mod_cern_meta.dsp
  5. os\win32\mod_digest.dsp
  6. os\win32\mod_expires.dsp
  7. os\win32\mod_headers.dsp
  8. os\win32\mod_info.dsp
  9. os\win32\mod_rewrite.dsp
  10. os\win32\mod_speling.dsp
  11. os\win32\mod_status.dsp
  12. os\win32\mod_usertrack.dsp
  13. os\win32\mod_proxy.dsp

The support\ folder contains project files for additional programs that are not part of the Apache runtime, but are used by the administrator to maintain password and log files.

  1. support\htdigest.dsp
  2. support\htpasswd.dsp
  3. support\logresolve.dsp
  4. support\rotatelogs.dsp

Once Apache has been compiled, it needs to be installed in its server root directory. The default is the \Apache directory, on the current hard drive.

To install the files into the c:\ServerRoot directory automatically, use one the following nmake commands (see above):

  • nmake /f Makefile.win installr INSTDIR=c:\ServerRoot (for release build)
  • nmake /f Makefile.win installd INSTDIR=c:\ServerRoot (for debug build)

The c:\ServerRoot argument to INSTDIR gives the installation directory (it can be omitted if Apache is to be installed into \Apache).

This will install the following:

  • c:\ServerRoot\Apache.exe – Apache program
  • c:\ServerRoot\ApacheCore.dll – Apache runtime [shared library]
  • c:\ServerRoot\Win9xConHook.dll – Win9x console fixups [shared library]
  • c:\ServerRoot\xmlparse.dll – XML parser [shared library]
  • c:\ServerRoot\xmltok.dll – XML token engine [shared library]
  • c:\ServerRoot\bin\*.exe – Administration programs
  • c:\ServerRoot\cgi-bin – Example CGI scripts
  • c:\ServerRoot\conf – Configuration files directory
  • c:\ServerRoot\icons – Icons for FancyIndexing
  • c:\ServerRoot\include\*.h – Apache header files
  • c:\ServerRoot\htdocs – Welcome index.html pages
  • c:\ServerRoot\htdocs\manual – Apache documentation
  • c:\ServerRoot\lib – Static library files
  • c:\ServerRoot\libexec – Dynamic link libraries
  • c:\ServerRoot\logs – Empty logging directory
  • c:\ServerRoot\modules\mod_*.dll – Loadable Apache modules

If you do not have nmake, or wish to install in a different directory, be sure to use a similar naming scheme.

To simplify the process, dependencies between all projects are defined in the Microsoft Visual Studio workspace file:

   src/Apache.dsw

This assures that lower-level sources are rebuilt from within Visual Studio. The top level project is InstallBin, which invokes Makefile.win to move the compiled executables and dlls. You may personalize the INSTDIR= setting by changing the Settings for InstallBin, Build command line entry under the General tab. The default from within the InstallBin.dsp project is one level up (..) from the src tree. Modify the InstallBin settings and edit the INSTDIR=.. entry to the desired target directory.

Tagged with:
preload preload preload