Implementing Load Balancing

1. Using Round Robin Policy

Example: Enable round_robin

conn, _ := grpc.NewClient("dns:///users.internal:50051",
    grpc.WithDefaultServiceConfig(`{"loadBalancingConfig":[{"round_robin":{}}]}`),
    grpc.WithTransportCredentials(creds),
)
PolicyBehavior
round_robinCycle through READY subchannels
pick_firstDefault; use first available
grpclb DEPRECATEDLook-aside LB
xDSEnvoy/Istio control plane MODERN

2. Configuring Client-Side Load Balancing

StepDetail
Resolver returns N addrse.g. dns:///headless-svc
Balancer creates subchannelsOne per address
Picker selects per RPCround_robin / least_request

3. Using DNS Resolver

TargetResolution
dns:///host:portResolve once + watch
Kubernetes headless svcReturns all pod IPs
DNS refreshPeriodic re-resolve (default 30 min); tune via env

4. Implementing Custom Resolver

Example: Custom resolver skeleton

type myBuilder struct{}
func (myBuilder) Scheme() string { return "mysvc" }
func (myBuilder) Build(t resolver.Target, cc resolver.ClientConn, _ resolver.BuildOptions) (resolver.Resolver, error) {
    r := &myResolver{cc: cc}
    go r.watch(t.Endpoint())
    return r, nil
}
func init() { resolver.Register(myBuilder{}) }
// dial: grpc.NewClient("mysvc:///users", ...)

5. Registering Custom Balancer

InterfaceMethod
balancer.BuilderBuild, Name
balancer.BalancerUpdateClientConnState, UpdateSubConnState
balancer.PickerPick(info) (PickResult, error)

6. Using Pick First Strategy

BehaviorDetail
DefaultTry addresses in order
All RPCs to one peerNo spread across replicas
Use caseSingle instance / sticky connection

7. Configuring Service Config JSON

Example: Service config

{
  "loadBalancingConfig": [{ "round_robin": {} }],
  "methodConfig": [{
    "name": [{ "service": "user.v1.UserService" }],
    "timeout": "2s",
    "retryPolicy": {
      "maxAttempts": 4,
      "initialBackoff": "0.1s",
      "maxBackoff": "1s",
      "backoffMultiplier": 2,
      "retryableStatusCodes": ["UNAVAILABLE"]
    }
  }]
}

8. Implementing Health-Based Balancing

MechanismDetail
Health watchSubscribe to gRPC Health service per subchannel
Outlier ejectionTemporarily drop failing endpoints
xDSHealth from control plane

9. Using External Load Balancer

LBDetail
EnvoyL7 with HTTP/2; aware of streams
LinkerdService mesh
L4 (TCP) LBRisks sticky one-connection problem — use client-side LB

10. Understanding Subchannel Management

ConceptDetail
SubchannelLogical connection to one address
Owned by balancerCreated/destroyed based on resolver updates
State transitionsIDLE → CONNECTING → READY → TRANSIENT_FAILURE