15

Looking at gRPC Java doc - ManagedChannelBuilder, there're two options to manage the connections. It seems idleTimeout() is the default/preferred configuration. But when I tried to search for a comparison, most of the posts are talking about keepAlive option.

I'm curious about what's the common practise and what are the pros and cons of these two options?

idleTimeout

Set the duration without ongoing RPCs before going to idle mode. In idle mode the channel shuts down all connections, the NameResolver and the LoadBalancer. A new RPC would take the channel out of idle mode. A channel starts in idle mode. Defaults to 30 minutes.

This is an advisory option. Do not rely on any specific behavior related to this option.

keepAliveWithoutCalls

Sets whether keepalive will be performed when there are no outstanding RPC on a connection. Defaults to false.

Clients must receive permission from the service owner before enabling this option. Keepalives on unused connections can easilly accidentally consume a considerable amount of bandwidth and CPU. idleTimeout() should generally be used instead of this option.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
xialin
  • 7,686
  • 9
  • 35
  • 66

1 Answers1

16

Use keepalive to notice connection failures while RPCs are in progress. Use idleTimeout to release resources and prevent idle TCP connections from breaking when the channel is unused.

idleTimeout is preferred over keepAliveWithoutCalls because it tends to reduce the overall load in the system. keepAliveWithoutCalls is used when you are willing to spend client, server, and network resources to have lower latency for very infrequent RPCs.

Eric Anderson
  • 24,057
  • 5
  • 55
  • 76
  • Thanks! Do you mean they can co-exist? – xialin Sep 13 '19 at 23:59
  • 1
    Yes, all three settings can co-exist. Combining keepAlive (only with calls) and idleTimeout in particular produce a pretty complete solution that is low overhead. – Eric Anderson Sep 16 '19 at 23:06
  • 1
    Is it possible to change the keepAlive after the channel has been created or is it a 1 time initialization setting? – Randgalt Jan 24 '20 at 02:34
  • 1
    It can only be set during initial channel construction. We're not aware of a use-case in which in would need to vary over time. – Eric Anderson Jan 24 '20 at 15:58
  • Is there an option to provide infinite idletimeout ? – debonair Jan 13 '22 at 08:09
  • 1
    @debonair, the idle code disables itself for large values as an optimization. Just use Long.MAX_VALUE with any unit. 2^63 nanoseconds is ~300 years. – Eric Anderson Jan 13 '22 at 17:43
  • This option is not available in C++. – debonair Jan 14 '22 at 05:10
  • @debonair, C++ does not have idle timeout enabled by default. C++ similarly disables itself with MAX_INT (the default). https://github.com/grpc/grpc/blob/2d4f3c56001cd1e1f85734b2f7c5ce5f2797c38a/include/grpc/impl/codegen/grpc_types.h#L169-L172 – Eric Anderson Jan 14 '22 at 21:44
  • 3
    @EricAnderson could you elaborate on `Use keepalive to notice connection failures while RPCs are in progress` – coderatcloud9 Aug 13 '22 at 17:19
  • @coderatcloud9, in the middle of an RPC the connection may not have any writes, as it is just waiting for a reply. But writes are required for TCP to detect broken connections. Enabling keepalive will have gRPC trigger writes occasionally (if necessary) in order to detect a broken connection. Those writes can also be used to inform the network the connection is still in use and should not be killed. You may also find https://github.com/grpc/proposal/blob/master/A8-client-side-keepalive.md helpful. – Eric Anderson Aug 14 '22 at 18:25