37
Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved. Recent Advances in HTTP, controlling them using ruby DeNA Co., Ltd. Kazuho Oku

Recent Advances in HTTP, controlling them using ruby

Embed Size (px)

Citation preview

Page 1: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

Recent Advances in HTTP,controlling them using ruby

DeNA Co., Ltd.Kazuho Oku

Page 2: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

2

Who am I lead developer of H2O HTTP/2 server

⁃ one of the most sophisticated HTTP/2 impl.⁃ initial public release: 2014/10 (license: MITL)⁃ used by Fastly, etc.

author of Cache-Digests Internet Draft⁃ considered as an essential work for HTTP/2

push works at DeNA Co., Ltd. also developer of: Q4M, Starlet, pisojson, ...

Recend Advances in HTTP2, controlling them using ruby

Page 3: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

3

Current State of HTTP

Recend Advances in HTTP2, controlling them using ruby

Page 4: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

4

Why use HTTP/2? latency has become the bottleneck of the Web HTTP/2 to conceal latency by raising concurrency

⁃ 6 concurrent requests in HTTP/1⁃ ~100 in HTTP/2

Recend Advances in HTTP2, controlling them using ruby

Page 5: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

5

Current state of HTTP HTTP/2 (RFC 7540) released on May 2015

1: https://github.com/HTTPWorkshop/workshop2016/blob/master/talks/http2-review-data.pdf

Recend Advances in HTTP2, controlling them using ruby

2015/7

2016/7

0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%

45

28

37

41

18

31

# of transactions by Firefox1

HTTP HTTPS (H1) HTTPS (H2)

Page 6: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

6

Key features of HTTP/2 header compression (HPACK) multiplexing & prioritization push

Recend Advances in HTTP2, controlling them using ruby

Page 7: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

7

Header compression working well according to Mozilla1:

⁃ median – 90% reduction⁃ 80th percentile – 75% reduction⁃ 90th – 10% reduction

Recend Advances in HTTP2, controlling them using ruby

Page 8: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

8

Multiplexing & prioritization HTTP/2 multiplexes responses into one TCP conn.

⁃ client gives hint for prioritization⁃ server uses the hint to schedule the responses

but some client-server pairs don’t do it right

Recend Advances in HTTP2, controlling them using ruby

Page 9: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

9

Push positive reports:

⁃ “20-30% speedup on page render time”2

negative comments:⁃ many unnecessary pushes (47% are reset2)⁃ increased render time in anti-patterns3

⁃ “consider preload instead of push”3

push from edge⁃ how?

2: https://github.com/HTTPWorkshop/workshop2016/blob/master/talks/server-push.pdf3: https://docs.google.com/document/d/1K0NykTXBbbbTlv60t5MyJvXjqKGsCVNYHyLEXIxYMv0/edit

Recend Advances in HTTP2, controlling them using ruby

Page 10: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

10

Fixes?

Recend Advances in HTTP2, controlling them using ruby

Page 11: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

11

Flow of an ideal HTTP transaction respond to high-priority requests

immediately send resources in right order

⁃ first send CSS/JS⁃ then send the HTML⁃ then send the images

push only the resources not cached by the client

Recend Advances in HTTP2, controlling them using ruby

client server

1 RT

T

GET /

HTML (head)

GET css

CSS

GET images

CSS

HTML (body)

images

Page 12: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

12

The reality respond to high-priority requests

immediately⁃ blocked by unsent data in TCP

send resources in right order⁃ some browsers don’t specify

priority, some servers fail to respect priority

⁃ issues caused by hidden resources push only the resources not cached

by the client⁃ how?

Recend Advances in HTTP2, controlling them using ruby

client server

1 RT

T

GET /

HTML (head)

GET css

HTML (body)

GET imagesCSS

images

CSS

Page 13: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

13

TCP head-of-line blocking head-of-line (HoL) blocking:

⁃ high-priority data blocked by preceding data in flight

TCP HoL blocking:⁃ data in TCP send buffer blocks following data of

higher priority

Recend Advances in HTTP2, controlling them using ruby

Page 14: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

14

TCP head-of-line blocking

Recend Advances in HTTP2, controlling them using ruby

typical H2 server writes much more than that can be sent immediately⁃ unsent data in TCP send buffer (and TLS buffer)

HOL-blocks following data

TCP send buffer

CWNDunacked poll threshold

TLS buf.

TLS Records

sent immediately not immediately sent

HTTP/2 frames

Page 15: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

15

TCP head-of-line blocking: the solution write only what can be sent immediately

⁃ obtain CWND and unacked size using TCP_INFO adjust poll threshold to delay write notification

until TCP becomes ready to send some data immediately

Recend Advances in HTTP2, controlling them using ruby

CWNDunacked poll threshold

TLS Records

sent immediately not immediately sent

HTTP/2 frames

TCP send buffer

Page 16: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

16

TCP head-of-line blocking: benchmark 1

Recend Advances in HTTP2, controlling them using ruby

conditions:⁃ server in Ireland, client in Tokyo (RTT 250ms)⁃ load tiny js at the top of a large HTML

result: delay decreased from 511ms to 250ms⁃ i.e. JS fetch latency was 2RTT, became 1 RTT• similar results in other environments

Page 17: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

17

TCP head-of-line blocking: benchmark 2 using same data as previous server: Sakura VPS (Ishikari DC)

Recend Advances in HTTP2, controlling them using ruby

Page 18: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

18

HTTP/2 prioritization

Recend Advances in HTTP2, controlling them using ruby

Root

Leader G

Follower Gweight: 1

HTMLweight: 32

Imageweight: 22

Imageweight: 22

Imageweight: 22

CSSweight: 32

CSSweight: 32

hybrid approach using weights and chaining⁃ servers are expected to obey to the priority

specified by the clients Firefox’s prioritization graph is shown below

JSweight: 32

JSweight: 32

Page 19: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

19

HTTP/2 prioritization some web browsers fail to specify priority

⁃ Safari, Blink⁃ older versions of Chrome also had issues⁃ server-side countermeasures required

Recend Advances in HTTP2, controlling them using ruby

Root

HTMLweight: 16

CSSweight: 16

JSweight: 16

Imageweight: 16

Imageweight: 16

Imageweight: 16

Page 20: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

20

HTTP/2 prioritization: the solution bandwidth distribution on server-side:

⁃ use Weighted Fair Queuing (WFQ) or Deficit Round Robin (DRR)

⁃ some servers do it right:• nghttp2 (and Apache) implements WFQ in O(log N)• H2O approximates WFQ in O(1)

detect dumb clients and fallback to server-driven prioritization⁃ H2O reprioritizes CSS, JS for clients that do not

use priority chains

Recend Advances in HTTP2, controlling them using ruby

Page 21: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

21

HTTP/2 prioritization: benchmark differences between the times spent until first-

paint (red bar)

Recend Advances in HTTP2, controlling them using ruby

Page 22: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

22

Hidden resource hidden resource: a resource

specified in CSS (@import) or JavaScript⁃ was anti-pattern in HTTP/1⁃ anti-pattern in HTTP/2 as well

solution:⁃ avoid use of hidden resources

that block rendering (e.g. CSS, JS)

⁃ or, specify them using link: rel=preload

Recend Advances in HTTP2, controlling them using ruby

client server

GET /

HTML

GET css, images

CSS (w. @import)

GET cssimages

CSS

Page 23: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

23

Push three use-cases:

⁃ prioritization⁃ push while processing request⁃ push from edge

Recend Advances in HTTP2, controlling them using ruby

Page 24: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

24

Pushing for prioritization

Recend Advances in HTTP2, controlling them using ruby

client server

GET /

GET/style.css

HTTP/2 200 OK<html><link rel=style.css...

HTTP/2 200 OKbody: ...#title: ...

1. send CSS, JS first2. then send HTML

(can be rendered progressively)

without push

client server

GET /GET /style.css HTTP/2HTTP/2 200 OKbody: ...#title: ...

with push

HTTP/2 200 OK<html><link rel=style.css ...

Page 25: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

25

Push while processing request web applications involving DB access, etc.

Recend Advances in HTTP2, controlling them using ruby

Page 26: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

26

Push from edge CDNs’ use-case

⁃ utilize the conn. while waiting for app. response

Recend Advances in HTTP2, controlling them using ruby

Page 27: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

27

How to push H2 server may push preloaded links

⁃ e.g. Link: </style.css>; rel=preload⁃ H2 server may push preloaded links⁃ recognized by Apache, H2O, nghttp2⁃ patch exists for Nginx

use nopush attribute to opt-out⁃ e.g. Link: </dontpush.jpg>; rel=preload;

nopush

note: use of preload as a push indicator is upon the process of standardization at W3C

Recend Advances in HTTP2, controlling them using ruby

Page 28: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

28

How to push while processing request

Recend Advances in HTTP2, controlling them using ruby

send Link: rel=preload as interim response⁃ application sends 100 then processes the

request

supported in H2O 2.1

GET / HTTP/1.1Host: example.com

HTTP/1.1 100 ContinueLink: </style.css>; rel=preload

HTTP/1.1 200 OKContent-Type: text/html<!DOCTYPE HTML>...

HTTP/2 server app. server Web app.

GET /

100 ContinueLink: …

GET /

200 OK200 OK

process request

Page 29: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

29

How to push while processing request configure your H2 server

⁃ in case of H2O:mruby.handler: | Proc.new do |env| push_paths = [] if /(\/|\.html)$/.match(env["PATH_INFO"]) push_paths << "/style.css” ... end [399, push_paths.empty? ? {} : {"link" => push_paths.map{|p| "<#{p}>; rel=preload"}.join("\n")}, []] endfile.dir: /path/to/doc-root

Recend Advances in HTTP2, controlling them using ruby

Page 30: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

30

BTW, you can do more by using mruby HTTP authentication

mruby.handler: | require "htpasswd.rb" Htpasswd.new("/path/to/.htpasswd", "realm-name")

DoS mitigationmruby.handler: | require "dos_detector.rb" DoSDetector.new({ :strategy => DoSDetector.CountingStrategy.new({ :period => 10, :threshold => 100, :ban_period => 300, }), })

Recend Advances in HTTP2, controlling them using ruby

Page 31: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

31

... and more Access Control

mruby.handler: | acl { allow { addr == "127.0.0.1" } deny { user_agent.match(/curl/i) && !addr.start_with?("192.168.") } respond(503, {}, ["Service Unavailable"]) { addr == malicious_ip } redirect("https://example.com/", 301) { path =~ /moved/ } use Htpasswd.new("/path/to/.htpasswd", "realm") { path.start_with?("/admin") } }

Recend Advances in HTTP2, controlling them using ruby

Page 32: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

32

... and more fast IPv4 address matching using Trie4

mruby.handler: | require "trie_addr.rb" trie = TrieAddr.new.add([ "192.168.0.0/16", "172.16.0.0/12", ...] ) acl { allow { trie.match?(addr) } deny }

4: http://dsas.blog.klab.org/archives/51293338.html

Recend Advances in HTTP2, controlling them using ruby

Page 33: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

33

How to push from edge depends on CDN

⁃ some CDNs may use RUM-based approach⁃ others may provide DSL• GCP provides http2-push-manifest (JSON-based)

⁃ though cannot be used for pushing from edge⁃ anybody using (m)ruby on edge?

Recend Advances in HTTP2, controlling them using ruby

Page 34: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

34

Push vs. cache why would you ever push cached resources?

⁃ it’s waste of bandwidth (and time) several ways to avoid pushing cached resources

⁃ cookie-based• supported by H2O

⁃ cache-digest• supported by Apache, H2O• needs browser support or ServiceWorker script• standardization in process at IETF

⁃ implement your own

Recend Advances in HTTP2, controlling them using ruby

Page 35: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

35

Avoiding negative effect caused by push don’t push unless your mechanism is cache-aware only push resources that block rendering

⁃ reason:• H2 endpoints have difficulty in distributing

bandwidth bet. pushed and pulled responses• negative effect caused by HoL blocking,

prioritization and hidden resources becomes more apparent with push

above rules don’t apply to the tiny pushes⁃ i.e. those used as a replacement for inlining

(i.e. <img src=“data:...”>)

Recend Advances in HTTP2, controlling them using ruby

Page 36: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

36

Summary

Recend Advances in HTTP2, controlling them using ruby

Page 37: Recent Advances in HTTP, controlling them using ruby

Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.

37

Summary HTTP/2 has become popular the effectiveness varies between implementations

⁃ HoL-blocking avoidance, prioritization, cache-aware push, ...

⁃ upcoming specs (e.g. TLS/1.3, QUIC) may cause even more difference

⁃ careful evaluation of servers / CDNs is important

H2O is the leader in HTTP/2 server performance⁃ and can be configured using mruby

Recend Advances in HTTP2, controlling them using ruby