Apache Web Server for High Load and Performance using PHP-FPM

THE PROJECT.

We require to setup a high performance Apache Server which can also deal with a large amount of simultaneous connections. During our research we decided to use: Apache, PHP-FPM and Centos 7. During testing and research we also decided to use the Apache Handler MPM-EVENT as it showed a improvement in performance.

The customer in question for this project was posting links to his web site from a YouTube channel with over 1 million subscribers so a standard built of Apache just fell over.

STEP 1 – Disable Selinux & Install Tools and repositories needed:

[code type=codetype]

sed -i ‘s/SELINUX=enforcing/SELINUX=disabled/’ /etc/selinux/config
reboot

# Add some tools to the base system

yum install net-tools nano wget libaio

# Install the Repositories required

rpm -Uvh https://www.ukhost4u.com/
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
ldconfig
yum update
reboot

[/code]

STEP 2 – install apache, php 5.6, php-fpm and other required features:

[code type=codetype]

# Installing Apache + PHP-FPM

yum –enablerepo=remi,remi-php56 install httpd php-fpm php-common php-pecl-zendopcache php-gd php-intl php-mbstring php-mysql php-mysqlnd php-xmlrpc php-openssl php-soap php-mcrypt php-pecl-pthreads

# Start and Enable Apache

systemctl start httpd.service
systemctl enable httpd.service
systemctl status httpd.service -l

# Start and Enable PHP-FPM

systemctl start php-fpm.service
systemctl enable php-fpm.service
systemctl status php-fpm.service -l

## We could also install PHP 7 if you wish by changing the yum command to: remi-php70 or remi-php71 if this was required.

[/code]

STEP 3 – setting up info.php and confirm everything works:

[code type=codetype]

# Setup a info.php page

printf ‘<?php phpinfo(); ?>’ > /var/www/html/info.php

# Configure the vhost entry and mod_proxy_fcgi

nano /etc/httpd/conf.d/localhost.conf

# Add the following and save it

<VirtualHost *:80>

ServerName localhost

ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/$1

DocumentRoot /var/www/html
<Directory /var/www/html>
AllowOverride All
Require all granted
</Directory>

ErrorLog /var/log/httpd/localhost_error.log
CustomLog /var/log/httpd/localhost_access.log combined
</VirtualHost>

# Restart Apache and check its running

systemctl restart httpd.service
systemctl status httpd.service -l

[/code]

At this point you should be able to test that everything has worked and access your server on its IP http://1.1.1.1/ and Php Info using http://1.1.1.1/info.php

STEP 4 – optimising apache:

We are going to make some changes to the configuration file for Apache.

[code type=codetype]

nano /etc/httpd/conf.modules.d/00-base.conf

## UPDATE THE FILE AS FOLLOWS:

#
# This file loads most of the modules included with the Apache HTTP
# Server itself.
#

#LoadModule access_compat_module modules/mod_access_compat.so
#LoadModule actions_module modules/mod_actions.so
LoadModule alias_module modules/mod_alias.so
#LoadModule allowmethods_module modules/mod_allowmethods.so
#LoadModule auth_basic_module modules/mod_auth_basic.so
#LoadModule auth_digest_module modules/mod_auth_digest.so
#LoadModule authn_anon_module modules/mod_authn_anon.so
LoadModule authn_core_module modules/mod_authn_core.so
#LoadModule authn_dbd_module modules/mod_authn_dbd.so
#LoadModule authn_dbm_module modules/mod_authn_dbm.so
LoadModule authn_file_module modules/mod_authn_file.so
#LoadModule authn_socache_module modules/mod_authn_socache.so
LoadModule authz_core_module modules/mod_authz_core.so
#LoadModule authz_dbd_module modules/mod_authz_dbd.so
#LoadModule authz_dbm_module modules/mod_authz_dbm.so
#LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_host_module modules/mod_authz_host.so
#LoadModule authz_owner_module modules/mod_authz_owner.so
#LoadModule authz_user_module modules/mod_authz_user.so
LoadModule autoindex_module modules/mod_autoindex.so
#LoadModule cache_module modules/mod_cache.so
#LoadModule cache_disk_module modules/mod_cache_disk.so
#LoadModule data_module modules/mod_data.so
#LoadModule dbd_module modules/mod_dbd.so
LoadModule deflate_module modules/mod_deflate.so
LoadModule dir_module modules/mod_dir.so
#LoadModule dumpio_module modules/mod_dumpio.so
#LoadModule echo_module modules/mod_echo.so
LoadModule env_module modules/mod_env.so
LoadModule expires_module modules/mod_expires.so
#LoadModule ext_filter_module modules/mod_ext_filter.so
#LoadModule filter_module modules/mod_filter.so
#LoadModule headers_module modules/mod_headers.so
#LoadModule include_module modules/mod_include.so
#LoadModule info_module modules/mod_info.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule logio_module modules/mod_logio.so
LoadModule mime_magic_module modules/mod_mime_magic.so
LoadModule mime_module modules/mod_mime.so
LoadModule negotiation_module modules/mod_negotiation.so
#LoadModule remoteip_module modules/mod_remoteip.so
LoadModule reqtimeout_module modules/mod_reqtimeout.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule setenvif_module modules/mod_setenvif.so
#LoadModule slotmem_plain_module modules/mod_slotmem_plain.so
#LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
#LoadModule socache_dbm_module modules/mod_socache_dbm.so
#LoadModule socache_memcache_module modules/mod_socache_memcache.so
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
#LoadModule status_module modules/mod_status.so
#LoadModule substitute_module modules/mod_substitute.so
#LoadModule suexec_module modules/mod_suexec.so
#LoadModule unique_id_module modules/mod_unique_id.so
LoadModule unixd_module modules/mod_unixd.so
#LoadModule userdir_module modules/mod_userdir.so
#LoadModule version_module modules/mod_version.so
#LoadModule vhost_alias_module modules/mod_vhost_alias.so

#LoadModule buffer_module modules/mod_buffer.so
#LoadModule watchdog_module modules/mod_watchdog.so
#LoadModule heartbeat_module modules/mod_heartbeat.so
#LoadModule heartmonitor_module modules/mod_heartmonitor.so
#LoadModule usertrack_module modules/mod_usertrack.so
#LoadModule dialup_module modules/mod_dialup.so
#LoadModule charset_lite_module modules/mod_charset_lite.so
#LoadModule log_debug_module modules/mod_log_debug.so
#LoadModule ratelimit_module modules/mod_ratelimit.so
#LoadModule reflector_module modules/mod_reflector.so
#LoadModule request_module modules/mod_request.so
#LoadModule sed_module modules/mod_sed.so
#LoadModule speling_module modules/mod_speling.so

[/code]

[code type=codetype]

nano /etc/httpd/conf.modules.d/00-dav.conf

#LoadModule dav_module modules/mod_dav.so
#LoadModule dav_fs_module modules/mod_dav_fs.so
#LoadModule dav_lock_module modules/mod_dav_lock.so

[/code]

[code type=codetype]

nano /etc/httpd/conf.modules.d/00-lua.conf

#LoadModule lua_module modules/mod_lua.so

[/code]

[code type=codetype]

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

# Select the MPM module which should be used by uncommenting exactly
# one of the following LoadModule lines:

# prefork MPM: Implements a non-threaded, pre-forking web server
# See: http://httpd.apache.org/docs/2.4/mod/prefork.html
#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so

# worker MPM: Multi-Processing Module implementing a hybrid
# multi-threaded multi-process web server
# See: http://httpd.apache.org/docs/2.4/mod/worker.html
#
#LoadModule mpm_worker_module modules/mod_mpm_worker.so

# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See: http://httpd.apache.org/docs/2.4/mod/event.html
#
LoadModule mpm_event_module modules/mod_mpm_event.so

[/code]

[code type=codetype]

nano /etc/httpd/conf.modules.d/00-proxy.conf

# This file configures all the proxy modules:
LoadModule proxy_module modules/mod_proxy.so
#LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so
#LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
#LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so
#LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so
#LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
#LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
#LoadModule proxy_connect_module modules/mod_proxy_connect.so
#LoadModule proxy_express_module modules/mod_proxy_express.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
#LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so
#LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
#LoadModule proxy_http_module modules/mod_proxy_http.so
#LoadModule proxy_scgi_module modules/mod_proxy_scgi.so

[/code]

[code type=codetype]

nano /etc/httpd/conf.modules.d/00-systemd.conf

# This file configures systemd module:
LoadModule systemd_module modules/mod_systemd.so

[/code]

[code type=codetype]

nano /etc/httpd/conf.modules.d/01-cgi.conf

# This configuration file loads a CGI module appropriate to the MPM
# which has been configured in 00-mpm.conf. mod_cgid should be used
# with a threaded MPM; mod_cgi with the prefork MPM.

<IfModule mpm_worker_module>
LoadModule cgid_module modules/mod_cgid.so
ThreadsPerChild 25
StartServers 3
ServerLimit 400
MinSpareThreads 75
MaxSpareThreads 250
MaxRequestWorkers 10000
MaxConnectionsPerChild 0
</IfModule>

<IfModule mpm_event_module>
LoadModule cgid_module modules/mod_cgid.so
ThreadsPerChild 25
StartServers 3
ServerLimit 400
MinSpareThreads 75
MaxSpareThreads 250
MaxRequestWorkers 10000
MaxConnectionsPerChild 0
</IfModule>

<IfModule mpm_prefork_module>
LoadModule cgi_module modules/mod_cgi.so
StartServers 5
ServerLimit 1000
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 1000
MaxConnectionsPerChild 0
</IfModule>

[/code]

[code type=codetype]

nano /etc/httpd/conf.d/security.conf
#
# https://www.ukhost4u.com/
#

Timeout 10
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
LimitRequestline 512
LimitRequestFields 100
LimitRequestFieldsize 1024
LimitRequestBody 102400

systemctl restart httpd.service

[/code]

STEP 5 – CONFIgure php:

[code type=codetype]

nano /etc/php.ini

# Add to the end of your php.ini file.

date.timezone = “Europe/London”
default_charset = “UTF-8”
upload_max_filesize = 10M
post_max_size = 20M
realpath_cache_size = 64k
realpath_cache_ttl = 3600
max_execution_time = 120

[/code]

STEP 6 – setup options for php-fpm:

During this step we are going to increase some of the limits for PHP-FPM to be similar to your apache seutp.

[code type=codetype]

nano /etc/php-fpm.d/www.conf

# Change the following settings

pm.max_children = 100
pm.start_servers = 50
pm.min_spare_servers = 20
pm.max_spare_servers = 50
pm.max_requests = 5000
[/code]

Conclusion.

After completing the following changes we tested this new setup with the initial client for this project and unlike before the changes the Apache server didn’t fall over. We feel this is a great setup for high performance, high load, fast response of Apache and taking the benifits from MPM and PHP-FPM