Slide 1

Slide 1 text

@julienviet @vertx_project #Devoxx #vertx Better Performance With HTTP/2 Julien Viet Red Hat

Slide 2

Slide 2 text

@julienviet @vertx_project #Devoxx #vertx Agenda • Why HTTP/2 ? • Server side HTTP/2 • HTTP/2 with Vert.x

Slide 3

Slide 3 text

@julienviet @vertx_project #Devoxx #vertx /me • Open source developer for 15 years • Current @vertx_project lead • Software engineer at Red Hat • Marseille JUG Leader • http://github.com/vietj • @julienviet

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

@julienviet @vertx_project #Devoxx #vertx Latency versus Bandwidth impact Page Load Time as bandwidth increases 1000 1550 2100 2650 3200 1Mbps 2Mbps 2Mbps 4Mbps 5Mbps 6Mbps 7Mbps 8Mbps 9Mbps 10Mbps Page Load Time as latency decrease 1000 1750 2500 3250 4000 200 ms 180 ms 160 ms 140 ms 120 ms 100 ms 80 ms 60 ms 40 ms 20 ms

Slide 7

Slide 7 text

@julienviet @vertx_project #Devoxx #vertx HTTP 1.1 improvements • Persistent connections

Slide 8

Slide 8 text

@julienviet @vertx_project #Devoxx #vertx Current solutions • Multiple connections • CDN • Concatenation / spriting • Compression / minification • Caching • Sharding

Slide 9

Slide 9 text

@julienviet @vertx_project #Devoxx #vertx HTTP/2 • Evolution of SPDY • Same semantic than HTTP/1 • Change the format on the wire • Use a single connection • HTTPS mandatory for browsers • Does not affect websockets

Slide 10

Slide 10 text

B1n4ry

Slide 11

Slide 11 text

Frames

Slide 12

Slide 12 text

COMPR ESS headers headers headers headers headers headers headers headers headers headers headers headers headers headers headers headers headers headers

Slide 13

Slide 13 text

Priorities

Slide 14

Slide 14 text

Push

Slide 15

Slide 15 text

Demo @julienviet @vertx_project #Devoxx #vertx

Slide 16

Slide 16 text

@julienviet @vertx_project #Devoxx #vertx #reactive HTTP/2 is TCP friendly

Slide 17

Slide 17 text

@julienviet @vertx_project #Devoxx #vertx #reactive Server side HTTP/2

Slide 18

Slide 18 text

@julienviet @vertx_project #Devoxx #vertx HTTP/1 vs HTTP/2 benchmark Server HTTP/1 vs HTTP/2 Backend Client 20ms think time

Slide 19

Slide 19 text

@julienviet @vertx_project #Devoxx #vertx Benchmark Throughput ratio 0 0.25 0.5 0.75 1 Aimed throughput (req / sec) 200 300 400 500 600 700 800 • Constant throughput benchmark • Pace requests at a different rates • Log the ratio: request performed/ request planned

Slide 20

Slide 20 text

@julienviet @vertx_project #Devoxx #vertx #reactive Throughput ratio 0 0.25 0.5 0.75 1 Aimed throughput (req / sec) 200 300 400 500 600 700 800 HTTP/1 - 8 connections pipelined

Slide 21

Slide 21 text

@julienviet @vertx_project #Devoxx #vertx #reactive What is limiting us ?

Slide 22

Slide 22 text

FIFO one thing at a time!

Slide 23

Slide 23 text

HTTP/2 multiplexing

Slide 24

Slide 24 text

@julienviet @vertx_project #Devoxx #vertx #reactive Throughput ratio 0 0.25 0.5 0.75 1 Aimed throughput (req / sec) 200 300 400 500 600 700 800 1000 1200 HTTP/1 - 8 connections HTTP/2 - 1 connection / max_concurrent_streams 20

Slide 25

Slide 25 text

@julienviet @vertx_project #Devoxx #vertx #reactive Let’s try more

Slide 26

Slide 26 text

@julienviet @vertx_project #Devoxx #vertx #reactive Throughput ratio 0 0.25 0.5 0.75 1 Aimed throughput (req / sec) 1000 2000 3000 4000 5000 HTTP/2 - 1 connection - max_concurrency_streams 400

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

Congestion

Slide 29

Slide 29 text

@julienviet @vertx_project #Devoxx #vertx #reactive

Slide 30

Slide 30 text

@julienviet @vertx_project #Devoxx #vertx #reactive We are using the wrong abstractions

Slide 31

Slide 31 text

@julienviet @vertx_project #Devoxx #vertx #reactive Concurrency not multithreading

Slide 32

Slide 32 text

@julienviet @vertx_project #Devoxx #vertx #reactive How to make a better usage of our resources ?

Slide 33

Slide 33 text

@julienviet @vertx_project #Devoxx #vertx #reactive HTTP/2 with Eclipse Vert.x

Slide 34

Slide 34 text

@julienviet @vertx_project #Devoxx #vertx http://vertx.io Vert.x is a toolkit for building reactive and polyglot applications for the JVM

Slide 35

Slide 35 text

@julienviet @vertx_project #Devoxx #vertx #reactive Toolkit

Slide 36

Slide 36 text

io.vertx vertx-web 3.3.3 io.vertx vertx-mongo-client 3.3.3

Slide 37

Slide 37 text

dependencies { compile “io.vertx:vertx-web:3.3.3” compile “io.vertx:vertx-mongo-client:3.3.3” }

Slide 38

Slide 38 text

> brew install vert.x … > vertx run server.java

Slide 39

Slide 39 text

> sdk install vert.x … > vertx run server.java

Slide 40

Slide 40 text

@julienviet @vertx_project #Devoxx #vertx #reactive Polyglot

Slide 41

Slide 41 text

public class Server extends AbstractVerticle { public void start() { vertx.createHttpServer() .requestHandler(request -> { request.response() .putHeader(“content-type”, “text/plain”) .end(“Hello from Vert.x”)); ).listen(8080); } }

Slide 42

Slide 42 text

shared class Server() extends Verticle() { start() => vertx.createHttpServer() .requestHandler((req) => req.response() .putHeader(“content-type”, “text/plain”) .end(“Hello from Vert.x!”)) .listen(8080); }

Slide 43

Slide 43 text

vertx.createHttpServer() .requestHandler(function(req) { req.response() .putHeader(“content-type”, “text/plain”) .end(“Hello from Vert.x!”); }).listen(8080);

Slide 44

Slide 44 text

vertx.createHttpServer() .requestHandler({ req -> req.response() .putHeader(“content-type”, “text/plain”) .end(“Hello from Vert.x!”) }).listen(8080)

Slide 45

Slide 45 text

$vertx.create_http_server() .request_handler { |req| req.response() .put_header(“content-type”, “text/plain”) .end “Hello from Vert.x!” }.listen 8080

Slide 46

Slide 46 text

class Server extends ScalaVerticle { override def start(): Unit = { vertx .createHttpServer() .requestHandler(_.response() .putHeader(“content-type”, “text/plain”) .end(“Hello from Vert.x”)) .listen(8080) } }

Slide 47

Slide 47 text

class Server : AbstractVerticle() { override fun start() { vertx.createHttpServer() .requestHandler() { req -> req.response() .putHeader(“content-type”, “text/plain”) .end("Hello from Vert.x”) } .listen(8080) } }

Slide 48

Slide 48 text

@julienviet @vertx_project #Devoxx #vertx #reactive Reactive all the things

Slide 49

Slide 49 text

@julienviet @vertx_project #Devoxx #vertx Blocking user service interface UserService { User loadUser(String userName) throws NotFoundException(); void close(); } User user = service.loadUser(“julien”); System.out.println(user.getName()); service.close(); System.out.println(“done”);

Slide 50

Slide 50 text

@julienviet @vertx_project #Devoxx #vertx Asyncifying the service interface UserService { void loadUser(String userName, Handler> handler); void close(Handler handler); } @FunctionalInterface interface Handler { /** * Something has happened, so handle it. */ void handle(E event); }

Slide 51

Slide 51 text

@julienviet @vertx_project #Devoxx #vertx Asyncifying the service userService.loadUser((Handler> event) -> { if (event.succeeded()) { User user = event.result(); System.out.println(user.getName()); } else { event.cause().printStackTrace(); } userService.close(v - >{ System.out.println(“done”); }); });

Slide 52

Slide 52 text

@julienviet @vertx_project #Devoxx #vertx What events can be ? Ȑ NIO selectors disk operations timers messages  database etc…

Slide 53

Slide 53 text

@julienviet @vertx_project #Devoxx #vertx Events at scale Ȑ      Ȑ Ȑ Ȑ Ȑ Ȑ buffer ->{…} timerID ->{…} asyncFile ->{…} rows ->{…} message ->{…}

Slide 54

Slide 54 text

@julienviet @vertx_project #Devoxx #vertx Reactor pattern with Event Loop Single thread

Slide 55

Slide 55 text

@julienviet @vertx_project #Devoxx #vertx Event Loop benefits • Easier to scale • Mechanical sympathetic • Simple concurrency model

Slide 56

Slide 56 text

@julienviet @vertx_project #Devoxx #vertx HTTP/2 with Vert.x • Server and client • h2 with Jetty ALPN or native OpenSSL / BoringSSL • h2c • HTTP Request / response API • HTTP/2 specific features for extensions like gRPC

Slide 57

Slide 57 text

@julienviet @vertx_project #Devoxx #vertx Non blocking server public static void main(String [] args) { HttpServerOptions options = new HttpServerOptions() .setUseAlpn(true) .setSsl(true) .setKeyStore(new JksOptions() .setPath(“keystore.jks”). .setPassword(“the-password”)); Vertx vertx = Vertx.vertx(); HttpServer server = vertx.createHttpServer(options); ... }

Slide 58

Slide 58 text

@julienviet @vertx_project #Devoxx #vertx Non blocking server public static void main(String [] args) { … HttpServer server = vertx.createHttpServer(options); server.requestHandler(req -> { req.response() .putHeader(“Content-Type”, “text/plain”) .end(“Hello World”); }); server.listen(8080); }

Slide 59

Slide 59 text

@julienviet @vertx_project #Devoxx #vertx Non blocking client public static void main(String [] args) { HttpServerOptions options = new HttpServerOptions() .setProtocolVersion(HttpVersion.HTTP_2) .setUseAlpn(true) .setSsl(true) .setKeyStore(new TrustOptions() .setPath(“trustore.jks”). .setPassword(“the-password”)); HttpClient client = vertx.createHttpClient(options); … }

Slide 60

Slide 60 text

@julienviet @vertx_project #Devoxx #vertx Non blocking client public static void main(String [] args) { … HttpClient client = vertx.createHttpClient(options); client.getNow(“http: //backend”, resp -> { int status = resp.status(); resp.bodyHandler(body -> { System.out.println(body.length()); }); }); }

Slide 61

Slide 61 text

@julienviet @vertx_project #Devoxx #vertx Non blocking proxy server.requestHandler(req -> { HttpServerResponse resp = req.response(); client.getNow(“http: //backend”, clientResp -> { int code = clientResp.status() resp.setStatus(code); clientResp.bodyHandler(body -> { resp.end(body); }); }); });

Slide 62

Slide 62 text

@julienviet @vertx_project #Devoxx #vertx #reactive

Slide 63

Slide 63 text

@julienviet @vertx_project #Devoxx #vertx #reactive

Slide 64

Slide 64 text

@julienviet @vertx_project #Devoxx #vertx #reactive Throughput ratio 0 0.25 0.5 0.75 1 Aimed throughput (req / sec) 1000 2000 3000 4000 5000 HTTP/2 blocking HTTP/2 non blocking

Slide 65

Slide 65 text

@julienviet @vertx_project #Devoxx #vertx #reactive Using a single core!

Slide 66

Slide 66 text

@julienviet @vertx_project #Devoxx #vertx #reactive Let’s for for multicore

Slide 67

Slide 67 text

@julienviet @vertx_project #Devoxx #vertx Multi-reactor pattern

Slide 68

Slide 68 text

@julienviet @vertx_project #Devoxx #vertx #reactive Throughput ratio 0 0.25 0.5 0.75 1 Aimed throughput (req / sec) 1000 2000 3000 4000 5000 7000 9000 11000 13000 HTTP/2 blocking HTTP/2 non blocking -1 core HTTP/2 non blocking - 2 cores

Slide 69

Slide 69 text

@julienviet @vertx_project #Devoxx #vertx #reactive

Slide 70

Slide 70 text

@julienviet @vertx_project #Devoxx #vertx TL;DR; • Unleash concurrency with HTTP/2 • Keep the good old HTTP semantics • Non blocking is a key factor for high concurrency • Vert.x is a great fit for HTTP/2 • reactive ecosystem • easy to scale

Slide 71

Slide 71 text

@julienviet @vertx_project #Devoxx #vertx Thank you • QA • Come grab your Vert.x sticker! • Links • http://vertx.io • https://github.com/vietj/http2-bench • http://www.belshe.com/2010/05/24/more-bandwidth-doesnt-matter- much/ • https://www.infoq.com/presentations/latency-pitfalls • https://hpbn.co