Upgrade to Pro — share decks privately, control downloads, hide ads and more …

unRESTful Web Services mit HTTP/2

unRESTful Web Services mit HTTP/2

HTTP/2, der Nachfolger des aktuellen HTTP/1.1-Protokolls, bringt eine Vielzahl von neuen Möglichkeiten für HTTP-basierte Server-to-Server-Schnittstellen: HTTP/2 ermöglicht bidirektionale Kommunikation, erlaubt Multiplexing innerhalb von TCP-Verbindungen und unterstützt lang laufende und zustandsbehaftete Verbindungen. Der HTTP/2-Standard beschreibt kein JavaScript-API, mit dem die neuen Features im Browser genutzt werden können. Deshalb stehen die neuen Features für Webclients nicht zur Verfügung. Für Server-to-Server-Kommunikation bietet HTTP/2 jedoch viel Potenzial, das über die bisherigen Möglichkeiten von REST-Schnittstellen hinausgeht. Im Vortrag wird HTTP/2 vorgestellt, und es wird gezeigt, wie Java-Entwickler die neuen Features für HTTP-basierte Server-to-Server-Schnittstellen nutzen können.

---

HTTP/2 client used in demos: https://github.com/fstab/h2c

---

W-JAX 2015, https://jax.de

Fabian Stäber

November 04, 2015
Tweet

More Decks by Fabian Stäber

Other Decks in Programming

Transcript

  1. Contents •  HTTP/2 Intro -> My First HTTP/2 Request • 

    HTTP/2 new Features and how to use them in Java – Multiplexing – Server Push – Stream Priorization and Flow Control •  Testing HTTP/2-based REST services
  2. HTTP/2 is all about reducing latency: •  Less protocol overhead

    •  Header compression •  Multiplexing •  Request Priorization •  Server Push Why HTTP/2?
  3. HTTP/2 does not break the Web •  Same semantics as

    HTTP/1 – Request/response based communication – HTTP Sessions and cookies •  Goal: Any HTTP/1 application can be deployed on an HTTP/2 server without code change. Compatibility with HTTP/1
  4. Ilya Grigorik hpbn.co Client Server HTTP/1 Upgrade Other Protocol, e.g.

    WebSocket Switching Protocol with HTTP/1 TCP Connection SSL Handshake
  5. Ilya Grigorik hpbn.co Client Server TCP Connection SSL Handshake +

    ALPN Other Protocol, e.g. HTTP/2 Switching Protocol with HTTP/2
  6. •  SSL is implemented in the JRE in package sun.security.ssl

    •  Jetty provides ALPN version of sun.security.ssl for many OpenJDK 7 and 8 releases •  Must start Java with VM parameter -Xbootclasspath/p:alpn-boot-VERSION.jar •  ALPN will be part of Java 9 with JEP 244 Application Layer Protocol Negotiation ALPN
  7. My First HTTP/2 Request: Example Servlet @Override protected void doGet(HttpServletRequest

    req, HttpServletResponse resp) { resp.setContentType("text/plain"); resp.getWriter().write("Hello, World!"); } demo
  8. My First HTTP/2 Request: Server demo git clone https://github.com/fstab/http2-examples cd

    http2-examples/jetty-http2-server-example mvn package wget http://repo1.maven.org/maven2/org/mortbay/jetty/alpn/\ > alpn-boot/8.1.5.v20150921/alpn-boot-8.1.5.v20150921.jar java -Xbootclasspath/p:alpn-boot-8.1.5.v20150921.jar \ > -jar target/jetty-http2-server-example.jar
  9. My First HTTP/2 Request: Client demo •  HTTP/2 is binary

    – telnet won‘t help •  The curl command doesn‘t support server push messages yet. •  Wrote my own little tool: https:// github.com/fstab/h2c •  h2c start –dump •  h2c get https://localhost:8443 https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  10. HTTP/2 output vs HTTP/1 output HTTP/1.1 200 OK Server: Jetty(9.3.3v20150827)

    Date: Fri, 16 Oct 2015 16:30:35 GMT Content-Type: text/plain;charset=iso-8859-1 {13 bytes} GET / HTTP/1.1 Host: localhost:8443 https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  11. HTTP/2 output vs HTTP/1 output -> HEADERS(3) + END_STREAM +

    END_HEADERS :method: GET :scheme: https :authority: localhost:8443 :path: / <- HEADERS(3) - END_STREAM + END_HEADERS :status: 200 server: Jetty(9.3.3.v20150827) date: Fri, 16 Oct 2015 16:30:35 GMT content-type: text/plain;charset=iso-8859-1 <- DATA(3) + END_STREAM {13 bytes} https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  12. Header Compression: HPACK GET /8-things-about-couchbase/ HTTP/1.1 Host: blog.arungupta.me Connection: keep-alive

    Cache-Control: max-age=0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) C hrome/46.0.2490.71 Safari/537.36 Referer: http://blog.arungupta.me/couchbase-javaone-2015/?utm_source=feedburner&utm_medium=feed& utm_campaign=Feed%3A+MilesToGo+%28Miles+to+go+2.0%29 Accept-Encoding: gzip, deflate, sdch Accept-Language: en-US,en;q=0.8,de;q=0.6,fr;q=0.4 Cookie: PHPSESSID=trr42cnr1u2ugekervdnkb4kc2; NCS_INENTIM=1445065465; JCS_INENREF=http%3 A//t.co/UlzEpBg7wx; JCS_INENTIM=1445065466166; 1919598ddf048ef8060898ffee630b16=7bc66ae543c a8e475a2ec85a9c2e7d49; SJECT15=CKON15; __utma=202419266.948108038.1445065466.1445065466 .1445065466.1; __utmb=202419266.2.10.1445065466; __utmc=202419266; __utmz=202419266.1445065 466.1.1.utmcsr=feedburner|utmccn=Feed:%20MilesToGo%20(Miles%20to%20go%202.0)|utmcmd=feed https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  13. Contents •  HTTP/2 Intro -> My First HTTP/2 Request • 

    HTTP/2 new Features and how to use them in Java – Multiplexing – Server Push – Stream Priorization and Flow Control •  Testing HTTP/2-based REST services https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  14. •  Goal: Make Web Sites faster •  Demo: https:// http2.golang.org/

    gophertiles Multiplexing demo https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  15. Multiplexing for REST: Non-Blocking Services git clone https://github.com/fstab/http2-examples.git cd http2-examples/multiplexing-examples

    mvn package wget http://repo1.maven.org/maven2/org/mortbay/jetty/alpn/\ > alpn-boot/8.1.5.v20150921/alpn-boot-8.1.5.v20150921.jar java -Xbootclasspath/p:alpn-boot-8.1.5.v20150921.jar \ > -jar server/target/server.jar java -Xbootclasspath/p:alpn-boot-8.1.5.v20150921.jar \ > -jar okhttp-client/target/okhttp-client.jar demo https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  16. Multiplexing for REST: Non-Blocking Services @Override protected void doGet(HttpServletRequest req,

    HttpServletResponse resp) { // ... sleep(SECONDS.toMillis(6)); // ... } demo https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  17. HTTP URL Connection private void sendGet() throws Exception { URL

    url = new URL("https://www.twitter.com"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); try (BufferedReader in = new BufferedReader( new InputStreamReader(con.getInputStream()))) { String line; while ((line = in.readLine()) != null) { System.out.println(line); } } } ... and is synchronous! Does not support HTTP/2 ... https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  18. OkHttp Request request = new Request.Builder() .url("https://localhost:8443") .build(); client.newCall(request).enqueue(new Callback()

    { public void onResponse(Response response) throws IOException { // do something with response.body() } }); https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  19. Netty FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, GET, ""); request.headers().addObject(HOST, URI.create("https://localhost:8443"));

    channel.writeAndFlush(request); public class HttpResponseHandler extends SimpleChannelInboundHandler<FullHttpResponse> { @Override protected void messageReceived( ChannelHandlerContext ctx, FullHttpResponse msg) throws Exception { // Do something with msg.content() ChannelPromise promise = streamidPromiseMap.get(streamId); promise.setSuccess(); } } https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  20. Jetty MetaData.Request request = new MetaData.Request( "GET", new HttpURI("https://localhost:8443/"), HTTP_2,

    requestFields); HeadersFrame headersFrame = new HeadersFrame(request, null, true); session.newStream(headersFrame, new FuturePromise<>(), responseListener); Stream.Listener responseListener = new Stream.Listener.Adapter() { @Override public void onData(Stream stream, DataFrame frame, Callback callback) { // do something with frame.getData() callback.succeeded(); } }; https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  21. •  Java SE: new HttpUrlConnection JEP 110 •  Java EE:

    JSR REST Client API ??? Upcoming Standard Libraries https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  22. Contents •  HTTP/2 Intro -> My First HTTP/2 Request • 

    HTTP/2 new Features and how to use them in Java – Multiplexing – Server Push – Stream Priorization and Flow Control •  Testing HTTP/2-based REST services https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  23. Push What it looks like: – Request sent from client to

    server What actually happens: – Push promise sent from server to client HTTP/2 is not a replacement for WebSockets. https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  24. Implicit Push for Web Servers How Web Servers use Push

    for delivering Web Pages: •  For generated content (JSF): Should be possible to know which resources need to be pushed <h:graphicImage library="images" name=“awww.png" /> •  For static content (HTML, Angular, ...): Learn from REFERER header (example included in Jetty as servlet filter). https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  25. Push and REST Example: How to trigger a push request

    in the Jetty server: Request baseRequest = Request.getBaseRequest(req); if (baseRequest.isPushSupported()) { baseRequest .getPushBuilder() .method("GET") .path("/data") .push(); } Will be standardized with Servlet 4.0 !!! https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  26. Push and REST Receive push request in client: Perform regular

    GET request, will be responded from the cache. HOWEVER: Client can be notified about the available response in an onPush() callback. https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  27. Push and REST Efficient Polling with HTTP/2 Server Push: • 

    REST interface where client polls a resource •  In case Server Push is supported, client polls not by time interval but polling is triggered by push message. •  Fully compatible with REST semantics but much more efficient than polling with HTTP/1. •  Makes workarounds like long polling, websockets, etc. obosolete. https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  28. Push and REST git clone https://github.com/fstab/http2-examples.git cd http2-examples/jetty-http2-echo-server mvn package

    java -Xbootclasspath/p:alpn-boot-8.1.5.v20150921.jar \ > -jar target/jetty-http2-echo-server.jar h2c start --dump h2c post --data 'hello' https://localhost:8443/data h2c get https://localhost:8443/data demo https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  29. Push Demo <- PUSH_PROMISE(1) + END_HEADERS Promised Stream Id: 2

    :scheme: https :method: GET :authority: localhost:8443 :path: /data content-length: 12 host: localhost:8443 x-http2-push: PushBuilder referer: https://localhost:8443/data demo https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  30. Contents •  HTTP/2 Intro -> My First HTTP/2 Request • 

    HTTP/2 new Features and how to use them in Java – Multiplexing – Server Push – Stream Priorization and Flow Control •  Testing HTTP/2-based REST services https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  31. Stream Priorization •  HEADERS frame may contain stream dependency • 

    PRIORITY frame contains Weight field •  Api planned in Servlet 4.0 A B C https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  32. Flow Control •  Based on WINDOW_UPDATE frames •  Send up

    to n Bytes, then wait for WINDOW_UPDATE public interface FlowControlStrategy { public static int DEFAULT_WINDOW_SIZE = 65535; public void onDataReceived(ISession session, IStream stream, int length); public void onDataConsumed(ISession session, IStream stream, int length); public void onDataSent(IStream stream, int length); public void onSessionStalled(ISession session); public void onStreamStalled(IStream stream); // ... } https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  33. Contents •  HTTP/2 Intro -> My First HTTP/2 Request • 

    HTTP/2 new Features and how to use them in Java – Multiplexing – Server Push – Stream Priorization and Flow Control •  Testing HTTP/2-based REST services https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  34. Testing with Arquillian Cube <arquillian ... > <extension qualifier="docker"> <!--

    REMOVE THE serverUri IF RUNNING ON LINUX --> <property name="serverUri">https://dockerHost:2376</property> <property name="dockerContainers"> wildfly-docker: image: fstab/wildfly-http2:9.0.1.Final await: strategy: polling sleepPollingTime: 1000 iterations: 120 portBindings: ["8443", "9990"] </property> </extension> https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  35. Testing with Arquillian Cube <container qualifier="wildfly-docker" default="true"> <configuration> <property name="managementAddress">dockerServerIp</property>

    <property name="managementPort">9990</property> <property name="username">admin</property> <property name="password">admin</property> </configuration> </container> </arquillian> https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  36. Testing with rhuss/docker-maven-plugin <plugin> <groupId>org.jolokia</groupId> <artifactId>docker-maven-plugin</artifactId> <version>${project.version}</version> <configuration> <images> <!--

    Docker image to use --> </images> </configuration> <!-- . . . --> https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  37. Testing with rhuss/docker-maven-plugin <!-- . . . --> <executions> <execution>

    <phase>pre-integration-test</phase> <!– start the container --> </execution> <execution> <id>stop</id> <phase>post-integration-test</phase> <!– stop the container --> </execution> </executions> </plugin> https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  38. Testing with OkHttp MockWebServer @Test public void test() throws Exception

    { MockWebServer server = new MockWebServer(); SSLContext sslContext = new SslContextBuilder(getLocalHost().getHostName()).build(); server.useHttps(sslContext.getSocketFactory(), false); server.enqueue(new MockResponse().setBody("hello, world!")); server.enqueue(new MockResponse().setBody("sup, bra?")); server.enqueue(new MockResponse().setBody("yo dog")); server.start(); HttpUrl baseUrl = server.url("/v1/chat/"); // Start the client, connect to baseURL, run some tests. } https://github.com/fstab/h2c https://github.com/fstab/http2-examples
  39. •  Adrian Cole, JavaZone https://vimeo.com/138955225 •  Simone Bordet, Voxxed Days

    Belgrade https://www.youtube.com/watch? v=ve3u00pw4V4 •  Ilya Grigorik: High Performance Browser Networking, http://hpbn.co References https://github.com/fstab/h2c https://github.com/fstab/http2-examples