Running PHP on Nginx
-
Upload
harald-zeitlhofer -
Category
Technology
-
view
610 -
download
0
Transcript of Running PHP on Nginx
1
Tips and tricks for high performance websites
Harald Zeitlhofer
Boost your website by running PHP on Nginx
@HZeitlhofer [email protected]
2
• Technology Strategist at Dynatrace • Database and Web Development
• PHP for more than 15 years
• Love to discover new things
Harald Zeitlhofer
3
Tips and tricks for high performance websites
4
Web ApplicaIons
5
6
Modern Web Pages: lots of staIc content
434 Resources in total on that page: 230 JPEGs, 75 PNGs, 50 GIFs, …
more than 20MB page size
7
Fifa.com during Worldcup 2014
hXp://blog.dynatrace.com/2014/05/21/is-‐the-‐fifa-‐world-‐cup-‐website-‐ready-‐for-‐the-‐tournament/
largest item on page: favicon.ico with 370 KB!!!
but also some heavyweight CSS and JS files with up to 288 KB!!!
8
cached content
can sIll create roundtrips to the network!
9
Web Request handling
10
Web Request handling
11
PHP run modes
Apache Module
– tradiIonal approach – used for most PHP environments
PHP-‐FPM
– fast process manager
– run mulIple PHP worker processes to serve FastCGI requests
HHVM
– Virtual machine for HipHop
– fast PHP engine – can serve FastCGI requests
12
PHP-‐FPM FastCGI Process Manager
Available since 5.3.3
Stable since 5.4.1
13
• InstallaIon
• Pool configuraIon /etc/php5/fpm/pool.d/www.conf
PHP-‐FPM
[www] user = www-data group = www-data listen = 127.0.0.1:9000 # for Unix socket: unix:/var/run/php5-fpm.sock;
root@hzvm01:/etc/nginx/sites-enabled# ps -ef | grep php root 6435 1 0 14:39 ? 00:00:32 php-fpm: master process (/etc/php5/fpm/php-fpm.conf) spelix 6439 6435 0 14:39 ? 00:00:00 php-fpm: pool batch spelix 6440 6435 0 14:39 ? 00:00:00 php-fpm: pool batch www-data 10576 6435 1 18:45 ? 00:00:48 php-fpm: pool www www-data 10920 6435 1 18:47 ? 00:00:47 php-fpm: pool www www-data 10927 6435 1 18:47 ? 00:00:46 php-fpm: pool www
sudo apt-get install php5-fpm
14
HHVM HipHop Virtual Machine
Facebook's PHP engine
JIT compiler
supports PHP and Hack
15
• InstallaIon
• start server cd /your/root/folder hhvm --mode server -vServer.Type=fastcgi -vServer.Port=9000
echo deb http://dl.hhvm.com/ubuntu trusty main | sudo tee /etc/apt/sources.list.d/hhvm.list sudo apt-get update sudo apt-get install hhvm
hhvm --mode server -vServer.Type=fastcgi –vServer.FileSocket=/var/run/hhvm.sock
16
Nginx
Lightweight HTTP server
Event based request handling
Open Source project (BSD)
Development started in 2002 by Igor Sysoev to solve the c10k problem
Commercial version NGINX Plus
17
Leading among top 100.000 websites
18
/etc/nginx/nginx.conf
# max_clients = worker_processes * worker_connections worker_processes 8; # number of CPUs pcre_jit on; # enable JIT for regex events { worker_connections 1024; multi_accept on; }
19
• StaIc content served by Nginx • Dynamic requests sent to PHP
IntegraIon
server { listen 80; server_name www.yourdomain.com; root /var/www/test; index index.php index.html index.htm;
location ~* \.(html|js|css|gif|jpg|jpe|jpeg|png|bmp|tif|pdf|ico)$ { try_files $uri =404; }
location / { try_files $uri $uri/ =404; }
location ~* \.php$ {
fastcgi_index index.php; fastcgi_pass 127.0.0.1; include fastcgi_params; }
}
20
CommunicaIon via sockets • TCP vs Unix
• Unix slightly faster when used on localhost
• Use TCP for high load
location ~* \.php$ { fastcgi_index index.php; fastcgi_pass 127.0.0.1:9000; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_NAME $fastcgi_script_name; }
fastcgi_pass unix:/var/run/php5-fpm.sock;
21
TransacIon flow
22
hXp://www.mysite.com/news/browse/2014
è to be processed by index.php
URL rewrite
... RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-l RewriteRule ^(.+)$ index.php ...
23
hXp://www.mysite.com/news/browse/2014
è to be processed by index.php
URL rewrite
upstream php { server unix:/var/run/php5-fpm.sock; } server {
listen 80; root /var/www; index index.php index.html index.htm; server_name www.mysite.com;
location / {
try_files $uri $uri/ @missing; }
location @missing {
rewrite (.*) /index.php; }
location ~ .php$ {
fastcgi_index index.php; include fastcgi_params; fastcgi_pass php;
} }
24
using Nginx/PHP-‐FPM there’s a beXer way:
URL rewrite
upstream php { server unix:/var/run/php5-fpm.sock; } server {
listen 80; root /var/www; index index.php index.html index.htm; server_name www.mysite.com;
location /images {
try_files $uri =404; }
location /scripts {
try_files $uri =404; }
location / {
fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME /var/www/index.php; fastcgi_pass php; }
}
<?php
$params = explode('/', $_SERVER["DOCUMENT_URI"]); ...
25
• Easy way to deploy your applicaIon • All source files packed into one *.phar file
PHAR – PHP Archives
location ~* \.(php|phar)$ { fastcgi_index index.php; fastcgi_pass 127.0.0.1:9000; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root/myapp.phar; }
26
PHAR example root@hzvm01:/var/www/app/src# ls -lrtR .: total 8 drwxrwxr-x 2 root root 4096 Oct 10 16:27 lib -rw-r--r-- 1 root root 27 Oct 10 16:27 index.php ./lib: total 4 -rw-r--r-- 1 root root 87 Oct 10 16:27 App.php
root@hzvm01:/var/www/app/src# cat index.php <?php $app = new App(); ?>
root@hzvm01:/var/www/app/src# cat lib/App.php <?php class App { function __construct() { echo "Starting Application\n"; }
}
27
PHAR example
location /myapp { fastcgi_index index.php; fastcgi_pass 127.0.0.1:9000; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root/myapp.phar; }
root@hzvm01:/var/www/app# phar pack -f myapp.phar src lib/App.php index.php root@hzvm01:/var/www/app# l myapp.phar -rw-r--r-- 1 root root 6923 Oct 10 19:51 myapp.phar
28
PHAR execuIon
29
Nginx and Caching
30
• Part of Nginx' FastCGI module
Nginx FastCGI cache
fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=APPKEY:100m inactive=60m; fastcgi_cache_key "$scheme$request_method$host$request_uri";
location ~* \.php$ { fastcgi_index index.php; fastcgi_pass 127.0.0.1:9000; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_cache APPKEY; fastcgi_cache_valid 200 60m; }
31
FastCGI cache in acIon
32
FastCGI cache in acIon
<?php echo time()."\n"; ?>
33
FastCGI cache in acIon
<?php echo time()."\n"; ?>
34
Full page cache with Memcached <?php ... function __construct () { $this->c = new Memcached(); $this->c->addServer('localhost',11211);
} function setCache ($key, $content) { $this->c->set($key, $content);
} ... // get HTML content $html = $this->renderPage(); $this->setCache($_SERVER['REQUEST_URI'], $html); ... ?>
35
Data cache with Memcached <?php ... function __construct () { $this->c = new Memcached(); $this->c->addServer('localhost',11211);
} function setCache ($key, $content) { $this->c->set($key, $content);
} ... // get data structure $newslist = $this->getNewsList(); $this->setCache('/data/news/getlist', json_encode($newslist)); ... ?>
36
• ngx_hXp_memcached_module
Full page / data cache with Nginx and Memcached
upstream php { server unix:/var/run/php5-fpm.sock; } server { location / { set $memcached_key "$uri"; memcached_pass localhost:11211; error_page 404 502 504 = @notincache; } location @notincache { fastcgi_pass php; } }
37
PHP, 5k requests, concurrency 100
0
1
2
3
4
5
6
7
8
Apache+PHP Nginx+PHP Nginx+Memcached
<?php echo "Hello World"; ?>
7,28 4,6 3,05 total Ime in se
c
38
• set HTTP response expires header
Caching StaIc Content
location ~ \.(html|js|css|gif|jpg|jpe|jpeg|png|bmp|tif|pdf|ico)$ { expires 365d; access_log off; error_log off; log_not_found off; add_header Cache-Control "public"; try_files $uri =404; }
39
• keep handlers for requested staIc files open
Filehandle Caching
open_file_cache max=1000 inactive=5m; open_file_cache_valid 60s; open_file_cache_min_uses 5; open_file_cache_errors off;
40
Load balancing upstream php { ip_hash; server unix:/var/run/php5-fpm.sock weight=5; server 192.168.56.12:9000 weight=2; server 192.168.56.13:9000; server 192.168.56.14:9000 backup;
} server { listen 80; root /home/www/test; server_name test.hzvm01; location / { try_files $uri =405; } location ~ \.php$ { fastcgi_pass php; fastcgi_index index.php; include fastcgi_params; }
}
41
• Methods • round-‐robin
• least-‐connected (least_conn)
• session persistence (ip_hash)
• Weighted load balancing
• Health checks • max_fails
• fail_Imeout
Load balancing
42
more performance tuning
location ~ \.(html|js|css|gif|jpg|jpe|jpeg|png|bmp|tif|pdf|ico)$ { expires 365d; access_log off; error_log off; log_not_found off; add_header Cache-Control "public"; try_files $uri =404; }
43
news from the NGINX front
44
• remove the spdy parameter from all listen direcIves !!!
HTTP/2
server { listen 443 ssl http2 default_server; ssl_certificate server.crt; ssl_certificate_key server.key; ... }
45
• first preview announced at nginx.conf 2015 • custom JS engine
• one VM for each request
• JS snippets embedded in NGINX configuraIon
• evaluated at runIme
nginScript
46
nginScript – js_set http { js_set $hello_world " var str = 'Hello World!'; // JavaScript str; "; server { ... location /{ return 200 $hello_world; } } }
47
nginScript – js_run
location / { js_run " var res; res = $r.response; res.status = 200; res.send('Hello World!'); res.finish(); "; }
48
nginScript – request parameters http { js_set $summary " var a, s, h; s += 'Method: ' + $r.method + '\n' + 'HTTP version: ' + $r.httpVersion + '\n'; s += 'Host: ' + $r.headers.host + '\n' + 'Remote Address: ' + $r.remoteAddress + '\n'; s += 'URI: ' + $r.uri + '\n'; s += 'Headers:\n'; for (h in $r.headers) { s += ' header \"' + h + '\" is \"' + $r.headers[h] + '\"\n'; } s += 'Args:\n'; for (a in $r.args) { s += ' arg \"' + a + '\" is \"' + $r.args[a] + '\"\n'; } s; "; server { listen 8000; location /summary { return 200 $summary; } }
49
• easy distribuIon of 3rd party modules to end users
• migraIon of exisIng modules (rebuild)
• only cerIfied modules loadable in NGINX Plus
Dynamic modules
50
• Nginx running with default sepngs
• Apache • AllowOverride None
• MulI-‐process (prefork) mode to allow usage of mod_php
Benchmarking Nginx vs Apache
51
StaIc HTML, 10k requests
0
1
2
3
4
5
6
7
8
9
100 500 1000 2000
Apache/2.4.9 nginx/1.1.19
concurrency
Total respo
nse Im
e [sec]
52
Performance Monitoring
53
• Load Generator (Apache Benchmark, Selenium, JMeter)
• Firebug, Google Developer Tools Dynatrace Ajax EdiIon
• Dynatrace Free Trial • Free trial license for 30 days
• Free personal license for developers
My favorite performance tools
hXp://bit.ly/dXrial
54
www.dynatrace.com
Thank you !!!
Harald Zeitlhofer Performance Advocate #HZeitlhofer [email protected] blog.dynatrace.com
Dynatrace Free Trial Free Personal License hDp://bit.ly/dDrial