Enable HTTP2 Support in Apache

From Sympl Wiki
Revision as of 09:13, 16 April 2020 by Kelduum (talk | contribs) (Kelduum moved page Http2 to Enable HTTP2 Support in Apache)
Jump to navigation Jump to search

To get http2 running on Symbiosis in a production environment reliably, brings about a few configuration changes. I'll attempt to highlight these here.

MPM_event to replace MPM_prefork

The prefork MPM has substantial limitations when working with http2 namely in that each connection can only handle one request at a time. More details can be found on the apache website. Because of this we are going to switch the apache server to using the event MPM. The event MPM is not able to preload the PHP module so we will also need to install php-fpm to parse php on the server.

If you had previously made modifications to the prefork settings to optimise performance then these will need transposing across to the MPM_event configuration as well. If you have not made changes as highlighted below then just disabling the prefork module and enabling the event module as below will be enough.

Setting up

Install the php-fpm, the default php install on a buster machine is currently php7.3:

 apt-get install -y php7.3-fpm 

We will disable the prefork and php7.3 module. The php7.3 module allows the prefork module to run in prefork but we need to remove it to run php-fpm

 a2dismod php7.3 mpm_prefork

We will then install the modules for the event MPM, proxy_fcgi for passing php requests to php-fpm and the http2 module

 a2enmod alias mpm_event proxy proxy_fcgi setenvif http2

We can then add the php7.3-fpm config as well.

 a2enconf php7.3-fpm

At this point the system is configured to run with the new settings but until we have restarted apache they have not taken effect. The php_admin directives that we are set in sympl to enhance security throw errors using the fpm as the multiple fields are not recognised by proxy_fcgi. We need to contain the multiple parameters in quotes so they are all seen as one parameter and passed through to php-fpm as a whole. To do this moving forwards we can adapt the sympl-web-configure templates:

 sed -E -i 's/php_admin_value (.*)/SetEnv php_admin_value \"\1\"/' /etc/sympl/apache.d/*.erb
 sed -E -i 's/php_admin_flag (.*)/SetEnv php_admin_flag \"\1\"/' /etc/sympl/apache.d/*.erb

if you have hand edited the configuration files and dont want to run sympl-web-configure --force

 sed -E -i 's/php_admin_value (.*)/SetEnv php_admin_value \"\1\"/' /etc/apache2/*-available/*.conf
 sed -E -i 's/php_admin_flag (.*)/SetEnv php_admin_flag \"\1\"/' /etc/apache2/*-available/*.conf

You can test the new configuration before restarting apache with the apachectl config test:

 apachectl -t

You should recieve a message saying 'Syntax OK'. there may be a message about the test not seeing the correct IP address but this can be ignored, as long as there are no errors your configuration will work. You can then create the config with the following command:

 sympl-web-configure --verbose

You can test the new configuration using a browser in debug mode or using curl from your server with:

 curl -I --http2 http://localhost

and you should recieve somethig like:

 HTTP/1.1 101 Switching Protocols
 Upgrade: h2c
 Connection: Upgrade

 HTTP/2 200
 date: Sat, 11 Apr 2020 21:55:34 GMT
 server: Apache
 content-type: text/html; charset=UTF-8

Tuning

As with all tuning, there can be a lot of factors that relate to how the figures configuration should be looked at. For edge situations or applications, further advice should be sought. The details below can be used as a guide for general purpose web servers.

Apache

Fine tuning of these settings can take you into a lot of detail, going beyond the initial basic configuration which for a base level machine (2 cores, 8GB RAM) is fine and a good starting point. If you have anything more, you will need to make at least the changes suggested here. If you need more tuning then you will need to consider what other services are on the machine, take some metrics as to what resource your current processes are using and factor in all the limits and capabilities of the server and take into consideration changes that are planned. As this guide is helping you get started we will not go into too much detail here. Your /etc/apache2/mods-available/mpm_event.conf would look a little like this:

 <IfModule mpm_event_module>
    StartServers                2       # You should set this to the number of cores you have on your server
    MinSpareThreads             25      
    MaxSpareThreads             75
    ThreadLimit                 64
    ThreadsPerChild             25
    MaxRequestWorkers           150     # This should be around StartServers * ThreadsPerChild + MaxSpareThreads. Here there are a few more to play with.
    MaxConnectionsPerChild      0 
 </IfModule>

If your server has 4 cores and 16GB RAM, you can set the StartServers to 4 and the MaxRequestWorkers to around 175 to 200. Further information can be found regarding the above parameters in the apache documentation.

PHP-fpm

Again there are a lot of things to consider regarding the settings for the FPM pool. We will look at the basics again but you will need to look at your systems RAM usage and other functions for further fine tuning. You can find the configuration file for the php-fpm in /etc/php/7.3/fpm/pool.d/www.conf. The configuration file for php-fpm is heavily commented, the main settings that you would need to set up are:

 pm = dynamic
 pm.max_children = 5 
 pm.start_servers = 2     
 pm.min_spare_servers = 1
 pm.max_spare_servers = 3

Again this would be a good starting point for a base server (2 cores, 8GB ram) and can be scaled up in a similar way so with 4 cores and 16GB ram you can increase the numbers by a factor of 2. Further information regarding the php-fpm configuration directives can be found in the php-fpm documentation.

multiple PHP Versions

As we are now running php outside of Apache we can run multiple versions of PHP on the system, utilise different php-fpm pools and reference them from .htaccess with relative ease.

setting up

Setting up the different PHP versions requires the use of a new package maintainers repository. This enables the different PHP versions to sit side by side on the system:

 wget -qO - https://packages.sury.org/php/apt.gpg | apt-key add -
 echo "deb https://packages.sury.org/php $(lsb_release cs) main" > /etc/apt/sources.list.d/sury.list
 apt-get update
 

Now we have the repo in place we can go ahead with the above for getting the system set up. If you want to install other versions of php for the system you can simply run:

 apt-get install php5.6-fpm

For php5.6 this will install the FPM and set up the basic pool as above, you can then copy the config from apache into an .htaccess file:

 cp /etc/apache2/conf-available/php5.6-fpm.conf /srv/{domain}/public/htdocs/.htaccess

The site for {domain} will now use php5.6. You can even set up further .htaccess files in other folders to control different PHP versions or different folders within the same site.

The one thing to remember is that you will need to manage the pool resources for each php version independantly. The configuration for php5.6 would be in /etc/php/5.6/fpm/pool.d/www.conf If you are supporting multiple sites, and only have one using php5.6 then it would be wise to have the pool smaller than that of other sites.