php projects beyond the lamp stack

89
projects Beyond the LAMP stack By Thijs Feryn PHP

Upload: codemotion

Post on 09-Jan-2017

171 views

Category:

Internet


3 download

TRANSCRIPT

Page 1: PHP projects beyond the LAMP stack

projectsBeyond the LAMP stack

By Thijs Feryn

PHP

Page 2: PHP projects beyond the LAMP stack

Hi, I’m Thijs

Page 3: PHP projects beyond the LAMP stack

I’m @ThijsFeryn on Twitter

Page 4: PHP projects beyond the LAMP stack

I’m an Evangelist

At

Page 5: PHP projects beyond the LAMP stack

I’m a at

board member

Page 6: PHP projects beyond the LAMP stack

LAMPStack?

Page 7: PHP projects beyond the LAMP stack

CPU memory I/O

PHP consumes lots of

Page 8: PHP projects beyond the LAMP stack

Faster PHP

Page 9: PHP projects beyond the LAMP stack
Page 10: PHP projects beyond the LAMP stack
Page 11: PHP projects beyond the LAMP stack

Different approach

Page 12: PHP projects beyond the LAMP stack

Offloading

Page 13: PHP projects beyond the LAMP stack

•Webserver •Database •User process

Page 14: PHP projects beyond the LAMP stack

Caching

Page 15: PHP projects beyond the LAMP stack

Optimize database

Optimize runtime

Avoid

Avoid

Page 16: PHP projects beyond the LAMP stack

Don’t recompute

data that hasn’t

changed

Page 17: PHP projects beyond the LAMP stack

Offload the webserver

Page 18: PHP projects beyond the LAMP stack

Varnish

Page 19: PHP projects beyond the LAMP stack

Reverse proxy

User Varnish Server

Proxyinthedatacenter

Page 20: PHP projects beyond the LAMP stack

✓ Varnish Configuration Language ✓ Edge Side Include support ✓ Gzip compression/decompression ✓ Cache purging ✓ HTTP streaming ✓ Grace mode ✓ Configure backends ✓ Backend loadbalancing ✓ ACL protection ✓ VMODs in C

Varnish

Page 21: PHP projects beyond the LAMP stack

Extend the default behavior

in VCL

Page 22: PHP projects beyond the LAMP stack

✓Strip tracking cookies (Google Analytics, …) ✓Sanitize URL ✓URL whitelist/blacklist ✓PURGE ACLs ✓Edge Side Include rules ✓Alway cache static files ✓Extend hash keys ✓Override TTL ✓Define grace mode

What to extend?

Page 23: PHP projects beyond the LAMP stack

vcl 4.0; import std;

acl purge { "127.0.0.1" }

backend default { .host = "176.62.160.59"; .port = "80"; .connect_timeout = 600s; .first_byte_timeout = 600s; .between_bytes_timeout = 600s; }

sub vcl_recv {

if (req.http.Authorization) { return (pass); }

if (req.http.Accept-Encoding) { 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 { unset req.http.Accept-Encoding; } } if (req.method == "PURGE") { if (!client.ip ~ purge) { return(synth(405,"Not allowed."));

Page 24: PHP projects beyond the LAMP stack

Minimal VCL

Let the application

handle it

Page 25: PHP projects beyond the LAMP stack

Caching in your architecture

Page 26: PHP projects beyond the LAMP stack

Respect HTTP

Page 27: PHP projects beyond the LAMP stack

Cache-control: public, max-age=3600, s-maxage=7200

Cache-control: no-cache, no-store

VS

Page 28: PHP projects beyond the LAMP stack

Cookies?

Page 29: PHP projects beyond the LAMP stack

State

Page 30: PHP projects beyond the LAMP stack

Non-cacheable

content

Page 31: PHP projects beyond the LAMP stack

Edge Side Includes

Page 32: PHP projects beyond the LAMP stack

<!DOCTYPE html><html><head> <title>The Demo</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <link rel="stylesheet" href="/css/bootstrap.min.css"> <link rel="stylesheet" href="/css/bootstrap-theme.min.css"> <script src=“/js/jquery-2.1.4.min.js"></script> <script src="/js/bootstrap.min.js"></script></head><body><nav class="navbar navbar-inverse navbar-fixed-top"> <esi:include src=“http://mysite.dev/nav" /></nav>

<div class="jumbotron"> <esi:include src="http://mysite.dev/jumbotron" /></div>

<div class="container"> {% block content %}{% endblock %} <hr> <footer> <esi:include src="http://mysite.dev/footer" /> </footer></div></body></html>

ESI tags

Page 33: PHP projects beyond the LAMP stack

Or just use AJAX

Async Graceful degradition

Page 34: PHP projects beyond the LAMP stack

✓Cache pages and static assets ✓Fastest way ✓Hit rate may vary ✓Chop your content up in pieces ✓Use ESI or AJAX ✓Gateway to your application

Where does Varnish fit in?

Page 35: PHP projects beyond the LAMP stack

You can also host your

static files on a separate set

of Nginx servers

Page 36: PHP projects beyond the LAMP stack

Content Delivery Network

Page 37: PHP projects beyond the LAMP stack

CDNs are nothing but a

bunch of reverse caching proxies

Page 38: PHP projects beyond the LAMP stack

Put the content where your

user is

Page 39: PHP projects beyond the LAMP stack

Offload the database

Page 40: PHP projects beyond the LAMP stack

Data is stored for flexibility, not for

performance

SQL (joins) allow different

compositions of the same data

Page 41: PHP projects beyond the LAMP stack

Make the data retrieval faster

Page 42: PHP projects beyond the LAMP stack
Page 43: PHP projects beyond the LAMP stack

✓ Key-value store ✓ Fast ✓ Lightweight ✓ Data stored in RAM ✓ ~Memcached ✓ Data types ✓ Data persistance ✓ Replication ✓ Clustering

Redis

Page 44: PHP projects beyond the LAMP stack

Redis$ redis-cli 127.0.0.1:6379> ping PONG 127.0.0.1:6379> set mykey somevalue OK 127.0.0.1:6379> get mykey "somevalue

Page 45: PHP projects beyond the LAMP stack

✓ Strings ✓ Hashes ✓ Lists ✓ Sets ✓ Sorted sets ✓ Geo ✓ …

Redis data types

Page 46: PHP projects beyond the LAMP stack

Redis$ redis-cli 127.0.0.1:6379> hset customer_1234 id 1234 (integer) 1 127.0.0.1:6379> hset customer_1234 items_in_cart 2 (integer) 1 127.0.0.1:6379> hmset customer_1234 firstname Thijs lastname Feryn OK 127.0.0.1:6379> hgetall customer_1234 1) "id" 2) "1234" 3) "items_in_cart" 4) "2" 5) "firstname" 6) "Thijs" 7) "lastname" 8) "Feryn" 127.0.0.1:6379>

Page 47: PHP projects beyond the LAMP stack

$ redis-cli 127.0.0.1:6379> lpush products_for_customer_1234 5 (integer) 1 127.0.0.1:6379> lpush products_for_customer_1234 345 (integer) 2 127.0.0.1:6379> lpush products_for_customer_1234 78 12 345 (integer) 5 127.0.0.1:6379> llen products_for_customer_1234 (integer) 5 127.0.0.1:6379> lindex products_for_customer_1234 1 "12" 127.0.0.1:6379> lindex products_for_customer_1234 2 "78" 127.0.0.1:6379> rpop products_for_customer_1234 "5" 127.0.0.1:6379> rpop products_for_customer_1234 "345" 127.0.0.1:6379> rpop products_for_customer_1234 "78" 127.0.0.1:6379> rpop products_for_customer_1234 "12" 127.0.0.1:6379> rpop products_for_customer_1234 "345" 127.0.0.1:6379> rpop products_for_customer_1234 (nil) 127.0.0.1:6379>

Redis

Page 48: PHP projects beyond the LAMP stack

Clustering

Page 49: PHP projects beyond the LAMP stack

✓ Database/API cache ✓ PHP session storage ✓ Message queue (lists) ✓ NoSQL database ✓ Real-time data retrieval

Where does Redis fit in?

Page 50: PHP projects beyond the LAMP stack

Basically: Real-time

& volatile data

Page 51: PHP projects beyond the LAMP stack

BUT:

MySQL can still remain “source of truth” database

Page 52: PHP projects beyond the LAMP stack
Page 53: PHP projects beyond the LAMP stack

✓Full-text search engine ✓Analytics engine ✓NoSQL database ✓Lucene based ✓Built-in clustering, replication, sharding ✓RESTful interface ✓Schemaless

ElasticSearch

Page 54: PHP projects beyond the LAMP stack

POST /my-index {"acknowledged":true}

POST/my-index/my-type { "key" : "value", "date" : "2015-05-10", "counter" : 1, "tags" : ["tag1","tag2","tag3"] }

{ "_index": "my-index", "_type": "my-type", "_id": "AU089olr9oI99a_rK9fi", "_version": 1, "created": true }

Confirmation

Page 55: PHP projects beyond the LAMP stack

GET/my-index/my-type/AU089olr9oI99a_rK9fi?pretty

{ "_index": "my-index", "_type": "my-type", "_id": "AU089olr9oI99a_rK9fi", "_version": 1, "found": true, "_source": { "key": "value", "date": "2015-05-10", "counter": 1, "tags": [ "tag1", "tag2", "tag3" ] } }

Retrieve document by

id

Document & meta data

Page 56: PHP projects beyond the LAMP stack

Analyzed vs

non-analyzed

Full-text vs

exact value

Filter vs

Query

Page 57: PHP projects beyond the LAMP stack

Search

Page 58: PHP projects beyond the LAMP stack

POST /products/product/_search?pretty { "query": { "match": { "name.raw": "Linen Blazer" } } }

POST /products/product/_search?pretty { "query": { "filtered": { "query": { "match_all": {} }, "filter": { "term": { "name": "Linen Blazer" } } } } }

Matches 2 products

Matches 1 product

Page 59: PHP projects beyond the LAMP stack

Aggregations

Page 60: PHP projects beyond the LAMP stack

Group by on steroids

Page 61: PHP projects beyond the LAMP stack

POST /products/product/_search?pretty { "fields": ["category","price","name"], "query": { "match": { "name.raw": "blazer" } }, "aggs": { "avg_price": { "avg": { "field": "price" } }, "min_price" : { "min": { "field": "price" } }, "max_price" : { "max": { "field": "price" } }, "number_of_products_per_category" : { "terms": { "field": "category", "size": 10 } } } }

Multi-group by &

query

Page 62: PHP projects beyond the LAMP stack

"aggregations": { "min_price": { "value": 455 }, "number_of_products_per_category": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "Blazers", "doc_count": 2 }, { "key": "Default Category", "doc_count": 2 }, { "key": "Men", "doc_count": 2 } ] }, "max_price": { "value": 490 }, "avg_price": { "value": 472.5 } }

Aggregation output

Page 63: PHP projects beyond the LAMP stack

Clustering

Page 64: PHP projects beyond the LAMP stack

✓ Full-text search engine with drill-down search

✓ Human language & text analysis

✓ NoSQL database ✓ Big data analytics tool

using Kibana

Where does ElasticSearch fit in?

Page 65: PHP projects beyond the LAMP stack
Page 66: PHP projects beyond the LAMP stack

Offload the user process

Page 67: PHP projects beyond the LAMP stack

Worker scripts

Page 68: PHP projects beyond the LAMP stack

✓ Uses PHP-CLI ✓ Runs continuously ✓ Process forking ✓ Pthreads ✓ Run worker scripts in

parallel ✓ Managed by supervisord

Worker scripts

Page 69: PHP projects beyond the LAMP stack

✓ Sync MySQL & Redis/ElasticSearch

✓ Resize images ✓ Async logging & metrics ✓ Other tasks that shouldn’t

block the user process

Worker scripts

Page 70: PHP projects beyond the LAMP stack

Message queues

Page 71: PHP projects beyond the LAMP stack
Page 72: PHP projects beyond the LAMP stack

✓ Pub/sub ✓ Speaks AMQP protocol ✓ Supported by Pivotal ✓ Channels/Exchanges/

Queues ✓ Built-in clustering ✓ Reliable messaging

RabbitMQ

Page 73: PHP projects beyond the LAMP stack

✓ Take load away from user process

✓ Free up resources on frontend servers

✓ Elaborate messaging strategies

✓ Async event-based actions

Where do RabbitMQ/workers fit in?

Page 74: PHP projects beyond the LAMP stack

But with most of these tools we still

go through the PHP runtime …

Page 75: PHP projects beyond the LAMP stack
Page 76: PHP projects beyond the LAMP stack
Page 77: PHP projects beyond the LAMP stack

SOA Microservices

AJAX Websockets

Page 78: PHP projects beyond the LAMP stack

✓ Javascript runtime ✓ Async ✓ Event-driven ✓ Non-blocking I/O ✓ Callbacks ✓ Lightweight ✓ NPM packages ✓ Backend-code in Javascript

NodeJS

Page 79: PHP projects beyond the LAMP stack

const http = require('http');

const hostname = '127.0.0.1'; const port = 1337;

http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello World\n'); }).listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); });

Page 80: PHP projects beyond the LAMP stack

Gateway to ElasticSearch,

RabbitMQ & Redis

Page 81: PHP projects beyond the LAMP stack
Page 82: PHP projects beyond the LAMP stack

✓ Compiled language for the web ✓ Invented by Google ✓ Strictly typed ✓ Feels like your average

interpreted language ✓ Async features ✓ Built for systems programming ✓ REALLY fast ✓ Not object oriented

Go(lang)

Page 83: PHP projects beyond the LAMP stack

package main

import ( "fmt" "net/http" "goji.io" "goji.io/pat" "golang.org/x/net/context" )

func hello(ctx context.Context, w http.ResponseWriter, r *http.Request) { name := pat.Param(ctx, "name") fmt.Fprintf(w, "Hello, %s!", name) }

func main() { mux := goji.NewMux() mux.HandleFuncC(pat.Get("/hello/:name"), hello) http.ListenAndServe("localhost:8000", mux) }

Page 84: PHP projects beyond the LAMP stack

Really fast workers Really fast APIs

Could replace PHP

workers

Could replace NodeJS

Page 85: PHP projects beyond the LAMP stack

The end game

Page 86: PHP projects beyond the LAMP stack

✓ Cache pages (Varnish) ✓ Assemble content via ESI or AJAX ✓ Static assets on Nginx or CDN ✓ Business logic in lightweight API calls

(NodeJS, Go) ✓ Key-value stores for volatile & real-time

data in Redis ✓ ElasticSearch as a NoSQL database ✓ RabbitMQ for async communication ✓ Worker processes read from message

queue

End game

Page 87: PHP projects beyond the LAMP stack

Use the right tool for the job

Page 88: PHP projects beyond the LAMP stack

Use the tools you like

Page 89: PHP projects beyond the LAMP stack