Apache 2.0 Architecture
Apache Server 2.0 makes Apache a more flexible, more portable, and more scalable Web solution than ever before. The new 2.0 releases offer many improvements. The first major change in Apache 2.0 is the introduction of multiprocessing modules (MPMs).
To understand why MPMs are created, you need to understand how Apache worked before. Apache Version 1.3 or earlier used a preforking architecture. In this architecture, an Apache parent process forked a set of child processes, which serviced the actual requests.
The parent process simply monitored the children and spawned or killed child processes based on the amount of requests received. Unfortunately, this model didn’t work well under platforms that are not process-centric such as Windows. So, the Apache Group came up with the MPMbased solution.
Each MPM is responsible for starting the server processes and for servicing requests via child processes or threads depending on the MPM implementation. Several MPMs are available.
- The prefork MPM
The prefork MPM mimics the Apache 1.3 or earlier architecture, creating a pool of child processes to service requests. Each child process has a single thread. For example, if Apache starts 30 child processes, it can service 30 requests simultaneously.
If something goes wrong and the child process dies, only a single request is lost. The number of child processes is controlled using a minimum and maximum setting. When the number of requests increases, new child processes are added until the maximum is reached. Similarly, when the requests fall, any extra child processes are killed.
- The threaded MPM
This MPM enables thread support in Apache 2.0. This is like the prefork MPM, but instead of each child process having a single thread, each child process is allowed to have a specified number of threads. Each thread within a child process can service a different request.
If Apache starts 30 child processes where each child is allowed to have at maximum 10 threads, than Apache can service 30 × 10 = 300 requests simultaneously. If something goes wrong with a thread, for example, an experimental module causes the thread to die, then the entire process dies.
This means that all the requests being serviced by the threads within the child process will be lost. However, because requests are distributed among threads on separate child processes, it is likely that a child’s death will take down at maximum of 1/n of all the total connection, where n presents the number of all simultaneous connections.
A process is added or removed by monitoring its spare-thread count. For example, if a process has less than the minimum number of spare threads, a new process is added.
Similarly, when a process has a maximum number of idle threads, it killed. All processes run under the same user and group ID assigned to Apache server. Because threads are more resource efficient than processes, this MPM is very scalable.
- The perchild MPM
This is also new in Apache 2.0. In this MPM model a set number of child processes are started with a specified number of threads. As request load increases the processes add new threads as needed. When request count reduces, processes shrink their thread counts using a minimum and maximum thread count setting.
The key difference between this module and the threaded MPM is that the process count is static and also each process can run using a different user and group ID. This makes it easy to run different virtual Web sites under different user and group IDs.
- The winnt MPM
This is the MPM for the Windows platform, including Windows 2000, Windows NT, and Window 9x. It is a multithreaded module. Using this module Apache will create a parent process and a child process. The child process creates all the threads that services the request.
Also, this module now takes advantage of some Windows-only native function calls, which allows it to perform better than the earlier versions of Apache server on Windows platform.
Apache 2.0 now provides architecture for layered I/O. This means that one module’s output can become another module’s input. This filtering effect is very interesting. For example, the output produced by CGI scripts, which is processed by the mod_cgi module, can now be handed to the mod_include module responsible for SSIs.
In other words, CGI scripts can produce output as SSI tags, which can be processed before the final output is sent to the Web browser. Many other applications of filtering I/O will be available in the future.
Because many of the MPM modules use threads, executing CGI scripts become cumbersome when a thread gets such a request. The mod_cgi module still works, but not optimally for threaded MPMs, so mod_cgid was added. The mod_cgid module creates a daemon process, which spawns CGI processes and interacts with threads more efficiently.
Here is how the CGI scripts are executed:
- When the CGI request comes to a thread within a child process, it passes the request to the CGI daemon.
- The CGI daemon spawns the CGI script and outputs the CGI script-generated data to the thread in the child process.
- The thread returns the data to the Web browser.
When the main Apache server starts, it also starts the CGI daemon and establishes a socket connection. So, when a new child process is created, it inherits the socket connection and therefore does not have any need to create a connection to the CGI daemon for each request.
The entire process improves CGI execution in the threaded environment. In furtherance of the Apache Group’s vision to create the most popular Web server in the world, it became clear that Apache’s portability needed to be addressed in Apache 2.0. Prior to the current release, Apache had been dealing with portability internally, which made the code base less manageable.
So, Apache Group introduced the Apache Portable Run-Time (APR). APR’s purpose is to provide a single C interface to platform-specific functions so that code can be written once. This enables Apache to run more natively on platforms such as Windows, BeOS, Amiga, and OS/2. Because of APR, many programs, such as ApacheBench, can run on these platforms.