Change Apache MPM in AWS EC2

How to change the Apache MPM on an EC2 instance

Apache is a powerful and flexible webserver. You can easily install it on a wide variety of platforms in various types of environments. However, depending upon your type of environment and platform, the needs may differ. The modular design of Apache httpd has allowed it to serve users well across a wide variety of environments. An important benefit for users is that they can select which features they want to keep enabled and which ones to disable using modules. Only the selected modules will run either at compile time or run time. 
Apache further extends its modular design through MPMs. It offers three main MPMs or multi processing modules – MPM Prefork, MPM Worker and MPM Event. MPM Prefork is the default module that comes enabled with Apache. Prefork is the default MPM that is enabled when you first install the Apache webserver on an EC2 instance. However, Prefork is suitable for older systems that require compatibility and stability. In the case of modern systems like the ones available in most cloud environments, it is safer to switch to one of the threaded modules like either MPM worker or MPM Event. 
The threaded MPMs offer some performance benefits over the non-threaded MPM Prefork. It is why the sites requiring greater scalability must choose either worker or event MPM.

If you plan to change your MPM, you can follow the method outlined below. While the commands may differ for different operating systems like Ubuntu and Centos, the files involved and process remains the same since we are dealing with a feature of the Apache server.

A brief intro to the three MPMs:

Prefork:


MPM Prefork causes Apache to fork into additional processes. These processes are ready before the requests are received. Since there is always an Apache process ready to handle a request, the server is able to respond faster after receiving a request from a client. In case of any problem with a single process, Apache kills it without any effect on the other processes. However, since Prefork is a non threaded MPM, each process can handle only a single request at a time. In such a case, what happens is that the concurrent requests get queued and are processed when the system is available. The MPM waits to process each request until the system is available. The scaled child processes also use more of the system RAM.  In simpler words, compared to the other two threaded MPMs, Prefork is a resource intensive MPM.

Worker:


The shortcomings of MPM Prefork can be overcome through the use of a threaded MPM like Worker. It causes Apache to fork into several processes so one crash cannot kill the entire Apache process. However, unlike Prefork, in the case of MPM worker, each process creates numerous threads and also a listener thread that will listen for connections. The system is able to respond to several concurrent requests in this manner.

Event:


Event MPM is built on the Worker MPM. It serves a single http request across multiple threads. It dedicates a thread to handle all live connections. The listening thread directs the incoming requests to an available thread. The system allocates a thread after recieving the request. Once the request is finished, the thread is instantly available. In the case of MPM worker, the entire threads wait for the KeepAliveTimeout. MPM event uses the listener approach that ensures that the worker threads do not need to wait for KeepAliveTimeout. It allocates the maximum worker threads to handle as many requests as possible.

In the case of most simple server setups, the default configurations of MPM Event work well. That’s why MPM event is considered a good starting point for performance tuning. 

Changing the MPM on an EC2 Instance:

To change the MPM on an EC2 instance (Amazon Linux 2), you need to make sure you have Apache installed and running as the web server. (It will also work on other cloud platforms or dedicated and VPS servers, given the webserver is Apache.)

The following command helps you find if Apache is Active and running:

sudo systemctl status httpd  (sudo systemctl status apache2 for Ubuntu or Debian)

The output will show you if Apache is Active and running:

$ sudo systemctl status httpd
● httpd.service – The Apache HTTP Server
  Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2023-02-21 11:41:42 UTC; 46min ago
    Docs: man:httpd.service(8)
Main PID: 1184 (httpd)
  Status: “Total requests: 1538; Idle/Busy workers 100/0;Requests/sec: 0.549; Bytes served/sec:  11KB/sec”
  CGroup: /system.slice/httpd.service
          ├─1184 /usr/sbin/httpd -DFOREGROUND
          ├─1185 /usr/sbin/httpd -DFOREGROUND
          ├─1186 /usr/sbin/httpd -DFOREGROUND
          ├─1188 /usr/sbin/httpd -DFOREGROUND
          ├─1225 /usr/sbin/httpd -DFOREGROUND
          └─1409 /usr/sbin/httpd -DFOREGROUND

Once you have verified that the Apache web server is active and running, you will need to check out which MPM is currently installed. You can do that by checking out all the modules installed on your server using sudo httpd -M.

This command will output a list of all the modules active on your server. The active MPM module is also listed along with the other modules. MPM Prefork comes installed by default with Apache and you will find it included in the list. Check out the list below and mark that MPM Prefork is active -> mpm_prefork_module (shared). At the bottom, you will also see the cgi_module (shared) in the list. Mark these two modules before proceeding to change the MPM.

List of Modules:

$ sudo httpd -M
Loaded Modules:
core_module (static)
so_module (static)
http_module (static)
access_compat_module (shared)
actions_module (shared)
alias_module (shared)
allowmethods_module (shared)
auth_basic_module (shared)
auth_digest_module (shared)
authn_anon_module (shared)
authn_core_module (shared)
authn_dbd_module (shared)
authn_dbm_module (shared)
authn_file_module (shared)
authn_socache_module (shared)
authz_core_module (shared)
authz_dbd_module (shared)
authz_dbm_module (shared)
authz_groupfile_module (shared)
authz_host_module (shared)
authz_owner_module (shared)
authz_user_module (shared)
autoindex_module (shared)
cache_module (shared)
cache_disk_module (shared)
cache_socache_module (shared)
data_module (shared)
dbd_module (shared)
deflate_module (shared)
dir_module (shared)
dumpio_module (shared)
echo_module (shared)
env_module (shared)
expires_module (shared)
ext_filter_module (shared)
filter_module (shared)
headers_module (shared)
include_module (shared)
info_module (shared)
log_config_module (shared)
logio_module (shared)
macro_module (shared)
mime_magic_module (shared)
mime_module (shared)
negotiation_module (shared)
remoteip_module (shared)
reqtimeout_module (shared)
request_module (shared)
rewrite_module (shared)
setenvif_module (shared)
slotmem_plain_module (shared)
slotmem_shm_module (shared)
socache_dbm_module (shared)
socache_memcache_module (shared)
socache_shmcb_module (shared)
status_module (shared)
substitute_module (shared)
suexec_module (shared)
unique_id_module (shared)
unixd_module (shared)
userdir_module (shared)
version_module (shared)
vhost_alias_module (shared)
watchdog_module (shared)
dav_module (shared)
dav_fs_module (shared)
dav_lock_module (shared)
lua_module (shared)
mpm_prefork_module (shared)
proxy_module (shared)
lbmethod_bybusyness_module (shared)
lbmethod_byrequests_module (shared)
lbmethod_bytraffic_module (shared)
lbmethod_heartbeat_module (shared)
proxy_ajp_module (shared)
proxy_balancer_module (shared)
proxy_connect_module (shared)
proxy_express_module (shared)
proxy_fcgi_module (shared)
proxy_fdpass_module (shared)
proxy_ftp_module (shared)
proxy_http_module (shared)
proxy_hcheck_module (shared)
proxy_scgi_module (shared)
proxy_uwsgi_module (shared)
proxy_wstunnel_module (shared)
ssl_module (shared)
systemd_module (shared)
cgi_module (shared)
http2_module (shared)
proxy_http2_module (shared)

Now, that you know which MPM is active on your server, now you can move ahead to change it. To change the MPM, use the following command:

sudo nano /etc/httpd/conf.modules.d/00-mpm.conf

To enable the MPM event, you will need to uncomment the following line:

#LoadModule mpm_event_module modules/mod_mpm_event.so

To enable the MPM Worker, you can uncomment the following line:

#LoadModule mpm_worker_module modules/mod_mpm_worker.so

You can save and close the file once you have uncommented the necessary line and commented out the following line:

LoadModulempm_prefork_module modules/mod_mpm_prefork.so

To save, close and exit, hit Ctrl + X, then Y and then hit enter. Remember that you must activate only one MPM at a time, otherwise it will throw an error. You can use anyone of the three MPMs and so, you will need to comment out the other two in the configuration file. Now, that you have successfully changed your MPM, to make the change stick, we need to restart the server using the following command:

$ sudo systemctl restart httpd (for centos7)

$sudo systemctl restart apache2

After having restarted the Apache httpd server, you can check out if the MPM has changed by listing all the modules again. Use sudo httpd -M.

$ sudo httpd -M
Loaded Modules:
core_module (static)
so_module (static)
http_module (static)
access_compat_module (shared)
actions_module (shared)
alias_module (shared)
allowmethods_module (shared)
auth_basic_module (shared)
auth_digest_module (shared)
authn_anon_module (shared)
authn_core_module (shared)
authn_dbd_module (shared)
authn_dbm_module (shared)
authn_file_module (shared)
authn_socache_module (shared)
authz_core_module (shared)
authz_dbd_module (shared)
authz_dbm_module (shared)
authz_groupfile_module (shared)
authz_host_module (shared)
authz_owner_module (shared)
authz_user_module (shared)
autoindex_module (shared)
cache_module (shared)
cache_disk_module (shared)
cache_socache_module (shared)
data_module (shared)
dbd_module (shared)
deflate_module (shared)
dir_module (shared)
dumpio_module (shared)
echo_module (shared)
env_module (shared)
expires_module (shared)
ext_filter_module (shared)
filter_module (shared)
headers_module (shared)
include_module (shared)
info_module (shared)
log_config_module (shared)
logio_module (shared)
macro_module (shared)
mime_magic_module (shared)
mime_module (shared)
negotiation_module (shared)
remoteip_module (shared)
reqtimeout_module (shared)
request_module (shared)
rewrite_module (shared)
setenvif_module (shared)
slotmem_plain_module (shared)
slotmem_shm_module (shared)
socache_dbm_module (shared)
socache_memcache_module (shared)
socache_shmcb_module (shared)
status_module (shared)
substitute_module (shared)
suexec_module (shared)
unique_id_module (shared)
unixd_module (shared)
userdir_module (shared)
version_module (shared)
vhost_alias_module (shared)
watchdog_module (shared)
dav_module (shared)
dav_fs_module (shared)
dav_lock_module (shared)
lua_module (shared)
mpm_event_module (shared)
proxy_module (shared)
lbmethod_bybusyness_module (shared)
lbmethod_byrequests_module (shared)
lbmethod_bytraffic_module (shared)
lbmethod_heartbeat_module (shared)
proxy_ajp_module (shared)
proxy_balancer_module (shared)
proxy_connect_module (shared)
proxy_express_module (shared)
proxy_fcgi_module (shared)
proxy_fdpass_module (shared)
proxy_ftp_module (shared)
proxy_http_module (shared)
proxy_hcheck_module (shared)
proxy_scgi_module (shared)
proxy_uwsgi_module (shared)
proxy_wstunnel_module (shared)
ssl_module (shared)
systemd_module (shared)
cgid_module (shared)
http2_module (shared)
proxy_http2_module (shared)

You can note that the MPM Prefork – mpm_prefork_module – has been replaced with MPM Event or mpm_event_module (shared). Apart from that, the cgi_module is replaced with the cgid_module. It is because cgi module is compatible with MPM Prefork and not with the threaded MPMs. Mod cgid is compatible with the threaded MPMs – MPM Worker and MPM Event. When you change from the Prefork MPM to a threaded module, the system automatically uninstalls the incompatible module and installs the compatible module. You will not need to manually uninstall the incompatibel modules when changing MPM. Even if you are on a dedicated server with WHM/Cpanel and using EasyApache4 to change MPM, the system will automatically uninstall the incompatible modules.

Changing the MPMs is easier for Apache users because Linux allows MPMs to be built as DSO modules (Dynamic Shared Objects) which can be loaded into the server dynamically just like the other DSO modules. So, users only need to update the LoadModule directive for the MPM instead of rebuilding the server to change MPM.