Top Description Inners Fields Constructors Methods
io.grpc

public abstract Class LoadBalancer

extends Object
Class Inheritance
Annotations
@ExperimentalApi:https://github.com/grpc/grpc-java/issues/1771
@NotThreadSafe
Static Imports
com.google.common.base.Preconditions.checkArgument, .Preconditions.checkNotNull

A pluggable component that receives resolved addresses from NameResolver and provides the channel a usable subchannel when asked.

Overview

A LoadBalancer typically implements three interfaces:

  1. LoadBalancer is the main interface. All methods on it are invoked sequentially in the same synchronization context (see next section) as returned by io.grpc.LoadBalancer.Helper#getSynchronizationContext. It receives the results from the NameResolver, updates of subchannels' connectivity states, and the channel's request for the LoadBalancer to shutdown.
  2. SubchannelPicker does the actual load-balancing work. It selects a Subchannel for each new RPC.
  3. Factory creates a new LoadBalancer instance.

Helper is implemented by gRPC library and provided to Factory. It provides functionalities that a LoadBalancer implementation would typically need.

The Synchronization Context

All methods on the LoadBalancer interface are called from a Synchronization Context, meaning they are serialized, thus the balancer implementation doesn't need to worry about synchronization among them. io.grpc.LoadBalancer.Helper#getSynchronizationContext allows implementations to schedule tasks to be run in the same Synchronization Context, with or without a delay, thus those tasks don't need to worry about synchronizing with the balancer methods.

However, the actual running thread may be the network thread, thus the following rules must be followed to prevent blocking or even dead-locking in a network:

  1. Never block in the Synchronization Context. The callback methods must return quickly. Examples or work that must be avoided: CPU-intensive calculation, waiting on synchronization primitives, blocking I/O, blocking RPCs, etc.
  2. Avoid calling into other components with lock held. The Synchronization Context may be under a lock, e.g., the transport lock of OkHttp. If your LoadBalancer holds a lock in a callback method (e.g., handleResolvedAddresses()) while calling into another method that also involves locks, be cautious of deadlock. Generally you wouldn't need any locking in the LoadBalancer if you follow the canonical implementation pattern below.

The canonical implementation pattern

A LoadBalancer keeps states like the latest addresses from NameResolver, the Subchannel(s) and their latest connectivity states. These states are mutated within the Synchronization Context,

A typical SubchannelPicker holds a snapshot of these states. It may have its own states, e.g., a picker from a round-robin load-balancer may keep a pointer to the next Subchannel, which are typically mutated by multiple threads. The picker should only mutate its own state, and should not mutate or re-acquire the states of the LoadBalancer. This way the picker only needs to synchronize its own states, which is typically trivial to implement.

When the LoadBalancer states changes, e.g., Subchannels has become or stopped being READY, and we want subsequent RPCs to use the latest list of READY Subchannels, LoadBalancer would create a new picker, which holds a snapshot of the latest Subchannel list. Refer to the javadoc of onSubchannelState() how to do this properly.

No synchronization should be necessary between LoadBalancer and its pickers if you follow the pattern above. It may be possible to implement in a different way, but that would usually result in more complicated threading.

Since
1.2.0

Nested and Inner Type Summary

Modifier and TypeClass and Description
public static class
public static class
LoadBalancer.ErrorPicker

Deprecated Use new FixedResultPicker(PickResult.withError(error)) instead.
A picker that always returns an erring pick.
public abstract static class
LoadBalancer.Factory

Factory to create LoadBalancer instance.

public static class
LoadBalancer.FixedResultPicker

A picker that always returns the same result.

public abstract static class
LoadBalancer.Helper

Provides essentials for LoadBalancer implementations.

public static class
LoadBalancer.PickResult

A balancing decision made by SubchannelPicker for an RPC.

public abstract static class
public static class
LoadBalancer.ResolvedAddresses

Represents a combination of the resolved server address, associated attributes and a load balancing policy config.

public abstract static class
LoadBalancer.Subchannel

A logical connection to a server, or a group of equivalent servers represented by an EquivalentAddressGroup.

public abstract static class
LoadBalancer.SubchannelPicker

The main balancing logic.

public static interface
LoadBalancer.SubchannelStateListener

Receives state changes for one Subchannel.

Field Summary

Modifier and TypeField and Description
public static final Attributes.Key<Map<String, ?>>
public static final LoadBalancer.SubchannelPicker
private int

Constructor Summary

AccessConstructor and Description
public

Method Summary

Modifier and TypeMethod and Description
public Status

Returns:

true if the resolved addresses were accepted. false if rejected.
acceptResolvedAddresses
(LoadBalancer.ResolvedAddresses
the resolved server addresses, attributes, and config.
resolvedAddresses
)

Accepts newly resolved addresses from the name resolution system.

public boolean
canHandleEmptyAddressListFromNameResolution()

Whether this LoadBalancer can handle empty address group list to be passed to handleResolvedAddresses(ResolvedAddresses).

public abstract void
handleNameResolutionError(Status
a non-OK status
error
)

Handles an error from the name resolution system.

public void
handleResolvedAddresses(LoadBalancer.ResolvedAddresses
the resolved server addresses, attributes, and config.
resolvedAddresses
)

Handles newly resolved server groups and metadata attributes from name resolution system.

public void
handleSubchannelState(LoadBalancer.Subchannel
the involved Subchannel
subchannel
,
ConnectivityStateInfo
the new state
stateInfo
)

Deprecated This method will be removed.
Handles a state change on a Subchannel.
public void
requestConnection()

The channel asks the LoadBalancer to establish connections now (if applicable) so that the upcoming RPC may then just pick a ready connection without waiting for connections.

public abstract void
shutdown()

The channel asks the load-balancer to shutdown.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait