User guide for keepalive and compression (#1135)

This commit is contained in:
Xuan Wang 2023-05-30 13:21:54 -07:00 committed by GitHub
parent 620ff1529d
commit 1a668d2016
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 147 additions and 0 deletions

View File

@ -0,0 +1,56 @@
---
title: Compression
description: >-
How to compress the data sent over the wire while using gRPC.
---
### Overview
Compression is used to reduce the amount of bandwidth used when communicating between peers and can be enabled or disabled based on call or message level for all languages. For some languages, it is also possible to control compression settings at the channel level. Different languages also support different compression algorithms, including a customized compressor.
### Compression Method Asymmetry Between Peers
gRPC allows asymmetrically compressed communication, whereby a response may be compressed differently with the request, or not compressed at all. A gRPC peer may choose to respond using a different compression method to that of the request, including not performing any compression, regardless of channel and RPC settings (for example, if compression would result in small or negative gains).
If a client message is compressed by an algorithm that is not supported by a server, the message will result in an `UNIMPLEMENTED` error status on the server. The server will include a `grpc-accept-encoding` header to the response which specifies the algorithms that the server accepts.
If the client message is compressed using one of the algorithms from the `grpc-accept-encoding` header and an `UNIMPLEMENTED` error status is returned from the server, the cause of the error won't be related to compression.
Note that a peer may choose to not disclose all the encodings it supports. However, if it receives a message compressed in an undisclosed but supported encoding, it will include said encoding in the response's `grpc-accept-encoding` header.
For every message a server is requested to compress using an algorithm it knows the client doesn't support (as indicated by the last `grpc-accept-encoding` header received from the client), it will send the message uncompressed.
### Specific Disabling of Compression
If the user requests to disable compression, the next message will be sent uncompressed. This is instrumental in preventing [BEAST] and [CRIME] attacks. This applies to both the unary and streaming cases.
### Language guides and examples
| Language | Example | Documentation |
|----------|------------------|------------------------|
| C++ | [C++ Example] | [C++ Documentation] |
| Go | [Go Example] | [Go Documentation] |
| Java | [Java Example] | [Java Documentation] |
| Python | [Python Example] | [Python Documentation] |
### Additional Resources
* [gRPC Compression]
* [gRPC (Core) Compression Cookbook]
* [gRFC for Python Compression API]
[C++ Example]: https://github.com/grpc/grpc/tree/master/examples/cpp/compression
[C++ Documentation]: https://github.com/grpc/grpc/tree/master/examples/cpp/compression
[Go Example]: https://github.com/grpc/grpc-go/tree/master/examples/features/compression
[Go Documentation]: https://github.com/grpc/grpc-go/blob/master/Documentation/compression.md
[Java Example]: https://github.com/grpc/grpc-java/tree/master/examples/src/main/java/io/grpc/examples/experimental
[Python Example]: https://github.com/grpc/grpc/tree/master/examples/python/compression
[Python Documentation]: https://github.com/grpc/grpc/tree/master/examples/python/compression
[gRPC Compression]: https://github.com/grpc/grpc/blob/master/doc/compression.md
[gRPC (Core) Compression Cookbook]: https://github.com/grpc/grpc/blob/master/doc/compression_cookbook.md#per-call-settings
[gRFC for Python Compression API]: https://github.com/grpc/proposal/blob/master/L46-python-compression-api.md
[BEAST]: https://en.wikipedia.org/wiki/Transport_Layer_Security#BEAST_attack
[CRIME]: https://en.wikipedia.org/wiki/CRIME
[Java Documentation]: https://grpc.github.io/grpc-java/javadoc/io/grpc/CallOptions.html#withCompression-java.lang.String-

View File

@ -0,0 +1,91 @@
---
title: Keepalive
description: >-
How to use HTTP/2 PING-based keepalives in gRPC.
---
### Overview
HTTP/2 PING-based keepalives are a way to keep an HTTP/2 connection alive even when there is no data being transferred. This is done by periodically sending a [PING frame] to the other end of the connection. HTTP/2 keepalives can improve performance and reliability of HTTP/2 connections, but it is important to configure the keepalive interval carefully.
{{% alert title="Note" color="info" %}}
There is a related but separate concern called [Health Checking]. Health checking allows a server to signal whether a *service* is healthy while keepalive is only about the *connection*.
{{% /alert %}}
### Background
[TCP keepalive] is a well-known method of maintaining connections and detecting broken connections. When TCP keepalive was enabled, either side of the connection can send redundant packets. Once ACKed by the other side, the connection will be considered as good. If no ACK is received after repeated attempts, the connection is deemed broken.
Unlike TCP keepalive, gRPC uses HTTP/2 which provides a mandatory [PING frame] which can be used to estimate round-trip time, bandwidth-delay product, or test the connection. The interval and retry in TCP keepalive don't quite apply to PING because the transport is reliable, so they're replaced with timeout (equivalent to interval * retry) in gRPC PING-based keepalive implementation.
{{% alert title="Note" color="info" %}}
It's not required for service owners to support keepalive. **Client authors must coordinate with service owners** for whether a particular client-side setting is acceptable. Service owners decide what they are willing to support, including whether they are willing to receive keepalives at all (If the service does not support keepalive, the first few keepalive pings will be ignored, and the server will eventually send a `GOAWAY` message with debug data equal to the ASCII code for `too_many_pings`).
{{% /alert %}}
### How configuring keepalive affects a call
Keepalive is less likely to be triggered for unary RPCs with quick replies. Keepalive is primarily triggered when there is a long-lived RPC, which will fail if the keepalive check fails and the connection is closed.
For streaming RPCs, if the connection is closed, any in-progress RPCs will fail. If a call is streaming data, the stream will also be closed and any data that has not yet been sent will be lost.
{{% alert title="Warning" color="warning" %}}
To avoid DDoSing, it's important to take caution when setting the keepalive configurations. Thus, it is recommended to avoid enabling keepalive without calls and for clients to avoid configuring their keepalive much below one minute.
{{% /alert %}}
### Common situations where keepalives can be useful
gRPC HTTP/2 keepalives can be useful in a variety of situations, including but not limited to:
* When sending data over a long-lived connection which might be considered as idle by proxy or load balancers.
* When the network is less reliable (For example, mobile applications).
* When using a connection after a long period of inactivity.
### Keepalive configuration specification
| Options | Availability | Description | Client Default | Server Default |
|---|---|---|---|---|
| `KEEPALIVE_TIME` | Client and Server | The interval in milliseconds between PING frames. | INT_MAX (Disabled) | 27200000 (2 hours) |
| `KEEPALIVE_TIMEOUT` | Client and Server | The timeout in milliseconds for a PING frame to be acknowledged. If sender does not receive an acknowledgment within this time, it will close the connection. | 20000 (20 seconds) | 20000 (20 seconds) |
| `KEEPALIVE_WITHOUT_CALLS` | Client | Is it permissible to send keepalive pings from the client without any outstanding streams. | 0 (false) | N/A |
| `PERMIT_KEEPALIVE_WITHOUT_CALLS` | Server | Is it permissible to send keepalive pings from the client without any outstanding streams. | N/A | 0 (false) |
| `PERMIT_KEEPALIVE_TIME` | Server | Minimum allowed time between a server receiving successive ping frames without sending any data/header frame. | N/A | 300000 (5 minutes) |
| `MAX_CONNECTION_IDLE` | Server | Maximum time that a channel may have no outstanding rpcs, after which the server will close the connection. | N/A | INT_MAX (Infinite) |
| `MAX_CONNECTION_AGE` | Server | Maximum time that a channel may exist. | N/A | INT_MAX (Infinite) |
| `MAX_CONNECTION_AGE_GRACE` | Server | Grace period after the channel reaches its max age. | N/A | INT_MAX (Infinite) |
{{% alert title="Note" color="info" %}}
Some languages may provide additional options, please refer to language examples and additional resource for more details.
{{% /alert %}}
### Language guides and examples
| Language | Example | Documentation |
|----------|------------------|------------------------|
| C++ | [C++ Example] | [C++ Documentation] |
| Go | [Go Example] | [Go Documentation] |
| Java | [Java Example] | [Java Documentation] |
| Python | [Python Example] | [Python Documentation] |
### Additional Resources
* [gRFC for Client-side Keepalive]
* [gRFC for Server-side Connection Management]
* [Using gRPC for Long-lived and Streaming RPCs]
[Health Checking]: https://github.com/grpc/grpc/blob/master/doc/health-checking.md
[TCP keepalive]: https://en.wikipedia.org/wiki/Keepalive#TCP_keepalive
[PING frame]: https://httpwg.org/specs/rfc7540.html#PING
[C++ Example]: https://github.com/grpc/grpc/tree/master/examples/cpp/keepalive
[C++ Documentation]: https://github.com/grpc/grpc/blob/master/doc/keepalive.md
[Go Example]: https://github.com/grpc/grpc-go/tree/master/examples/features/keepalive
[Go Documentation]: https://github.com/grpc/grpc-go/blob/master/Documentation/keepalive.md
[Java Example]: https://github.com/grpc/grpc-java/tree/master/examples/src/main/java/io/grpc/examples/keepalive
[Python Example]: https://github.com/grpc/grpc/tree/master/examples/python/keep_alive
[Python Documentation]: https://github.com/grpc/grpc/blob/master/doc/keepalive.md
[gRFC for Client-side Keepalive]: https://github.com/grpc/proposal/blob/master/A8-client-side-keepalive.md
[gRFC for Server-side Connection Management]: https://github.com/grpc/proposal/blob/master/A9-server-side-conn-mgt.md
[Using gRPC for Long-lived and Streaming RPCs]: https://www.youtube.com/watch?v=Naonb2XD_2Q
[Java Documentation]: https://grpc.github.io/grpc-java/javadoc/io/grpc/ManagedChannelBuilder.html#keepAliveTime-long-java.util.concurrent.TimeUnit-