newrelic / newrelic-java-agent

The New Relic Java agent
Apache License 2.0
202 stars 143 forks source link

Investigate support for HTTP2/3 #1799

Open jbedell-newrelic opened 7 months ago

jbedell-newrelic commented 7 months ago

It was discovered that our Netty instrumentation does not work with HTTP2/3: Linked issue: https://github.com/newrelic/newrelic-java-agent/issues/1789

As a result, we want to check other instrumentations as well to see if there are any other deficiencies. We may also want to explore adding tests specifically for HTTP2/3.

workato-integration[bot] commented 7 months ago

https://new-relic.atlassian.net/browse/NR-248622

jasonjkeller commented 7 months ago

Great overview of the changes in HTTP/2: https://hpbn.co/http2/ https://web.dev/articles/performance-http2

The core change is that each Message (i.e. Request/Response) is being broken down into a collection of Frames which are then transferred over a single stream, which may interleave many Frames representing many different Messages. This could certainly impact some agent instrumentation.

At the core of all performance enhancements of HTTP/2 is the new binary framing layer, which dictates how the HTTP messages are encapsulated and transferred between the client and server.

The "layer" refers to a design choice to introduce a new optimized encoding mechanism between the socket interface and the higher HTTP API exposed to our applications: the HTTP semantics, such as verbs, methods, and headers, are unaffected, but the way they are encoded while in transit is different.

In short, HTTP/2 breaks down the HTTP protocol communication into an exchange of binary-encoded frames, which are then mapped to messages that belong to a particular stream, all of which are multiplexed within a single TCP connection.

  • Stream: A bidirectional flow of bytes within an established connection, which may carry one or more messages.
  • Message: A complete sequence of frames that map to a logical request or response message.
  • Frame: The smallest unit of communication in HTTP/2, each containing a frame header, which at a minimum identifies the stream to which the frame belongs.

The relation of these terms can be summarized as follows:

  • All communication is performed over a single TCP connection that can carry any number of bidirectional streams.
  • Each stream has a unique identifier and optional priority information that is used to carry bidirectional messages.
  • Each message is a logical HTTP message, such as a request, or response, which consists of one or more frames.
  • The frame is the smallest unit of communication that carries a specific type of data—e.g., HTTP headers, message payload, and so on. Frames from different streams may be interleaved and then reassembled via the embedded stream identifier in the header of each frame.
jasonjkeller commented 6 months ago

HTTP/3 overview: https://www.cloudflare.com/learning/performance/what-is-http3/ https://blog.cloudflare.com/http3-the-past-present-and-future/

An important difference in HTTP/3 is that it runs on QUIC, a new transport protocol. QUIC is designed for mobile-heavy Internet usage in which people carry smartphones that constantly switch from one network to another as they move about their day. This was not the case when the first Internet protocols were developed: devices were less portable and did not switch networks very often.

The use of QUIC means that HTTP/3 relies on the User Datagram Protocol (UDP), not the Transmission Control Protocol (TCP). Switching to UDP will enable faster connections and faster user experience when browsing online.

The QUIC protocol was developed by Google in 2012 and was adopted by the Internet Engineering Task Force (IETF) — a vendor-neutral standards organization — as they started creating the new HTTP/3 standard. After consulting with experts around the world, the IETF has made a host of changes to develop their own version of QUIC.