php conference berlin 2015: running php on nginx
TRANSCRIPT
1
Tips and tricks for high performance websites
Harald ZeitlhoferJune 2015
Boost your website by running PHP on Nginx
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 Applications
5
overloaded pages
6
Modern Web Pages: lots of static content
434 Resources in total on that page:230 JPEGs, 75 PNGs, 50 GIFs, …
more than 20MB page size
7
cached content
can still create roundtrips to the network!
8
Web Request handling
10
Web Request handling
11
PHPrun modes
Apache Module
– traditional approach
– used for most PHP environments
PHP-FPM
– fast process manager
– run multiple PHP worker processes to serve FastCGI requests
HHVM
– Virtual machine for HipHop
– fast PHP engine
– can serve FastCGI requests
12
PHP-FPMFastCGI Process Manager
Available since 5.3.3
Stable since 5.4.1
13
• Installation
• Pool configuration/etc/php5/fpm/pool.d/www.conf
PHP-FPM
[www]user = www-datagroup = www-datalisten = 127.0.0.1:9000 # for Unix socket: unix:/var/run/php5-fpm.sock;
root@hzvm01:/etc/nginx/sites-enabled# ps -ef | grep phproot 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
HHVMHipHop Virtual Machine
Facebook's PHP engine
JIT compiler
supports PHP and Hack
15
• Installation
• start servercd /your/root/folderhhvm --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.listsudo apt-get updatesudo 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
Fast especially at high load
Open Source project (BSD)
Commercial version NGINX Plus
18
/etc/nginx/nginx.conf
# max_clients = worker_processes * worker_connections
worker_processes 8; # number of CPUs
events {worker_connections 1024;multi_accept on;
}
19
• Static content to be served by Nginx
• Dynamic requests to be sent to PHP
Integration
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
Communication 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
Transaction flow
22
http://www.mysite.com/news/browse/2014
to be processed by index.php
URL rewrite
...RewriteEngine OnRewriteCond %{REQUEST_FILENAME} !-dRewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-lRewriteRule ^(.+)$ index.php...
23
http://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 better 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"]);...
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 action
32
FastCGI cache in action
<?phpecho time()."\n";?>
33
FastCGI cache in action
<?phpecho 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_http_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
Apache+PHP Nginx+PHP Nginx+Memcached0
1
2
3
4
5
6
7
8
<?php echo "Hello World";?>
7,28 4,6 3,05
38
• set HTTP response expires header
Client Side Caching
location ~ \.(html|js|css|gif|jpg|jpe|jpeg|png|bmp|tif|pdf|ico)$ { expires 90d; access_log off; error_log off; try_files $uri =404;}
39
• keep handlers for requested static 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 balancingupstream 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_timeout
Load balancing
42
• Nginx running with default settings
• Apache• AllowOverride None
• Multi-process (prefork) mode to allow usage of mod_php
Benchmarking Nginx vs Apache
43
Static HTML, 10k requests
100 500 1000 20000
1
2
3
4
5
6
7
8
9
Apache/2.4.9nginx/1.1.19
concurrency
Tota
l res
pons
e tim
e [s
ec]
44
Performance Monitoring
45
Performance Tools
51
• Load Generator (Apache Benchmark, Selenium, JMeter)
• Firebug, Google Developer ToolsDynatrace Ajax Edition
• Dynatrace Free Trial• Free trial license for 30 days
• Free personal license for developers
My favorite performance tools
http://bit.ly/dttrial
52
www.dynatrace.com
Thank you !!!
Harald ZeitlhoferSenior Technology Strategist
http://blog.dyntrace.com
Dynatrace Free Trial:
http://bit.ly/dttrial