Apache server – performance 02

MPM prefork Optimisation

Now that we understand a little better configuration of the Apache process boot system we will be able to discuss configuration changes to improve performance. I warn you all right away unless you have an ultra loaded website the performance gains will not be so significant, moreover you will have to do validation tests and take “risks” up to a certain point during the modifications . The biggest gain you will have is if you have a VPS with little RAM or if you take an Amazon EC2 instance with little memory and CPU.

Let’s see an example of a default “classic” configuration for the prefork system

 

$ cat /etc/apache2/mods-enabled/mpm_prefork.conf [ ... OUTPUT COUPÉ ... ] StartServers 5 MinSpareServers 5 MaxSpareServers 10 MaxRequestWorkers 150 MaxConnectionsPerChild 0

In order not to interfere with previously realized configurations we will disable the activated cache system when demonstrating the CPU usage.

$ cat /etc/apache2/sites-enabled/siteA-ssl.conf [ ... OUTPUT COUPÉ ... ] # Mise en cache de tous les contenus #CacheEnable disk / #CacheIgnoreCacheControl On #CacheDefaultExpire 3600 [ ... OUTPUT COUPÉ ... ] $ sudo apachectl configtest && sudo /etc/init.d/apache2 restart

I will mainly manipulate the MaxRequestWorkers directive. As a reminder, this directive defines the number of processes that apache will start in order to be able to support the load, in other words in this situation the site will be able to provide 150 competitive customers. We will do a load test with 250 requests including 250 competitor:

[client]$ ab -n 250 -c 250 -l https://www.linux202-siteA.com/ Percentage of the requests served within a certain time (ms) 50% 2416 66% 2622 75% 2753 80% 2801 90% 3089 95% 3352 98% 3735 99% 4689 100% 4805 (longest request) [server]$ $ ps aux | egrep 'apache|RSS' | head USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 58 0.1 0.9 90556 19536 ? Ss 08:33 0:00 /usr/sbin/apache2 -k start www-data 63 0.0 0.2 90588 5468 ? S 08:33 0:00 /usr/sbin/apache2 -k start [ ... OUTPUT COUPÉ ... ] [server]$ ps aux | tr -s " " | cut -d " " -f 6,11- | grep apache | egrep -v "grep|htcache" | awk '{ sum+=$1} END {print sum}' 799480 [server]$ bc -l bc 1.06.95 Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type warranty. 799480 / 1024 780.74218750000000000000

In the above example when mounted in load I made the calculation of the memory used by apache, adding the column RSS. As you can see, we have mounted 780 Megs of RAM, for only the home page with 250 competing client, this mounted load is only temporary the time to do the connection processing. Is it really required?!?! We only communicate with the homepage that does not contain much information … We can also see that the maximum response time for the page is 4805 ms.

Let’s make a small change let’s do the same thing but reduce the number of apache processes that can be started. As we are prefork and there is copy of the memory stack for each process if there is less process there will be less memory. I assume that your first instinct is to say, “yes it’s true, but less process to take the queries will explode the response time …”. Your idea is right but presumed it is not confirm: P, let’s test it and look at the result:

 

$ cat /etc/apache2/mods-enabled/mpm_prefork.conf [ ... OUTPUT COUPÉ ... ] StartServers 5 MinSpareServers 5 MaxSpareServers 10 MaxRequestWorkers 50 MaxConnectionsPerChild 0 $ sudo apachectl configtest && sudo /etc/init.d/apache2 restart

So we reduce the number of usable processes by apache, we pass from 150 to 50

 

[client]$ ab -n 250 -c 250 -l https://www.linux202-siteA.com/ Percentage of the requests served within a certain time (ms) 50% 2467 66% 2746 75% 2857 80% 2954 90% 3488 95% 3894 98% 4298 99% 4748 100% 4806 (longest request) [server]$ ps aux | tr -s " " | cut -d " " -f 6,11- | grep apache | egrep -v "grep|htcache" | awk '{ sum+=$1} END {print sum}' 441432 [server]$ bc -l bc 1.06.95 Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type warranty. 441432/ 1024 431.08593750000000000000

So we are now using 431 megs of RAM and comparing the result of the server’s response time:

150 Workers 50 Workrs % of the requests served (ms) % of the requests served (ms) 50% 2416 50% 2467 66% 2622 66% 2746 75% 2753 75% 2857 80% 2801 80% 2954 90% 3089 90% 3488 95% 3352 95% 3894 98% 3735 98% 4298 99% 4689 99% 4748 100% 4805 (longest request) 100% 4806 (longest request)

We have almost reduced the memory used by the system by 50% for a minimal impact on response times, so we can see it as a success. We could even try to reduce that number still to 25 for example:

[client]$ ab -n 250 -c 250 -l https://www.linux202-siteA.com/ Percentage of the requests served within a certain time (ms) 50% 2443 66% 2690 75% 2825 80% 2893 90% 3316 95% 3704 98% 4024 99% 4488 100% 4660 (longest request) [server]$ ps aux | tr -s " " | cut -d " " -f 6,11- | grep apache | egrep -v "grep|htcache" | awk '{ sum+=$1} END {print sum}' 235584 [server]$ bc -l bc 1.06.95 Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'. 235584 / 1024 230.06250000000000000000

So 250 megs for an impact on response times still frankly very very comfortable.

Woww, well I understand the saving of memory … But if I accept that 50 connections and there 250 arrive how the server does to answer?!?! Where is the server limit?!?! This is not clear! You have reasons, it requires a little more explanation on what is happening under the carpet: P.

The definition of the limit of concurrent connections is defined by the instruction ServerLimit, the latter allows to define the number of competition. The latter is also used to limit the number of processes in conjunction with the MaxRequestWorkers statement. The default is 256, so you should not change it unless you have a server: P.

 

 

During a load increase the system will use the ListenBackLog instruction to support the TCP connection (3 handshakes). The result is that the client has established the connection with the server and the server will receive the information from the web page when a process is released. By default the number of connection in the queue is 511. We must be careful when we play with this value because we put ourselves at risk of an attack not TCP flood if the latter is too high.

Reference: http://www.ryanfrantz.com/posts/apache-tcp-backlog/

So all the mystery of connection management is in these 2 parameters: D.

 

  • Reference:

    • https://httpd.apache.org/docs/2.4/fr/mod/mpm_common.html

    • https://httpd.apache.org/docs/2.4/fr/mod/prefork.html

MPM worker

We just covered the prefork mode let’s go to the worker mode at the risk of repeating myself, prefork fork the processes so make a copy of the process to do the processing while worker is working in thread mode and use the shared memory of the threads to do the processing.

 

I will change the prefork default mode to worker mode.

$ sudo a2enmod mpm_worker Considering conflict mpm_event for mpm_worker: Considering conflict mpm_prefork for mpm_worker: ERROR: Module mpm_prefork is enabled - cannot proceed due to conflicts. It needs to be disabled first! Considering conflict mpm_itk for mpm_worker:

As you can see the 2 modules can not coexist, we expected so I will disable the prefork mode to switch to worker mode.

$ sudo a2dismod mpm_prefork Module mpm_prefork disabled. To activate the new configuration, you need to run: service apache2 restart $ sudo a2enmod mpm_worker Considering conflict mpm_event for mpm_worker: Considering conflict mpm_prefork for mpm_worker: Considering conflict mpm_itk for mpm_worker: Enabling module mpm_worker. To activate the new configuration, you need to run: service apache2 restart

We validate the configuration + the restart and we validate it all! As mentioned in the past, the php module with Ubuntu is not compatible with the worker mode so we will come back for the moment I will disable it.

$ sudo apachectl configtest && sudo /etc/init.d/apache2 restart [Mon Jul 04 17:28:01.104973 2016] [:crit] [pid 144:tid 3074546304] Apache is running a threaded MPM, but your PHP Module is not compiled to be threadsafe. You need to recompile PHP. AH00013: Pre-configuration failed Action 'configtest' failed. The Apache error log may have more information. $ sudo a2dismod php5 Module php5 disabled. To activate the new configuration, you need to run: service apache2 restart $ sudo apachectl configtest && sudo /etc/init.d/apache2 restart Syntax OK * Restarting web server apache2 ...done.

If we go to the site page we should have the site as before: https://www.linux202-sitea.com/

Cool ! Now that it works a little explanation before analyzing it

A single control process (the parent) is responsible for starting child processes. Each child process creates a fixed number of server threads based on the value of the ThreadsPerChild directive, as well as a thread that waits for connections and passes them to a server thread for processing as they arrive.

The Apache HTTP server always tries to maintain a set of idle or inactive server threads, which are ready to process incoming requests. In this way, customers do not have to wait for a new thread or process to be created before their requests can be processed. The number of processes started initially is defined by the StartServers directive. During operation, the server evaluates the total number of inactive threads in all processes, and creates or stops them to maintain that number within the limits defined by the MinSpareThreads and MaxSpareThreads directives. As this module self-controls effectively, one can usually keep the default values. The maximum number of clients that can be served simultaneously (that is, the maximum total number of threads for all processes) is set by the MaxRequestWorkers directive. The maximum number of active child processes is defined by the value of the MaxRequestWorkers directive divided by the value of the ThreadsPerChild directive.

 

Reference: https://httpd.apache.org/docs/2.4/en/mod/worker.html

Visualize the configuration:

$ cat /etc/apache2/mods-enabled/mpm_worker.conf [ ... OUTPUT COUPÉ ... ] StartServers 2 MinSpareThreads 25 MaxSpareThreads 75 ThreadLimit 64 ThreadsPerChild 25 MaxRequestWorkers 150 MaxConnectionsPerChild 0

Let’s analyze the directives available

  • StartServers

 

Define the number of processes that will start when the service is initialized, with the worker module the default value is 2. This value is usually quite low, the goal is to be able to respond to the first queries quickly. As you can see, the value is lower than for the prefork module because the system uses 1 process to process multiple requests using threads so it does not need to start any process to support the request.

  • MinSpareThreads

 

This is the minimum number of idle threads to handle peaks of queries. In worker mode, the default setting is MinSpareThreads 75, and the number of idle threads is monitored at the server level. If the server does not have enough inactive threads, child processes are created until the number of idle threads goes back over the number.

  • MaxSpareThreads

 

This is the maximum number of idle threads. In worker mode, the default setting is MaxSpareThreads 250. This MPM handles inactive threads at the server level. If the server has too many idle threads, child processes will be stopped until the number of idle threads falls below this limit.

  • ThreadLimit

 

This directive sets the maximum number that can be assigned to the ThreadsPerChild directive for the lifetime of the Apache httpd process. The ThreadsPerChild directive can be changed during a reboot to the value of the ThreadLimit directive, but any attempt to modify the ThreadLimit directive during a reboot will be ignored.

The use of this directive must be the subject of special precautions. If ThreadLimit is set to a much greater value than the ThreadsPerChild directive, additional shared memory will be unnecessarily allocated. If the ThreadLimit and ThreadsPerChild directives are set to higher values ​​than the system can handle, the system may become unstable, or Apache httpd may simply refuse to start. Do not set this directive to a value greater than the maximum value that you expect to assign to the ThreadsPerChild directive for the running Apache httpd process.

 

  • ThreadsPerChild

 

This directive sets the number of threads that each child process will create. A child process creates these threads at startup and no longer creates others. With a worker-like MPM that launches multiple child processes, the total number of threads must be large enough to support the server load

  • MaxRequestWorkers

 

The MaxRequestWorkers directive is used to set the maximum number of requests that can be processed simultaneously. If the MaxRequestWorkers limit is reached, any connection attempt will normally be queued up to a number that depends on the ListenBacklog directive. When a child process is released after the completion of a request, the pending connection can be processed in turn. For threaded and hybrid servers (such as event or worker), MaxRequestWorkers sets the total number of threads that will be available to serve clients. In the case of hybrid MPMs, the default value is 16 (ServerLimit directive) multiplied by 25 (ThreadsPerChild directive). Therefore, to assign a value to the MaxRequestWorkers directive that requires more than 16 processes, you must also increase the value of the ServerLimit directive.

  • MaxConnectionsPerChild

 

The MaxConnectionsPerChild directive sets the maximum number of connections that a child process will be able to process during its operation. When it processed MaxConnectionsPerChild connections, the child process is stopped. If MaxConnectionsPerChild is set to 0, there is no limit on the number of connections the process will handle. Setting MaxConnectionsPerChild to a non-zero value limits the amount of memory a process can consume because of (accidental) memory leaks.

MPM Worker Optimisation

Now that we understand a little better configuration of the Apache process boot system we will be able to discuss configuration changes to improve performance. I warn you all right away unless you have an ultra loaded website the performance gains will not be so significant, moreover you will have to do validation tests and take “risks” up to a certain point during the modifications . The biggest gain you will have is if you have a VPS with little RAM or if you take an Amazon EC2 instance with little memory and CPU.

We will begin by seeing the behavior of the worker system to perform the manipulations later. Firstly according to the StartServers directive when starting the service, we only have 2 processes in addition to the listener on the port (s).

 

$ ps aux |grep apache2 root 54 0.0 0.3 8952 6580 ? Ss 08:41 0:00 /usr/sbin/apache2 -k start www-data 59 0.0 0.2 231584 4656 ? Sl 08:41 0:00 /usr/sbin/apache2 -k start www-data 60 0.0 0.2 231584 4656 ? Sl 08:41 0:00 /usr/sbin/apache2 -k start

We will load up quietly with a first test to see the behavior of the processes. We went nicely with a 200 queries including 10 competitors.

[client]$ ab -n 100 -c 10 -l https://www.linux202-siteA.com/ [ ... OUTPUT COUPÉ ... ] Concurrency Level: 10 Time taken for tests: 2.056 seconds Complete requests: 100 Failed requests: 0 Total transferred: 36900 bytes HTML transferred: 10000 bytes Requests per second: 48.63 [#/sec] (mean) Time per request: 205.628 [ms] (mean) Time per request: 20.563 [ms] (mean, across all concurrent requests) Transfer rate: 17.52 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 33 184 92.6 213 291 Processing: 1 12 17.1 5 77 Waiting: 0 9 14.4 3 64 Total: 34 196 95.1 240 303 Percentage of the requests served within a certain time (ms) 50% 240 66% 263 75% 284 80% 285 90% 287 95% 292 98% 300 99% 303 100% 303 (longest request) [server]$ ps aux | grep apache2 root 54 0.0 0.3 8952 6580 ? Ss 08:41 0:00 /usr/sbin/apache2 -k start www-data 59 0.4 0.3 234884 8084 ? Sl 08:41 0:01 /usr/sbin/apache2 -k start www-data 60 0.3 0.3 234744 8020 ? Sl 08:41 0:01 /usr/sbin/apache2 -k start

As all the queries were processed by threads running through the processes there is no increase of these.

I would like to bring your attention to the first test of AB that we realized realization of ab, we had used the same number of request but with the system prefork, here are the results that we had had:

 

Concurrency Level: 10 Time taken for tests: 2.263 seconds Complete requests: 100 Failed requests: 0 Total transferred: 36900 bytes HTML transferred: 10000 bytes Requests per second: 44.19 [#/sec] (mean) Time per request: 226.313 [ms] (mean) Time per request: 22.631 [ms] (mean, across all concurrent requests) Transfer rate: 15.92 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 33 189 77.2 201 456 Processing: 1 22 19.3 19 86 Waiting: 0 16 16.5 9 76 Total: 34 210 82.5 215 457 Percentage of the requests served within a certain time (ms) 50% 215 66% 237 75% 253 80% 258 90% 288 95% 363 98% 403 99% 457 100% 457 (longest request)

There is not much difference however we see that over time the thread system responds better, this is mainly because the system does not need to wait for the operating system to start processes to make Query management.

Let’s go up to see a little bit: D

 

[client]$ ab -n 200 -c 50 -l https://www.linux202-siteA.com/ [... OUTPUT COUPÉ ..] Percentage of the requests served within a certain time (ms) 50% 992 66% 1007 75% 1014 80% 1026 90% 1066 95% 1073 98% 1077 99% 1135 100% 1266 (longest request) [server]$ ps aux | grep apache root 54 0.0 0.3 8952 6580 ? Ss 08:41 0:00 /usr/sbin/apache2 -k start www-data 59 0.4 0.4 236072 9396 ? Sl 08:41 0:03 /usr/sbin/apache2 -k start www-data 60 0.3 0.4 235944 9556 ? Sl 08:41 0:03 /usr/sbin/apache2 -k start www-data 129 26.8 0.4 235796 9264 ? Sl 08:54 0:01 /usr/sbin/apache2 -k start www-data 159 0.0 0.2 231584 4660 ? Sl 08:54 0:00 /usr/sbin/apache2 -k start [server]$ ps aux | grep apache root 54 0.0 0.3 8952 6580 ? Ss 08:41 0:00 /usr/sbin/apache2 -k start www-data 191 0.0 0.2 231584 4660 ? Sl 08:54 0:00 /usr/sbin/apache2 -k start

I will restore the system prefork and make a real rise in order to demonstrate the difference in behavior we will always use the homepage to have an equivalent test.

As a reminder, the prefork configuration

 

$ cat /etc/apache2/mods-available/mpm_prefork.conf StartServers 5 MinSpareServers 5 MaxSpareServers 10 MaxRequestWorkers 150 MaxConnectionsPerChild 0 [server]$ uptime 08:17:32 up 7 min, 1 user, load average: 0.50, 0.48, 0.28 [client]$ ab -n 500 -c 100 -l https://www.linux202-siteA.com/ Percentage of the requests served within a certain time (ms) 50% 1953 66% 2038 75% 2083 80% 2114 90% 2195 95% 2227 98% 2348 99% 2392 100% 2434 (longest request) # apres le teste de charge [server]$ uptime 08:18:39 up 8 min, 1 user, load average: 3.16, 1.04, 0.47

I activate the prefork mode and redo the test …

$ cat /etc/apache2/mods-enabled/mpm_worker.conf StartServers 2 MinSpareThreads 25 MaxSpareThreads 75 ThreadLimit 64 ThreadsPerChild 25 MaxRequestWorkers 150 MaxConnectionsPerChild 0 [server]$ uptime 08:21:42 up 11 min, 1 user, load average: 0.36, 0.68, 0.44 [client]$ ab -n 500 -c 100 -l https://www.linux202-siteA.com/ Percentage of the requests served within a certain time (ms) 50% 1964 66% 2103 75% 2189 80% 2267 90% 2501 95% 2622 98% 2848 99% 3071 100% 3454 (longest request) # apres le teste de charge [server]$ uptime 08:23:43 up 13 min, 1 user, load average: 14.77, 4.49, 1.75

Clearly it is more powerful … Uh oh the load of the machine is mounted at 14.77, there is a problem we will not be able to load up if the machine is so requested.

The question is why this mounted load, which is not displayed in the demonstration above is the number of processes that were started even if the thread system is more efficient my system is not able to support this mounted load.

I will reduce the number of MaxRequestWorkers from 150 to 25

 

[server]$ uptime 08:31:31 up 21 min, 1 user, load average: 0.58, 2.61, 1.95 [client]$ ab -n 500 -c 100 -l https://www.linux202-siteA.com/ Percentage of the requests served within a certain time (ms) 50% 2149 66% 2557 75% 2602 80% 2634 90% 2693 95% 2708 98% 2751 99% 2755 100% 2802 (longest request) # apres le teste de charge [server]$ uptime 08:31:45 up 21 min, 1 user, load average: 2.30, 2.89, 2.06

Again by reducing the number of concurrent processing that I accept, I reduce the load on the server and allows a better treatment of the latter.

But, but, but we did not say that worker is more efficient … Yes because he does not realize a copy of the processes but manages the requests by thread

 

Worker

# Utilisation de la RAM au démarrage [server]$ ps aux | tr -s " " | cut -d " " -f 6,11- | grep apache | egrep -v "grep|htcache" | awk '{ sum+=$1} END {print sum/1024 " Megs"}' 11.3555 Megs [server]$ uptime 08:45:11 up 24 min, 1 user, load average: 0.20, 0.28, 0.33 [client]$ ab -n 500 -c 100 -l https://www.linux202-siteA.com/ [... OUTPUT COUPÉ ...] Percentage of the requests served within a certain time (ms) 50% 1933 66% 2052 75% 2126 80% 2157 90% 2224 95% 2250 98% 2279 99% 2316 100% 2326 (longest request) [server]$ ps aux | tr -s " " | cut -d " " -f 6,11- | grep apache | egrep -v "grep|htcache" | awk '{ sum+=$1} END {print sum/1024 " Megs"}' 16.0039 Megs [server]$ $ uptime 08:48:57 up 28 min, 1 user, load average: 2.02, 0.65, 0.44

So with the worker mode during the processing time we went up to a big 16 Megs of RAM to process the requests.

PreFork

# Switch de la configuration [server]$ sudo a2dismod mpm_worker [server]$ sudo a2enmod mpm_prefork [server]$ sudo apachectl configtest && sudo /etc/init.d/apache2 restart # Utilisation de la RAM au démarrage [server]$ ps aux | tr -s " " | cut -d " " -f 6,11- | grep apache | egrep -v "grep|htcache" | awk '{ sum+=$1} END {print sum/1024 " Megs"}' 23.0352 Megs [server]$ uptime 08:53:48 up 33 min, 1 user, load average: 0.29, 0.47, 0.41 [client]$ ab -n 500 -c 100 -l https://www.linux202-siteA.com/ [... OUTPUT COUPÉ ...] [server]$ ps aux | tr -s " " | cut -d " " -f 6,11- | grep apache | egrep -v "grep|htcache" | awk '{ sum+=$1} END {print sum/1024 " Megs"}' 157.547 Megs [server]$ uptime 08:54:40 up 34 min, 1 user, load average: 2.39, 0.90, 0.56

Conclusion

Although the load on the server is substantially equivalent to the level of the load average we clearly see a gain in the management of the memory. For the same test we go from 157 Megs (prefork) to 16 Megs (worker) a small 141 Megs d saved.

You may tell me that RAM is not very expensive, however if you see the use of multiple Amazon EC2 instances, or renting a small machine at a lower cost such as VPS you will all benefit from better memory usage available. We will have the same requirement if we set up dockers on the same machine to manage micro services.

Super will tell me but I need to have php me, you probably have an application developed with this language is difficult to get rid of. You do not want to have another apache server just to provide the php service that runs prefork. We will now see how we can make php work with the worker mode.

Improved php performance

Personally I am not a big fan of PHP not that it is a bad programming language, however that simplicity of development has brought are lot of page badly programmed. Result I have a negative bias of this language, I am honest in my remarks, however it is a reality that pages php are very present in our daily lives.

So we’ll see how we can improve the performance of our apache system when we need to run php. We have seen how handled the CPU problem using a cache system, we saw how to deal with the problem of IO when writing file using a file system in memory. On the other hand the ideal solution for the problem of memory remains the use of the module of process management worker unfortunately mod_php can not work with this last one. Let’s see a solution to this problem, we will use php5-fpm.

 

Use in cgi mode (php5-fpm)

PHP-FPM (FastCGI Process Manager) is an SAPI interface for communication between a Web server and PHP, based on the FastCGI protocol and written by Andrei Nigmatulin.

Installation & configuration of php5-fpm

Thank you Debian we have a pasting for that: P.

$ sudo apt-get install php5-fpm libapache2-mod-fastcgi

This will allow us to have a Fastcgi service available for apache, but that’s what it Fastcgi in other words instead that apache is able to interpret itself php files run the / usr / bin / php command to build the page. The downside if you use this method is that I’ve already seen in the pass a small change of behavior in php pages when the latter expects to “live” in apache. We had encountered a problem mainly in environment variables that are not present because not running under apache.

Following the operation you can see that the FastCGI module is already active:

 

$ ls -l /etc/apache2/mods-enabled/*fast* lrwxrwxrwx 1 root root 30 Jul 8 17:05 /etc/apache2/mods-enabled/fastcgi.conf -> ../mods-available/fastcgi.conf lrwxrwxrwx 1 root root 30 Jul 8 17:05 /etc/apache2/mods-enabled/fastcgi.load -> ../mods-available/fastcgi.load

We will disable the mod_php and put the system in worker mode:

$ sudo a2dismod php5 $ sudo a2dismod mpm_prefork $ sudo a2enmod mpm_worker

We could restart apache at this point but we will set up the configuration for php-fpm. We will create the configuration file /etc/apache2/conf-available/php5-fpm.conf

AddHandler php5-fcgi .php Action php5-fcgi /php5-fcgi Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /var/run/php5-fpm.sock -pass-header Authorization

Let’s analyze the configuration file:

  • AddHandler: we add an interpreter for files whose extension ends with .php when this type of file will be processed we will call the handler (the interpreter) php-fcgi

  • Action: Following the identification of the file extension we define the action to take we tell him to communicate with / php5-fcgi

  • Alias: We have already seen Alias mode this allows us to redirect a destination in the URL to another PATH on the server. In our case it will be / usr / lib / cgi-bin / php5-fcgi

  • FastCgiExternalServer: To finish we specify that when communicating to the / usr / lib / cgi-bin / php5-fcgi file it must pass it to the /var/run/php5-fpm.sock socket via the FastCgi system.

WOOT, I almost understood: P, let’s see the files now:

$ ls -l /usr/lib/cgi-bin/php5-fcgi ls: cannot access /usr/lib/cgi-bin/php5-fcgi: No such file or directory $ ls -l /var/run/php5-fpm.sock ls: cannot access /var/run/php5-fpm.sock: No such file or directory

Well there if you just copy pasted configuration files you say to yourself, here is Thomas wrote the documentation after the victory of France against Germany at EURO 2016. He was in the potatoes … No panic j have cuvée since: P

The / usr / lib / cgi-bin / php5-fcgi file is not true but only to force the FastCgiExternalServer call, we will create an empty file.

 

$ sudo touch /usr/lib/cgi-bin/php5-fcgi $ ls -ld /usr/lib/cgi-bin/php5-fcgi -rw-r--r-- 1 root root 0 Jul 8 17:24 /usr/lib/cgi-bin/php5-fcgi

The file /var/run/php5-fpm.sock is a socket defined by the php5-fpm service so we will start it, of course you also have to make sure that this service restarts during a restart of the server all as apache.

$ sudo /etc/init.d/php5-fpm start $ sudo /etc/init.d/php5-fpm status * php5-fpm is running $ ls -l /var/run/php5-fpm.sock srw-rw---- 1 www-data www-data 0 Jul 8 17:26 /var/run/php5-fpm.sock

Let’s activate the configuration:

$ cd /etc/apache2/conf-enabled/ $ sudo ln -s ../conf-available/php5-fpm.conf

Good it looks good GO?

$ sudo apachectl configtest && sudo /etc/init.d/apache2 restart AH00526: Syntax error on line 3 of /etc/apache2/conf-enabled/php5-fpm.conf: Invalid command 'Action', perhaps misspelled or defined by a module not included in the server configuration Action 'configtest' failed. The Apache error log may have more information.

Oupss it was missing a module

$ sudo a2enmod actions

RE GO ?

$ sudo apachectl configtest && sudo /etc/init.d/apache2 restart Syntax OK * Restarting web server apache2 ...done.

Validate the URL: https://www.linux202-sitea.com/info.php Issh: You do not have permission to access /php5-fcgi/info.php on this server.

Validate the logs, I like to put some errors in my training this allows to see a little practice analysis because unfortunately it rarely works the first time: P, it will probably not the same mistakes but it offers a demonstration of analysis.

$ tail /data/vhosts/siteA/logs/error-ssl.log [... OUPUT COUPÉ ...] [Fri Jul 08 17:29:39.669126 2016] [authz_core:error] [pid 473:tid 3051350848] [client 172.17.42.1:43232] AH01630: client denied by server configuration: /usr/lib/cgi-bin/php5-fcgi

Why ?? Remember at the level of security I like blocked the whole system with since the root result all new configuration obliges me to open the access … We will therefore modify the configuration to allow access to the directory / usr / lib / cgi-bin /. Open the file

AddHandler php5-fcgi .php Action php5-fcgi /php5-fcgi Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /var/run/php5-fpm.sock -pass-header Authorization # Authorization de l'access au repertoire cgi-bin Require all granted

It’s gone: D:

$ sudo apachectl configtest && sudo /etc/init.d/apache2 restart

performance test with php5-fpm

Visualization of mpm_worker configurations:

$ cat /etc/apache2/mods-enabled/mpm_worker.conf StartServers 2 MinSpareThreads 25 MaxSpareThreads 75 ThreadLimit 64 ThreadsPerChild 25 MaxRequestWorkers 25 MaxConnectionsPerChild 0

We go on the URL: https://www.linux202-sitea.com/info.php: WOOT it works … Go is the time of stress tests. For the calculation of the use of the RAM, I changed a little the command because in addition to apache we must be able to calculate the service php:

$ ps aux | tr -s " " | grep ^www-data www-data 422 0.0 0.2 86620 4700 ? S 17:26 0:00 php-fpm: pool www www-data 423 0.0 0.4 86620 9912 ? S 17:26 0:00 php-fpm: pool www www-data 551 0.0 0.1 8380 3200 ? S 17:36 0:00 /usr/sbin/fcgi-pm -k start www-data 552 0.0 0.3 232920 7016 ? Sl 17:36 0:00 /usr/sbin/apache2 -k start $ ps aux | tr -s " " | grep ^www-data | cut -d " " -f 6,11- | egrep -v "grep|htcache" | awk '{ sum+=$1} END {print sum/1024 " Megs"}' 24.2461 Megs

So we have the apache2 process but also all processes related to php management

I can not wait to do the load test so GO :).

 

[server]$ uptime 17:41:51 up 47 min, 1 user, load average: 0.53, 0.47, 0.41 [server]$ ps aux | tr -s " " | grep ^www-data | cut -d " " -f 6,11- | egrep -v "grep|htcache" | awk '{ sum+=$1} END {print sum/1024 " Megs"}' 24.2461 Megs [client]$ ab -n 100 -c 10 -l https://www.linux202-siteA.com/info.php Percentage of the requests served within a certain time (ms) 50% 241 66% 263 75% 287 80% 294 90% 313 95% 339 98% 353 99% 361 100% 361 (longest request) [server]$ ps aux | tr -s " " | grep ^www-data | cut -d " " -f 6,11- | egrep -v "grep|htcache" | awk '{ sum+=$1} END {print sum/1024 " Megs"}' 29.543 Megs [server]$ uptime 17:43:26 up 49 min, 1 user, load average: 0.95, 0.59, 0.46

Second test:

[server]$ $ uptime 17:46:41 up 52 min, 1 user, load average: 0.45, 0.57, 0.48 [server]$ ps aux | tr -s " " | grep ^www-data | cut -d " " -f 6,11- | egrep -v "grep|htcache" | awk '{ sum+=$1} END {print sum/1024 " Megs"}' 29.543 Megs [client]$ ab -n 300 -c 30 -l https://www.linux202-siteA.com/info.php Percentage of the requests served within a certain time (ms) 50% 781 66% 842 75% 886 80% 933 90% 1106 95% 1229 98% 1348 99% 1404 100% 1417 (longest request) [server]$ uptime 17:46:55 up 52 min, 1 user, load average: 2.42, 1.00, 0.62 [server]$ ps aux | tr -s " " | grep ^www-data | cut -d " " -f 6,11- | egrep -v "grep|htcache" | awk '{ sum+=$1} END {print sum/1024 " Megs"}' 39.4375 Megs

REF : https://www.digitalocean.com/community/questions/apache-2-4-with-php5-fpm

Comparative with prefork and mod_php5

Let’s resume the test with the mod_prefork with 100 requests including 10 competitors, here is the configuration of the prefork:

$ cat /etc/apache2/mods-enabled/mpm_prefork.conf StartServers 5 MinSpareServers 5 MaxSpareServers 10 # MaxRequestWorkers 150 MaxRequestWorkers 25 MaxConnectionsPerChild 0

It’s gone for the charge test

[server]$ uptime 08:40:58 up 22 min, 1 user, load average: 0.17, 0.44, 0.41 [server]$ ps aux | tr -s " " | cut -d " " -f 6,11- | grep apache | egrep -v "grep|htcache" | awk '{ sum+=$1} END {print sum/1024 " Megs"}' 59.332 Megs [client] $ ab -n 100 -c 10 -l https://www.linux202-siteA.com/info.php Connection Times (ms) min mean[+/-sd] median max Connect: 51 191 65.0 197 334 Processing: 9 41 23.0 34 133 Waiting: 1 21 16.0 18 95 Total: 65 232 73.9 230 407 Percentage of the requests served within a certain time (ms) 50% 230 66% 269 75% 289 80% 296 90% 327 95% 340 98% 383 99% 407 100% 407 (longest request) [server]$ ps aux | tr -s " " | cut -d " " -f 6,11- | grep apache | egrep -v "grep|htcache" | awk '{ sum+=$1} END {print sum/1024 " Megs"}' 130.27 Megs [server]$ uptime 08:41:58 up 23 min, 1 user, load average: 0.14, 0.38, 0.39

Second test with 300 queries including 30 competitors:

[server]$ uptime 08:30:49 up 13 min, 1 user, load average: 0.11, 0.18, 0.21 [server]$ ps aux | tr -s " " | grep ^www-data | cut -d " " -f 6,11- | egrep -v "grep|htcache" | awk '{ sum+=$1} END {print sum/1024 " Megs"}' 43.6719 Megs [client]$ ab -n 300 -c 30 -l https://www.linux202-siteA.com/info.php Percentage of the requests served within a certain time (ms) 50% 736 66% 810 75% 845 80% 867 90% 940 95% 986 98% 1135 99% 1233 100% 1284 (longest request) [server]$ $ ps aux | tr -s " " | grep ^www-data | cut -d " " -f 6,11- | egrep -v "grep|htcache" | awk '{ sum+=$1} END {print sum/1024 " Megs"}' 324.855 Megs [server]$ uptime 08:31:56 up 14 min, 1 user, load average: 2.36, 0.67, 0.36

conclusion

In the current situation with a server that has very little CPU we have very similar results in both modes, in terms of the response time of web pages. We can also see that the load on the CPU is very similar if we refer to the load average of the system. We can see a big improvement in the use of the system at the memory level we have a huge economic using the mpm_worker mode.

Correction of data transfer

We saw the use of mod_cache which allowed us to define a cache system on the pages that are called on our server thus improving the load of the CPU used during the call. I will mention another module to analyze if you have another type of problem. I will not take the time to demonstrate its use, I leave you happy. I think that my added value is not so much in the demonstration of every feature but rather in the demonstration of principles.

If you have a problem of bandwidth usage, your site transmits a lot of data, this congesting the internet link or causing a slowdown during the transfer to the client. With the module mod_deflate you can put a place a compression system of your site during the transfer to the customer. Of course this will have an impact on the use of the CPU on your machine because compression has a hit!

I leave you the pleasure to consult the site of apache in connection with this module: mod_deflate.

Global consideration to improve performance

I might have started with that but I like to go to the heart of the matter to start and return to the less critical considerations later. Because The set of instructions below you can find them on the Internet without me, so there is less value from my point of view.

To improve performance you should consider the following points:

 

  • Distribution of disk access: Access to the hard disk remains a “problematic” point when optimizing performance, the disk being slow you can have a performance boost by adjusting the organization of your file system according to the access. Here are more concrete ways of using:

    • Define your logs on a separate hard disk: It may be optimal for your apache system to write the logs to a dedicated hard disk so that it will not run through the same disk to write the logs AND provide the information of the website.

    • Define the cache on a dedicated disk: Just like logs it is more optimal to dedicate a disk for the cache system instead of putting it on the rest of the file system.

  • Disabling verbose logs: If you enable debug type log mode the system will have to write a large amount to disk thus slow down the system due to disk access. We find the debug mode for php or mod_rewrite.

  • Disabled ALL modules you do not use: All modules use memory, whether you use worker or prefork mode if you do not use them disable. Of course with the prefork mode the impact will be even more significant.

  • Disabled the HostnameLookups directive: If you enable this directive Apache will perform a reverse DNS on the IP address in order to have the associated domain name to write it to the logs. Even if this information can be useful to you I advise you to carry out this operation when generating the statistics of access to the site when your website is less solicited.

  • Using IP Address in Configuration Instead of DNS Names: I am ambiguous about this recommendation, but have seen it repeatedly. Here there is a strong relationship between infrastructure management / maintenance and performance. If you only set IP addresses effectively we save a DNS query. However, this can have a cost on the management, because you lose the flexibility to be able to modify the surrounding infrastructure without modifying the application. So must see according to your problem.
  • Disabling .htaccess File Management: As presented when demonstrating .htaccess files to prevent Apache from looking for this file in each disabled directory.

  • Use Apache for dynamic data: Apache is a Swiss army knife on the web, we can do a lot of things. On the other hand Apache is not the web server is a little greedy with the time of other solution one saw the days, with certainly less functionality but faster. If you have problems supplying your clients you could set up a lighttpd or ngnix server to provide all static content (images, videos, …) and Apache for dynamic content (php, …).

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.

Protection of your website

I’m going to make a small difference on the consideration of the performances, because whatever the configurations that you will put in place if you are victims of a DDOS your site will crash. The goal of the solution is simple, a system analyzes the logs of your website and according to established rules will block the address of the customer. The rules can be simple such as a repeated error number 404 to your site or or a number of requests within a set time, indicating that we are dealing with a robot. The system will implement an iptables firewall application policy on the machine. The software it names: fail2ban.

REF: https://www.digitalocean.com/community/tutorials/how-to-protect-an-apache-server-with-fail2ban-on-ubuntu-14-04 REF: http://r3dux.org/2013 / 06 / how-to-stop-apache-dos-attacks-with-fail2ban /

 

  • URL :

    • http://httpd.apache.org/docs/current/misc/perf-tuning.html

    • https://www.devside.net/articles/apache-performance-tuning

    • http://www.monitis.com/blog/2011/07/05/25-apache-performance-tuning-tips

    • https://wiki.mikejung.biz/Apache

Reference:

  • http://httpd.apache.org/docs/current/misc/perf-tuning.html

  • https://www.devside.net/articles/apache-performance-tuning

  • http://www.monitis.com/blog/2011/07/05/25-apache-performance-tuning-tips

  • https://wiki.mikejung.biz/Apache