soheilhy / cmux

Connection multiplexer for GoLang: serve different services on the same port!
Apache License 2.0
2.53k stars 197 forks source link

Compatible issues with HTTP Keep-Alive option, and TCP connection reuse #62

Closed lnshi closed 5 years ago

lnshi commented 5 years ago

I saw the comments/documents on the matchers: https://github.com/soheilhy/cmux/blob/master/matchers.go#L137 (HTTP1HeaderFieldPrefix returns a matcher matching the header fields of the first request of an HTTP 1 connection. If the header with key name has a value prefixed with valuePrefix, this will match.), this will cause issues with HTTP Keep-Alive option, and some connection pool, actually i am already experiencing problem with Chrome and istio-proxy/envoy.

Explanation:

  1. I have 1st http server, and which has the matcher cmux.HTTP1HeaderFieldPrefix("User-Agent", "xxx/m.n"), and which has the endpoint /api/a
  2. I have 2nd http server, and which has the matcher cmux.HTTP1Fast(), and which has the endpoint /api/b
  3. I have 3rd grpc server, and which has the matcher cmux.HTTP2HeaderField("content-type", "application/grpc")

When the client turn on the Keep-Alive, or has the connection pool(only tag the connection by host+port), to reuse the underlying TCP connection, then this will happen:

I know the root cause is the client doesn't tag the connection properly, for our own connection pool we can do that, but for those public client, like Chrome, like those sidecar proxy product, if they are not configurable on how to tag one connection, then we can do nothing.

What is the solution for this kind of case, what are you guys' suggestions? Pls help.

@soheilhy @tamird @acomagu @tmm1

soheilhy commented 5 years ago

CMux is a transparent connection multiplexer. Once a connection is multiplexed, we cannot take back connections that are already multiplexed. In a sense, your problem requires a request multiplexer, which has to be implemented inside your server as requests come in, not outside. The only way to do this in CMux is fake a connection per request which is against the point and is quite expensive. So, I'm afraid, this is not something we can fix or add to CMux.

pennyluis commented 5 years ago

Leave

lnshi commented 5 years ago

@soheilhy thanks for ur reply, i totally agree with ur explanations and thoughts.

pls help to inspire me on what are those best use cases for cmux or more generally to say a layer 4 connection multiplexer?

soheilhy commented 5 years ago

Connection multiplexing is the only use case for Cmux, where you have multiple listeners and you want to use them transparently on a single port. It's not really about layers (i.e., L4 or L7 multiplexing), but about stickiness of multiplexing decision.