outbound: Discover profiles for each unique TCP target#698
outbound: Discover profiles for each unique TCP target#698olix0r merged 9 commits intover/accept-profilesfrom
Conversation
|
Depends on #697 |
The `AcceptHttp` service is stateful. It builds the underlying HTTP, HTTP/2, and TCP service stacks lazily the first time they're needed. This interacts badly with the derived implementation of `Clone`: if it's cloned before the state is set, the state will only be set for the clone, rather than for the original instance in the cache. Since `Prefix` clones and oneshots the underlying service (`AcceptHttp`), this means that we rebuild the HTTP, HTTP/2, and TCP stacks on every connection to the same orig dest. This basically breaks caching for everything other than service profile discovery, causing us to do new destination discovery for every connection to the same original destination. Which...isn't great. This branch fixes this issue by removing the `Clone` impl from `AcceptHttp` and putting it behind a buffer instead. In the future, it may be possible to fix this in a nicer way, but this resolves the issue for now.
Removes defunct identity tests per linkerd/linkerd2#4947
The proxy has classically discovered profiles & endpoints by looking at each HTTP request's headers. This change removes all per-request discovery. Instead, resolution is now done for each unique outbound TCP target (regardless of whether the connection serves HTTP or not). This eager resolution eliminates per-request cache binding; and supports using `TrafficSplit` with non-HTTP services. This has a few side effects: - The `l5d-dst-override` header is no longer honored. - When the application attempts to connect to a pod IP, the proxy no longer load balances these requests among all pods in the service. The proxy will now honor session-stickiness as selected by an application-level load balancer (see linkerd/linkerd2#4956). - TrafficSplits are only applied when a client targets a service's IP. - The proxy no longer performs DNS "canonicalization" to translate relative host header names to a fully-qualified form.
hawkw
left a comment
There was a problem hiding this comment.
i was surprised by how simple the actual functional change is; most of this is actually just the test changes. the change itself is very straightforward! this looks good to me 👍
| H: NewService<(HttpVersion, T)>, | ||
| { | ||
| pub fn new(target: T, server: Server, new_http: H, new_tcp: F, drain: drain::Watch) -> Self { | ||
| tracing::trace!("new AcceptHttp"); |
There was a problem hiding this comment.
we probably don't need this, i stuck it in while debugging and forgot to take it out
| tracing::trace!("new AcceptHttp"); |
| Some(HttpVersion::Http1) => { | ||
| debug!("Handling as HTTP"); | ||
| let http1 = if let Some(svc) = self.http1.clone() { | ||
| trace!("HTTP service already exists"); |
There was a problem hiding this comment.
these were also from debugging but i thought they might actually be worth having.
| pub profile: Option<profiles::Receiver>, | ||
| } | ||
|
|
||
| #[derive(Clone, Debug)] |
There was a problem hiding this comment.
nit: while working on the test changes i realized that it might not be great to derive Debug for TcpLogical, since it has a MPSC receiver in it, which dumps a bunch of internal state that we don't care about...we might want a custom Debug impl for TcpLogical because of that.
not a blocker, can fix it later; just something i remembered while looking at this.
The proxy has classically discovered profiles & endpoints by looking at
each HTTP request's headers. This change removes all per-request
discovery. Instead, resolution is now done for each unique outbound TCP
target (regardless of whether the connection serves HTTP or not). This
eager resolution eliminates per-request cache binding; and supports
using
TrafficSplitwith non-HTTP services.This has a few side effects:
l5d-dst-overrideheader is no longer honored.longer load balances these requests among all pods in the service.
The proxy will now honor session-stickiness as selected by an
application-level load balancer (see Session Stickiness only works with TLS backends linkerd2#4956).
relative host header names to a fully-qualified form.