Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

Hi   my  name   is  Thijs

Slide 3

Slide 3 text

THIJS

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

TAZE

Slide 6

Slide 6 text

Excited   to  be   here!

Slide 7

Slide 7 text

I’m   an  evangelist  at

Slide 8

Slide 8 text

I’m   a  board  member   at

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

It  works  on  my  computer

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

It’s  the  internet’s  fault

Slide 14

Slide 14 text

Developer  !=  web  developer

Slide 15

Slide 15 text

HTTP?  HUH?

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

What  do  you  do  when  things  go  wrong?

Slide 20

Slide 20 text

Do  a  complete  rewrite  !

Slide 21

Slide 21 text

Absolutely   nothing!

Slide 22

Slide 22 text

Throw  servers   at  the  problem

Slide 23

Slide 23 text

Bigger  box

Slide 24

Slide 24 text

More  boxes

Slide 25

Slide 25 text

Reduce   impact

Slide 26

Slide 26 text

What  kind  of  infrastructure  do  you  need?

Slide 27

Slide 27 text

One  big   box?

Slide 28

Slide 28 text

Scale  across   100  nodes?

Slide 29

Slide 29 text

That  big  F5   loadbalancer?

Slide 30

Slide 30 text

Only  the  DB   gets   hammered

Slide 31

Slide 31 text

Lots  of  staCc   traffic

Slide 32

Slide 32 text

Shared  hosCng   will  do  ...   except  during  the   month  of  the  event

Slide 33

Slide 33 text

SaaS PaaS IaaS

Slide 34

Slide 34 text

DB  &   webserver? Or  specialized  tools?

Slide 35

Slide 35 text

m ulC-­‐server  setup About  a

Slide 36

Slide 36 text

m ulC-­‐server  setup About  a Loadbalancing

Slide 37

Slide 37 text

m ulC-­‐server  setup About  a What  about  uploaded  files?

Slide 38

Slide 38 text

m ulC-­‐server  setup About  a What  about  sessions?

Slide 39

Slide 39 text

m ulC-­‐server  setup About  a Database  replicaCon

Slide 40

Slide 40 text

Impact

Slide 41

Slide 41 text

rt_sigaction(SIGQUIT,  {0x7f11489295f0,  [QUIT],  SA_RESTORER|SA_INTERRUPT,  0x7f114d583f rt_sigprocmask(SIG_UNBLOCK,  [QUIT],  NULL,  8)  =  0 rt_sigprocmask(SIG_BLOCK,  [TERM],  NULL,  8)  =  0 rt_sigaction(SIGTERM,  {0x7f11489295f0,  [TERM],  SA_RESTORER|SA_INTERRUPT,  0x7f114d583f rt_sigprocmask(SIG_UNBLOCK,  [TERM],  NULL,  8)  =  0 rt_sigprocmask(SIG_BLOCK,  [XCPU],  NULL,  8)  =  0 rt_sigaction(SIGXCPU,  {0x7f11489295f0,  [XCPU],  SA_RESTORER|SA_INTERRUPT,  0x7f114d583f rt_sigprocmask(SIG_UNBLOCK,  [XCPU],  NULL,  8)  =  0 rt_sigprocmask(SIG_BLOCK,  [XFSZ],  NULL,  8)  =  0 rt_sigaction(SIGXFSZ,  {0x7f11489295f0,  [XFSZ],  SA_RESTORER|SA_INTERRUPT,  0x7f114d583f rt_sigprocmask(SIG_UNBLOCK,  [XFSZ],  NULL,  8)  =  0 open("/proc/meminfo",  O_RDONLY)                  =  3 fstat(3,  {st_mode=S_IFREG|0444,  st_size=0,  ...})  =  0 mmap(NULL,  4096,  PROT_READ|PROT_WRITE,  MAP_PRIVATE|MAP_ANONYMOUS,  -­‐1,  0)  =  0x7f115022 read(3,  "MemTotal:                2097152  kB\nMemFr"...,  1024)  =  560 close(3)                                                                =  0 munmap(0x7f1150225000,  4096)                        =  0 getrlimit(RLIMIT_NOFILE,  {rlim_cur=1024,  rlim_max=1024})  =  0 brk(0x1ae1000)                                                    =  0x1ae1000 brk(0x1b02000)                                                    =  0x1b02000 socket(PF_FILE,  SOCK_STREAM,  0)                  =  3 fcntl(3,  F_SETFL,  O_RDWR|O_NONBLOCK)        =  0 connect(3,  {sa_family=AF_FILE,  path="/var/run/nscd/socket"...},  110)  =  -­‐1  ECONNREFUSE close(3)                                                                =  0 socket(PF_FILE,  SOCK_STREAM,  0)                  =  3 fcntl(3,  F_SETFL,  O_RDWR|O_NONBLOCK)        =  0 connect(3,  {sa_family=AF_FILE,  path="/var/run/nscd/socket"...},  110)  =  -­‐1  ECONNREFUSE close(3)                                                                =  0 open("/etc/services",  O_RDONLY|O_CLOEXEC)  =  3 fstat(3,  {st_mode=S_IFREG|0644,  st_size=18480,  ...})  =  0 System calls

Slide 42

Slide 42 text

rt_sigaction(SIGQUIT,  {0x7f11489295f0,  [QUIT],  SA_RESTORER|SA_INTERRUPT,  0x7f114d583f rt_sigprocmask(SIG_UNBLOCK,  [QUIT],  NULL,  8)  =  0 rt_sigprocmask(SIG_BLOCK,  [TERM],  NULL,  8)  =  0 rt_sigaction(SIGTERM,  {0x7f11489295f0,  [TERM],  SA_RESTORER|SA_INTERRUPT,  0x7f114d583f rt_sigprocmask(SIG_UNBLOCK,  [TERM],  NULL,  8)  =  0 rt_sigprocmask(SIG_BLOCK,  [XCPU],  NULL,  8)  =  0 rt_sigaction(SIGXCPU,  {0x7f11489295f0,  [XCPU],  SA_RESTORER|SA_INTERRUPT,  0x7f114d583f rt_sigprocmask(SIG_UNBLOCK,  [XCPU],  NULL,  8)  =  0 rt_sigprocmask(SIG_BLOCK,  [XFSZ],  NULL,  8)  =  0 rt_sigaction(SIGXFSZ,  {0x7f11489295f0,  [XFSZ],  SA_RESTORER|SA_INTERRUPT,  0x7f114d583f rt_sigprocmask(SIG_UNBLOCK,  [XFSZ],  NULL,  8)  =  0 open("/proc/meminfo",  O_RDONLY)                  =  3 fstat(3,  {st_mode=S_IFREG|0444,  st_size=0,  ...})  =  0 mmap(NULL,  4096,  PROT_READ|PROT_WRITE,  MAP_PRIVATE|MAP_ANONYMOUS,  -­‐1,  0)  =  0x7f115022 read(3,  "MemTotal:                2097152  kB\nMemFr"...,  1024)  =  560 close(3)                                                                =  0 munmap(0x7f1150225000,  4096)                        =  0 getrlimit(RLIMIT_NOFILE,  {rlim_cur=1024,  rlim_max=1024})  =  0 brk(0x1ae1000)                                                    =  0x1ae1000 brk(0x1b02000)                                                    =  0x1b02000 socket(PF_FILE,  SOCK_STREAM,  0)                  =  3 fcntl(3,  F_SETFL,  O_RDWR|O_NONBLOCK)        =  0 connect(3,  {sa_family=AF_FILE,  path="/var/run/nscd/socket"...},  110)  =  -­‐1  ECONNREFUSE close(3)                                                                =  0 socket(PF_FILE,  SOCK_STREAM,  0)                  =  3 fcntl(3,  F_SETFL,  O_RDWR|O_NONBLOCK)        =  0 connect(3,  {sa_family=AF_FILE,  path="/var/run/nscd/socket"...},  110)  =  -­‐1  ECONNREFUSE close(3)                                                                =  0 open("/etc/services",  O_RDONLY|O_CLOEXEC)  =  3 fstat(3,  {st_mode=S_IFREG|0644,  st_size=18480,  ...})  =  0

Slide 43

Slide 43 text

CPU RAM IO

Slide 44

Slide 44 text

Modular   architecture

Slide 45

Slide 45 text

Connection   handling strategy

Slide 46

Slide 46 text

Path   lookups

Slide 47

Slide 47 text

Caching

Slide 48

Slide 48 text

Is  caching   the   answer?

Slide 49

Slide 49 text

Frontend Backend Data   cache Opcode   cache Page   cache APC Memcached SQLite File Redis +more +more

Slide 50

Slide 50 text

What? When  not? How  long? CompaCbility Limited  size

Slide 51

Slide 51 text

APC

Slide 52

Slide 52 text

Do  you  have  a   data  access   strategy?

Slide 53

Slide 53 text

Distributed   cache

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

memcached.sess_prefix = "memc.sess.key." session.save_path="127.0.0.1:11211" session.save_handler = memcached Also   for  session   clustering

Slide 56

Slide 56 text

No content

Slide 57

Slide 57 text

Reverse   (caching)   proxies

Slide 58

Slide 58 text

Protects  your   servers

Slide 59

Slide 59 text

Put  ‘em  before   your   webserver

Slide 60

Slide 60 text

They  honor   your  caching   headers

Slide 61

Slide 61 text

No content

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

Content Delivery Network

Slide 64

Slide 64 text

No content

Slide 65

Slide 65 text

No content

Slide 66

Slide 66 text

I like Varnish

Slide 67

Slide 67 text

Exceptional   performance

Slide 68

Slide 68 text

Open  source   software

Slide 69

Slide 69 text

Varnish   Configuration   Language

Slide 70

Slide 70 text

Supports   ESI

Slide 71

Slide 71 text

Can  handle   purging  &   banning

Slide 72

Slide 72 text

backend default { .host = "127.0.0.1"; .port = "8080"; } acl purge { "localhost"; "127.0.0.1"; "some.host.name.com"; "1.2.3.4"; }

Slide 73

Slide 73 text

sub vcl_recv { if (req.request == "PURGE") { if (!client.ip ~ purge) { error 405 "Not allowed: " + client.ip; } return(lookup); } if (req.request != "GET" && req.request != "HEAD" && req.request != "PUT" && req.request != "POST" && req.request != "TRACE" && req.request != "OPTIONS" && req.request != "DELETE") { return (pipe); }

Slide 74

Slide 74 text

if (req.request != "GET" && req.request != "HEAD") { return (pass); } if (req.http.Accept-Encoding) { if (req.url ~ "\.(gif|jpg|jpeg|swf|flv|mp3|mp4| pdf|ico|png|gz|tgz|bz2)(\?.*|)$") { remove req.http.Accept-Encoding; } else if (req.http.Accept-Encoding ~ "gzip") { set req.http.Accept-Encoding = "gzip"; } else if (req.http.Accept-Encoding ~ "deflate"){ set req.http.Accept-Encoding = "deflate"; } else { remove req.http.Accept-Encoding; } }

Slide 75

Slide 75 text

if (req.url ~ "\.(gif|jpg|jpeg|swf|css|js|flv|mp3| mp4|pdf|ico|png)(\?.*|)$") { unset req.http.cookie; set req.url = regsub(req.url, "\?.*$", ""); return (lookup); } if (req.url ~ "\?(utm_(campaign|medium|source|term)| adParams|client|cx|eid|fbid|feed|ref(id|src)?|v(er| iew))=") { set req.url = regsub(req.url, "\?.*$", ""); } if (req.http.cookie ~ "^ *$") { unset req.http.cookie; }

Slide 76

Slide 76 text

sub vcl_fetch { if (req.url ~ "wp-(login|admin)" || req.url ~ "preview=true" || req.url ~ "xmlrpc.php") { return (hit_for_pass); } if ( (!(req.url ~ "(wp-(login|admin)|login)"))) { unset beresp.http.set-cookie; set beresp.ttl = 1h; } if (req.url ~ "\.(gif|jpg|jpeg|swf|css|js|flv|mp3| mp4|pdf|ico|png)(\?.*|)$") { set beresp.ttl = 365d; } }

Slide 77

Slide 77 text

sub vcl_deliver { if (obj.hits > 0) { set resp.http.X-Cache = "HIT"; } else { set resp.http.X-Cache = "MISS"; } } sub vcl_hit { if (req.request == "PURGE") { purge; set obj.ttl = 0s; error 200 "OK"; } } sub vcl_miss { if (req.request == "PURGE") { purge; error 200 "OK"; } }

Slide 78

Slide 78 text

Webserver     performance

Slide 79

Slide 79 text

Apache  vs  Nginx

Slide 80

Slide 80 text

Prefork  or  worker  mode Async,  event-­‐driven  workers Apache Nginx

Slide 81

Slide 81 text

Evented  non-­‐blocking  I/O We’ll  call   you  back!

Slide 82

Slide 82 text

Blocking var  results  =  db.query("SELECT  *  FROM  tablename"); //use  results   Non-­‐blocking db.query("SELECT  *  FROM  tablename"  ,  function  (results)  {   //use  results   });   //do  something  else  

Slide 83

Slide 83 text

Example var  http  =  require('http'); http.createServer(function  (req,  res)  {    res.writeHead(200,  {'Content-­‐Type':  'text/plain'});    res.end('Hello  World\n'); }).listen(1337,  '127.0.0.1'); console.log('Server  running  at  http://127.0.0.1:1337/');

Slide 84

Slide 84 text

We  can  do  it  in  PHP  too

Slide 85

Slide 85 text

Example writeHead(200, array('Content- Type' => 'text/plain')); $response->end("Hello World\n"); }; $loop = React\EventLoop\Factory::create(); $socket = new React\Socket\Server($loop); $http = new React\Http\Server($socket, $loop); $http->on('request', $app); echo "Server running at http://127.0.0.1:1337\n"; $socket->listen(1337); $loop->run();

Slide 86

Slide 86 text

Real  /me  data Ajax Websockets

Slide 87

Slide 87 text

Websockets var conn = new WebSocket('ws:// some.host'); conn.onmessage = function(e) { console.log(e.data); }; conn.send('Hello World!'); Client

Slide 88

Slide 88 text

Websockets Server Ratchet:   websocket   framework   on  top  of   React

Slide 89

Slide 89 text

clients = new \SplObjectStorage; } public function onOpen(ConnectionInterface $conn) { $this->clients->attach($conn); } public function onMessage(ConnectionInterface $from, $msg) { foreach ($this->clients as $client) { if ($from !== $client) { $client->send('Response: '.$msg); } } } public function onClose(ConnectionInterface $conn) { $this->clients->detach($conn); } public function onError(ConnectionInterface $conn, \Exception $e) { echo "An error has occurred: {$e->getMessage()}\n"; $conn->close(); } }

Slide 90

Slide 90 text

disableVersion(0); $server = IoServer::factory($ws,80,'1.2.3.4'); $server->run();

Slide 91

Slide 91 text

FPM hJp://www.php.net/manual/en/install.fpm.configuraOon.php

Slide 92

Slide 92 text

[www] listen = 9000 user = www-data group = www-data pm = dynamic pm.max_children = 10 pm.start_servers = 4 pm.max_spare_servers = 6 pm.max_requests = 500 php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f [email protected] php_flag[display_errors] = off php_admin_value[error_log] = /var/log/fpm-php.www.log php_admin_flag[log_errors] = on php_admin_value[memory_limit] = 32M

Slide 93

Slide 93 text

upstream fpm { server php1.server.com:9000; server php2.server.com:9000; } upstream memcached { server memcached1.server.com:11211; server memcached2.server.com:11211; } server { root /var/www; index index.php index.html index.htm; server_name nginx.server.com; location / { try_files $uri $uri/ /index.php; } location @php { fastcgi_pass fpm; fastcgi_index index.php; include fastcgi_params; }

Slide 94

Slide 94 text

location ~ \.php$ { set $memcached_key $request_uri; memcached_pass memcached; memcached_next_upstream not_found; default_type text/html; error_page 404 405 502 = @php; } location ~* \.(?:ico|css|js|gif|jpe?g|png)$ { expires max; add_header Pragma public; add_header Cache-Control "public, must- revalidate, proxy-revalidate"; } }

Slide 95

Slide 95 text

Offloading Resources

Slide 96

Slide 96 text

fastcgi_finish_request();

Slide 97

Slide 97 text

Disconnects  from  webserver ConCnues  async  processing

Slide 98

Slide 98 text

No content

Slide 99

Slide 99 text

No content

Slide 100

Slide 100 text

# Reverse Worker Code $worker= new GearmanWorker(); $worker->addServer(); $worker->addFunction("reverse", "my_reverse_function"); while ($worker->work()); function my_reverse_function($job) { return strrev($job->workload()); } # Reverse Client Code $client= new GearmanClient(); $client->addServer(); print $client->do("reverse", "Hello World!");

Slide 101

Slide 101 text

# Reverse Client Code $client= new GearmanClient(); $client->addServer(); print $client->do("reverse", "Hello World!");

Slide 102

Slide 102 text

Don’t  be  clueless

Slide 103

Slide 103 text

Apply  the  tricks

Slide 104

Slide 104 text

And  don’t  forget  to  refactor  aPerwards

Slide 105

Slide 105 text

And  then  relax  ...  and  be  happy

Slide 106

Slide 106 text

No content