Running PHP on Nginx
-
Upload
harald-zeitlhofer -
Category
Technology
-
view
617 -
download
0
Transcript of Running PHP on Nginx
![Page 1: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/1.jpg)
1
Tips and tricks for high performance websites
Harald Zeitlhofer
Boost your website by running PHP on Nginx
@HZeitlhofer [email protected]
![Page 2: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/2.jpg)
2
• Technology Strategist at Dynatrace • Database and Web Development
• PHP for more than 15 years
• Love to discover new things
Harald Zeitlhofer
![Page 3: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/3.jpg)
3
Tips and tricks for high performance websites
![Page 4: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/4.jpg)
4
Web ApplicaIons
![Page 5: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/5.jpg)
5
![Page 6: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/6.jpg)
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
![Page 7: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/7.jpg)
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!!!
![Page 8: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/8.jpg)
8
cached content
can sIll create roundtrips to the network!
![Page 9: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/9.jpg)
9
Web Request handling
![Page 10: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/10.jpg)
10
Web Request handling
![Page 11: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/11.jpg)
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
![Page 12: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/12.jpg)
12
PHP-‐FPM FastCGI Process Manager
Available since 5.3.3
Stable since 5.4.1
![Page 13: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/13.jpg)
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
![Page 14: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/14.jpg)
14
HHVM HipHop Virtual Machine
Facebook's PHP engine
JIT compiler
supports PHP and Hack
![Page 15: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/15.jpg)
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
![Page 16: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/16.jpg)
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
![Page 17: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/17.jpg)
17
Leading among top 100.000 websites
![Page 18: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/18.jpg)
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; }
![Page 19: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/19.jpg)
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; }
}
![Page 20: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/20.jpg)
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;
![Page 21: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/21.jpg)
21
TransacIon flow
![Page 22: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/22.jpg)
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 ...
![Page 23: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/23.jpg)
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;
} }
![Page 24: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/24.jpg)
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"]); ...
![Page 25: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/25.jpg)
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; }
![Page 26: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/26.jpg)
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"; }
}
![Page 27: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/27.jpg)
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
![Page 28: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/28.jpg)
28
PHAR execuIon
![Page 29: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/29.jpg)
29
Nginx and Caching
![Page 30: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/30.jpg)
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; }
![Page 31: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/31.jpg)
31
FastCGI cache in acIon
![Page 32: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/32.jpg)
32
FastCGI cache in acIon
<?php echo time()."\n"; ?>
![Page 33: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/33.jpg)
33
FastCGI cache in acIon
<?php echo time()."\n"; ?>
![Page 34: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/34.jpg)
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); ... ?>
![Page 35: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/35.jpg)
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)); ... ?>
![Page 36: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/36.jpg)
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; } }
![Page 37: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/37.jpg)
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
![Page 38: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/38.jpg)
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; }
![Page 39: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/39.jpg)
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;
![Page 40: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/40.jpg)
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; }
}
![Page 41: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/41.jpg)
41
• Methods • round-‐robin
• least-‐connected (least_conn)
• session persistence (ip_hash)
• Weighted load balancing
• Health checks • max_fails
• fail_Imeout
Load balancing
![Page 42: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/42.jpg)
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; }
![Page 43: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/43.jpg)
43
news from the NGINX front
![Page 44: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/44.jpg)
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; ... }
![Page 45: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/45.jpg)
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
![Page 46: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/46.jpg)
46
nginScript – js_set http { js_set $hello_world " var str = 'Hello World!'; // JavaScript str; "; server { ... location /{ return 200 $hello_world; } } }
![Page 47: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/47.jpg)
47
nginScript – js_run
location / { js_run " var res; res = $r.response; res.status = 200; res.send('Hello World!'); res.finish(); "; }
![Page 48: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/48.jpg)
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; } }
![Page 49: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/49.jpg)
49
• easy distribuIon of 3rd party modules to end users
• migraIon of exisIng modules (rebuild)
• only cerIfied modules loadable in NGINX Plus
Dynamic modules
![Page 50: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/50.jpg)
50
• Nginx running with default sepngs
• Apache • AllowOverride None
• MulI-‐process (prefork) mode to allow usage of mod_php
Benchmarking Nginx vs Apache
![Page 51: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/51.jpg)
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]
![Page 52: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/52.jpg)
52
Performance Monitoring
![Page 53: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/53.jpg)
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
![Page 54: Running PHP on Nginx](https://reader030.fdocuments.net/reader030/viewer/2022021507/586e0f691a28ab8a588b4d21/html5/thumbnails/54.jpg)
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