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),
)
| Policy | Behavior |
|---|---|
| round_robin | Cycle through READY subchannels |
| pick_first | Default; use first available |
| grpclb DEPRECATED | Look-aside LB |
| xDS | Envoy/Istio control plane MODERN |
2. Configuring Client-Side Load Balancing
| Step | Detail |
|---|---|
| Resolver returns N addrs | e.g. dns:///headless-svc |
| Balancer creates subchannels | One per address |
| Picker selects per RPC | round_robin / least_request |
3. Using DNS Resolver
| Target | Resolution |
|---|---|
dns:///host:port | Resolve once + watch |
| Kubernetes headless svc | Returns all pod IPs |
| DNS refresh | Periodic 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
| Interface | Method |
|---|---|
balancer.Builder | Build, Name |
balancer.Balancer | UpdateClientConnState, UpdateSubConnState |
balancer.Picker | Pick(info) (PickResult, error) |
6. Using Pick First Strategy
| Behavior | Detail |
|---|---|
| Default | Try addresses in order |
| All RPCs to one peer | No spread across replicas |
| Use case | Single 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
| Mechanism | Detail |
|---|---|
| Health watch | Subscribe to gRPC Health service per subchannel |
| Outlier ejection | Temporarily drop failing endpoints |
| xDS | Health from control plane |
9. Using External Load Balancer
| LB | Detail |
|---|---|
| Envoy | L7 with HTTP/2; aware of streams |
| Linkerd | Service mesh |
| L4 (TCP) LB | Risks sticky one-connection problem — use client-side LB |
10. Understanding Subchannel Management
| Concept | Detail |
|---|---|
| Subchannel | Logical connection to one address |
| Owned by balancer | Created/destroyed based on resolver updates |
| State transitions | IDLE → CONNECTING → READY → TRANSIENT_FAILURE |