Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

One channel per HTTP2 stream #6842

Merged
merged 10 commits into from
Sep 28, 2022
Merged

One channel per HTTP2 stream #6842

merged 10 commits into from
Sep 28, 2022

Conversation

yawkat
Copy link
Member

@yawkat yawkat commented Jan 31, 2022

This PR refactors the NettyHttpServer to have a more straight-forward pipeline setup in a separate class (HttpPipelineBuilder), and then uses netty's Http2MultiplexHandler to multiplex each HTTP2 stream from one connection to its own Channel.

Multiplexing improves compatibility with HTTP 1 handlers downstream. While HTTP 1 handlers do not need to be aware of multiple concurrent request or response streams, HTTP 2 handlers do. With multiplexing, the HTTP 1 handlers only manage one HTTP 2 stream each, so concurrent requests are not an issue anymore.

This change prevents a class of bugs related to faulty STREAM_ID handling, such as #6785. It also adds a new feature, concurrent streaming responses (tested in this PR by Http2ConcurrentStreamSpec).

While all tests pass, this is a bit of a risky change. We expose a lot of the handler pipeline to downstream users, and this PR changes that pipeline fundamentally. For example, the SslHandler isn't visible on the pipeline anymore, which might lead downstream code to think SSL is disabled (this caused the test failure fixed in c9456e2). It's possible that there are similar downstream dependencies on the structure of the pipeline in other modules. This is why I'm making this PR to 3.4.x, so that we can see any issues as early as possible.

@yawkat yawkat added the type: improvement A minor improvement to an existing feature label Jan 31, 2022
@yawkat yawkat added this to the 3.4.0 milestone Jan 31, 2022
@yawkat
Copy link
Member Author

yawkat commented Jan 31, 2022

for review: it may be easier to look at 4013917 as its own change, it does most of the refactoring of the HTTP pipeline setup. The subsequent commits change the pipeline setup for the multiplexing.

@yawkat yawkat marked this pull request as draft February 16, 2022 10:14
@yawkat yawkat removed the request for review from jameskleeh March 15, 2022 13:39
@sdelamo sdelamo modified the milestones: 3.4.0, 3.5.0 Mar 18, 2022
@yawkat yawkat added the status: next major version The issue will be considered for the next major version label Mar 18, 2022
@yawkat yawkat modified the milestones: 3.5.0, 4.0.0 May 17, 2022
@yawkat yawkat removed the request for review from graemerocher May 17, 2022 09:12
@yawkat yawkat changed the base branch from 3.4.x to 4.0.x June 24, 2022 13:49
@sonarcloud
Copy link

sonarcloud bot commented Jun 24, 2022

SonarCloud Quality Gate failed.    Quality Gate failed

Bug C 1 Bug
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 4 Code Smells

90.8% 90.8% Coverage
0.0% 0.0% Duplication

yawkat added a commit that referenced this pull request Jun 30, 2022
The changes in #6842 planned for 4.0 will break compatibility of `ChannelPipelineCustomizer` users that modify the server pipeline. This patch introduces a new `ServerNettyCustomizer` API that is more generic and, importantly, allows for more granularity when waiting for the stages of pipeline construction.

Also included in this patch is an extensive test suite that tests the logbook customizer example from the documentation in all scenarios we support (raw http1, tls alpn, and h2c support).
graemerocher pushed a commit that referenced this pull request Jul 28, 2022
The changes in #6842 planned for 4.0 will break compatibility of `ChannelPipelineCustomizer` users that modify the server pipeline. This patch introduces a new `ServerNettyCustomizer` API that is more generic and, importantly, allows for more granularity when waiting for the stages of pipeline construction.

Also included in this patch is an extensive test suite that tests the logbook customizer example from the documentation in all scenarios we support (raw http1, tls alpn, and h2c support).
# Conflicts:
#	http-server-netty/src/main/java/io/micronaut/http/server/netty/HttpPipelineBuilder.java
#	http-server-netty/src/main/java/io/micronaut/http/server/netty/types/files/FileTypeHandler.java
#	http-server-netty/src/main/java/io/micronaut/http/server/netty/types/stream/NettyStreamedCustomizableResponseType.java
@sonarcloud
Copy link

sonarcloud bot commented Aug 3, 2022

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

91.7% 91.7% Coverage
0.0% 0.0% Duplication

@yawkat yawkat marked this pull request as ready for review August 3, 2022 09:12
@yawkat
Copy link
Member Author

yawkat commented Sep 27, 2022

@graemerocher @timyates can you review this, it's blocking #5621

@yawkat yawkat merged commit 8d6862e into 4.0.x Sep 28, 2022
@yawkat yawkat deleted the h2-pipelines branch September 28, 2022 09:06
yawkat added a commit that referenced this pull request Oct 19, 2022
This PR adds a new connection pooling infrastructure to the HTTP client. The biggest changes are in ConnectionManager, which contains network setup code, and in the new PoolResizer class, which handles pool dynamics (it calls into ConnectionManager.Pool to assign requests, establish new connections, etc, but does no network setup by itself).

Changes in no particular order:

- The `http-version` config setting has been replaced by two settings. `plaintext-mode` applies to `http` URLs and can be set to either `HTTP_1` or `H2C`. `alpn-modes` applies to `https` URLs, and determines the protocols that should be supported in protocol negotiation (it's a list, with the supported values `h2` and `http/1.1`). The old http-version setting remains for compatibility, and should remain for 4.0. It is also used in some test cases.
- connection pooling now applies to all connections (except websockets), not just exchange calls, and it is enabled by default.
- HTTP2 connections now use a channel-per-stream model (like #6842), and allow concurrent requests on one connection.
- Connection pool configuration is more fine-grained, with separate settings for HTTP1 and HTTP2.
- Pooled connections are now tracked using netty's resource leak detection, to avoid "dangling" connections in the pool (note: resource leak detection is still only tested widely for the tests in the http-server-netty module atm).
- One minor fix in the http server that came up in the test suite because connection pooling is on by default now.

There are still some TODOs in this PR. Some relate to pending netty improvements (netty/netty#12827 , netty/netty#12830), but work fine for the moment. Some are future improvements that could be made, but that I want to do in separate PRs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: next major version The issue will be considered for the next major version type: improvement A minor improvement to an existing feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants