envoyproxy / envoy

Cloud-native high-performance edge/middle/service proxy
https://www.envoyproxy.io
Apache License 2.0
24.96k stars 4.81k forks source link

Feature request: network quality estimator support #8425

Open hainesc opened 5 years ago

hainesc commented 5 years ago

Title: Feature request: Network quality estimator support

Description:

For many applications, it is important to know the network quality of each client. eg, when you watch a video on youtube, it displays different quality (1080p, 720p, 360p...), if your network quality is good, then 1080p, if weak, then 360p. This feature depends on network quality estimator. Now on client side, there are some implementations, see https://chromium.googlesource.com/chromium/src/+/master/net/nqe.

I'd like to see network quality estimator support in envoy, then, the application server side can get network quality of each client and decides which quality of the resources(videos, images) to dispatch for the given request, It will be great for the developers of the applications.

Thanks for your time to take a consideration!

[optional Relevant Links:]

Any extra documentation required to understand the issue. Please open this URL by Chrome: https://googlechrome.github.io/samples/network-information/index.html Example output:

type: undefined
downlink: 2.3Mb/s
rtt: 100ms
downlinkMax: undefinedMb/s
effectiveType: 4g
saveData: false
mattklein123 commented 5 years ago

FWIW this is something we plan on implementing in the context of Envoy Mobile. cc @junr03 @goaway

hainesc commented 5 years ago

Thanks @mattklein123 for your reply.

As RTT(round trip time) is the most important metrics of network quality. I will use RTT as network quality below.

Envoy mobile run on the client side, so the client application developer should fetch RTT and then they have two choices:

  1. Send RTT in http headers(then the server decide which quality of resource to response)
  2. Get RTT and decide which quality of resource to GET(eg, HTTP GET /example_video_720p)

If we do network quality detecting by envoy, and then modify the http request header by adding RTT: 120ms, the client side developer need do nothing (eg HTTP GET /example_video). (The server side get the http headers and decide which quality of resource to response, without any adding work). It matchs the philosophy of envoy which says The network should be transparent to applications.

I think it will be great to the developers.

I don't deny that network quality estimator in Envoy Mobile is a good idea, but please consider that should we do it at server side.

And, another important point is, how to get RTT by Envoy, I think we can do by tcp_diag. See

$ ss -i state established '( sport = :http or dport = :http )'
Netid  Recv-Q Send-Q Local Address:Port                 Peer Address:Port                
tcp    0      0         ::ffff:10.224.17.151:http                 ::ffff:10.93.247.27:59709                
     westwood wscale:6,10 rto:232 rtt:31.697/2.894 ato:40 mss:1368 cwnd:10 bytes_acked:4062 bytes_received:3303 segs_out:10 segs_in:19 data_segs_out:8 data_segs_in:8 send 3.4Mbps lastsnd:3024 lastrcv:3024 lastack:2992 pacing_rate 6.9Mbps rcv_space:28960 minrtt:29.067
tcp    0      0         ::ffff:10.224.17.151:http                 ::ffff:10.93.235.90:51914                
     westwood wscale:6,10 rto:236 rtt:32.086/9.681 ato:40 mss:1368 cwnd:10 bytes_acked:959 bytes_received:776 segs_out:3 segs_in:6 data_segs_out:2 data_segs_in:2 send 3.4Mbps lastsnd:584 lastrcv:584 lastack:552 pacing_rate 6.8Mbps rcv_space:28960 minrtt:31.043
tcp    0      0         ::ffff:10.224.17.151:http                 ::ffff:10.93.247.27:60156                
     westwood wscale:6,10 rto:232 rtt:31.98/15.99 mss:1368 cwnd:10 segs_in:2 send 5.5Kbps lastsnd:3044 lastrcv:3044 lastack:3044 pacing_rate 6.8Mbps rcv_space:28960 minrtt:31.98
hainesc commented 5 years ago

And again, for some clients, eg Chrome, which accept Client hints including RTT and ECT, The only work we need to do at envoy is Intercepting the response package and adding client hints in http headers.

Accept-CH: rtt, ect
Accept-CH-Lifetime: 3600

Then chrome will report the values by adding them in their next request header. See https://developers.google.com/web/updates/2015/09/automating-resource-selection-with-client-hints

Thanks again.