31
31
*
32
32
*/
33
33
34
- // Package grpclb implements the load balancing protocol defined at
35
- // https://github.com/grpc/grpc/blob/master/doc/load-balancing.md.
36
- // The implementation is currently EXPERIMENTAL.
37
- package grpclb
34
+ package grpc
38
35
39
36
import (
40
37
"errors"
@@ -45,14 +42,50 @@ import (
45
42
"time"
46
43
47
44
"golang.org/x/net/context"
48
- "google.golang.org/grpc"
49
45
"google.golang.org/grpc/codes"
50
46
lbpb "google.golang.org/grpc/grpclb/grpc_lb_v1"
51
47
"google.golang.org/grpc/grpclog"
52
48
"google.golang.org/grpc/metadata"
53
49
"google.golang.org/grpc/naming"
54
50
)
55
51
52
+ // Client API for LoadBalancer service.
53
+ // Mostly copied from generated pb.go file.
54
+ // To avoid circular dependency.
55
+ type loadBalancerClient struct {
56
+ cc * ClientConn
57
+ }
58
+
59
+ func (c * loadBalancerClient ) BalanceLoad (ctx context.Context , opts ... CallOption ) (* balanceLoadClientStream , error ) {
60
+ desc := & StreamDesc {
61
+ StreamName : "BalanceLoad" ,
62
+ ServerStreams : true ,
63
+ ClientStreams : true ,
64
+ }
65
+ stream , err := NewClientStream (ctx , desc , c .cc , "/grpc.lb.v1.LoadBalancer/BalanceLoad" , opts ... )
66
+ if err != nil {
67
+ return nil , err
68
+ }
69
+ x := & balanceLoadClientStream {stream }
70
+ return x , nil
71
+ }
72
+
73
+ type balanceLoadClientStream struct {
74
+ ClientStream
75
+ }
76
+
77
+ func (x * balanceLoadClientStream ) Send (m * lbpb.LoadBalanceRequest ) error {
78
+ return x .ClientStream .SendMsg (m )
79
+ }
80
+
81
+ func (x * balanceLoadClientStream ) Recv () (* lbpb.LoadBalanceResponse , error ) {
82
+ m := new (lbpb.LoadBalanceResponse )
83
+ if err := x .ClientStream .RecvMsg (m ); err != nil {
84
+ return nil , err
85
+ }
86
+ return m , nil
87
+ }
88
+
56
89
// AddressType indicates the address type returned by name resolution.
57
90
type AddressType uint8
58
91
@@ -63,18 +96,18 @@ const (
63
96
GRPCLB
64
97
)
65
98
66
- // Metadata contains the information the name resolution for grpclb should provide. The
99
+ // AddrMetadataGRPCLB contains the information the name resolution for grpclb should provide. The
67
100
// name resolver used by grpclb balancer is required to provide this type of metadata in
68
101
// its address updates.
69
- type Metadata struct {
102
+ type AddrMetadataGRPCLB struct {
70
103
// AddrType is the type of server (grpc load balancer or backend).
71
104
AddrType AddressType
72
105
// ServerName is the name of the grpc load balancer. Used for authentication.
73
106
ServerName string
74
107
}
75
108
76
- // Balancer creates a grpclb load balancer.
77
- func Balancer (r naming.Resolver ) grpc. Balancer {
109
+ // NewGRPCLBBalancer creates a grpclb load balancer.
110
+ func NewGRPCLBBalancer (r naming.Resolver ) Balancer {
78
111
return & balancer {
79
112
r : r ,
80
113
}
@@ -86,13 +119,16 @@ type remoteBalancerInfo struct {
86
119
name string
87
120
}
88
121
89
- // addrInfo consists of the information of a backend server.
90
- type addrInfo struct {
91
- addr grpc. Address
122
+ // grpclbAddrInfo consists of the information of a backend server.
123
+ type grpclbAddrInfo struct {
124
+ addr Address
92
125
connected bool
93
- // dropRequest indicates whether a particular RPC which chooses this address
94
- // should be dropped.
95
- dropRequest bool
126
+ // dropForRateLimiting indicates whether this particular request should be
127
+ // dropped by the client for rate limiting.
128
+ dropForRateLimiting bool
129
+ // dropForLoadBalancing indicates whether this particular request should be
130
+ // dropped by the client for load balancing.
131
+ dropForLoadBalancing bool
96
132
}
97
133
98
134
type balancer struct {
@@ -101,9 +137,9 @@ type balancer struct {
101
137
mu sync.Mutex
102
138
seq int // a sequence number to make sure addrCh does not get stale addresses.
103
139
w naming.Watcher
104
- addrCh chan []grpc. Address
140
+ addrCh chan []Address
105
141
rbs []remoteBalancerInfo
106
- addrs []* addrInfo
142
+ addrs []* grpclbAddrInfo
107
143
next int
108
144
waitCh chan struct {}
109
145
done bool
@@ -119,7 +155,7 @@ func (b *balancer) watchAddrUpdates(w naming.Watcher, ch chan []remoteBalancerIn
119
155
b .mu .Lock ()
120
156
defer b .mu .Unlock ()
121
157
if b .done {
122
- return grpc . ErrClientConnClosing
158
+ return ErrClientConnClosing
123
159
}
124
160
for _ , update := range updates {
125
161
switch update .Op {
@@ -135,7 +171,7 @@ func (b *balancer) watchAddrUpdates(w naming.Watcher, ch chan []remoteBalancerIn
135
171
if exist {
136
172
continue
137
173
}
138
- md , ok := update .Metadata .(* Metadata )
174
+ md , ok := update .Metadata .(* AddrMetadataGRPCLB )
139
175
if ! ok {
140
176
// TODO: Revisit the handling here and may introduce some fallback mechanism.
141
177
grpclog .Printf ("The name resolution contains unexpected metadata %v" , update .Metadata )
@@ -206,18 +242,19 @@ func (b *balancer) processServerList(l *lbpb.ServerList, seq int) {
206
242
servers := l .GetServers ()
207
243
expiration := convertDuration (l .GetExpirationInterval ())
208
244
var (
209
- sl []* addrInfo
210
- addrs []grpc. Address
245
+ sl []* grpclbAddrInfo
246
+ addrs []Address
211
247
)
212
248
for _ , s := range servers {
213
249
md := metadata .Pairs ("lb-token" , s .LoadBalanceToken )
214
- addr := grpc. Address {
250
+ addr := Address {
215
251
Addr : fmt .Sprintf ("%s:%d" , net .IP (s .IpAddress ), s .Port ),
216
252
Metadata : & md ,
217
253
}
218
- sl = append (sl , & addrInfo {
219
- addr : addr ,
220
- dropRequest : s .DropRequest ,
254
+ sl = append (sl , & grpclbAddrInfo {
255
+ addr : addr ,
256
+ dropForRateLimiting : s .DropForRateLimiting ,
257
+ dropForLoadBalancing : s .DropForLoadBalancing ,
221
258
})
222
259
addrs = append (addrs , addr )
223
260
}
@@ -244,7 +281,7 @@ func (b *balancer) processServerList(l *lbpb.ServerList, seq int) {
244
281
return
245
282
}
246
283
247
- func (b * balancer ) callRemoteBalancer (lbc lbpb. LoadBalancerClient , seq int ) (retry bool ) {
284
+ func (b * balancer ) callRemoteBalancer (lbc * loadBalancerClient , seq int ) (retry bool ) {
248
285
ctx , cancel := context .WithCancel (context .Background ())
249
286
defer cancel ()
250
287
stream , err := lbc .BalanceLoad (ctx )
@@ -306,7 +343,7 @@ func (b *balancer) callRemoteBalancer(lbc lbpb.LoadBalancerClient, seq int) (ret
306
343
return true
307
344
}
308
345
309
- func (b * balancer ) Start (target string , config grpc. BalancerConfig ) error {
346
+ func (b * balancer ) Start (target string , config BalancerConfig ) error {
310
347
b .rand = rand .New (rand .NewSource (time .Now ().Unix ()))
311
348
// TODO: Fall back to the basic direct connection if there is no name resolver.
312
349
if b .r == nil {
@@ -316,9 +353,9 @@ func (b *balancer) Start(target string, config grpc.BalancerConfig) error {
316
353
b .mu .Lock ()
317
354
if b .done {
318
355
b .mu .Unlock ()
319
- return grpc . ErrClientConnClosing
356
+ return ErrClientConnClosing
320
357
}
321
- b .addrCh = make (chan []grpc. Address )
358
+ b .addrCh = make (chan []Address )
322
359
w , err := b .r .Resolve (target )
323
360
if err != nil {
324
361
b .mu .Unlock ()
@@ -340,7 +377,7 @@ func (b *balancer) Start(target string, config grpc.BalancerConfig) error {
340
377
// Spawn a goroutine to talk to the remote load balancer.
341
378
go func () {
342
379
var (
343
- cc * grpc. ClientConn
380
+ cc * ClientConn
344
381
// ccError is closed when there is an error in the current cc.
345
382
// A new rb should be picked from rbs and connected.
346
383
ccError chan struct {}
@@ -419,15 +456,15 @@ func (b *balancer) Start(target string, config grpc.BalancerConfig) error {
419
456
creds := config .DialCreds
420
457
ccError = make (chan struct {})
421
458
if creds == nil {
422
- cc , err = grpc . Dial (rb .addr , grpc . WithInsecure ())
459
+ cc , err = Dial (rb .addr , WithInsecure ())
423
460
} else {
424
461
if rb .name != "" {
425
462
if err := creds .OverrideServerName (rb .name ); err != nil {
426
463
grpclog .Printf ("Failed to override the server name in the credentials: %v" , err )
427
464
continue
428
465
}
429
466
}
430
- cc , err = grpc . Dial (rb .addr , grpc . WithTransportCredentials (creds ))
467
+ cc , err = Dial (rb .addr , WithTransportCredentials (creds ))
431
468
}
432
469
if err != nil {
433
470
grpclog .Printf ("Failed to setup a connection to the remote balancer %v: %v" , rb .addr , err )
@@ -439,8 +476,8 @@ func (b *balancer) Start(target string, config grpc.BalancerConfig) error {
439
476
seq := b .seq
440
477
b .next = 0
441
478
b .mu .Unlock ()
442
- go func (cc * grpc. ClientConn , ccError chan struct {}) {
443
- lbc := lbpb . NewLoadBalancerClient ( cc )
479
+ go func (cc * ClientConn , ccError chan struct {}) {
480
+ lbc := & loadBalancerClient { cc }
444
481
b .callRemoteBalancer (lbc , seq )
445
482
cc .Close ()
446
483
select {
@@ -454,7 +491,7 @@ func (b *balancer) Start(target string, config grpc.BalancerConfig) error {
454
491
return nil
455
492
}
456
493
457
- func (b * balancer ) down (addr grpc. Address , err error ) {
494
+ func (b * balancer ) down (addr Address , err error ) {
458
495
b .mu .Lock ()
459
496
defer b .mu .Unlock ()
460
497
for _ , a := range b .addrs {
@@ -465,7 +502,7 @@ func (b *balancer) down(addr grpc.Address, err error) {
465
502
}
466
503
}
467
504
468
- func (b * balancer ) Up (addr grpc. Address ) func (error ) {
505
+ func (b * balancer ) Up (addr Address ) func (error ) {
469
506
b .mu .Lock ()
470
507
defer b .mu .Unlock ()
471
508
if b .done {
@@ -479,7 +516,7 @@ func (b *balancer) Up(addr grpc.Address) func(error) {
479
516
}
480
517
a .connected = true
481
518
}
482
- if a .connected && ! a .dropRequest {
519
+ if a .connected && ! a .dropForRateLimiting && ! a . dropForLoadBalancing {
483
520
cnt ++
484
521
}
485
522
}
@@ -493,12 +530,12 @@ func (b *balancer) Up(addr grpc.Address) func(error) {
493
530
}
494
531
}
495
532
496
- func (b * balancer ) Get (ctx context.Context , opts grpc. BalancerGetOptions ) (addr grpc. Address , put func (), err error ) {
533
+ func (b * balancer ) Get (ctx context.Context , opts BalancerGetOptions ) (addr Address , put func (), err error ) {
497
534
var ch chan struct {}
498
535
b .mu .Lock ()
499
536
if b .done {
500
537
b .mu .Unlock ()
501
- err = grpc . ErrClientConnClosing
538
+ err = ErrClientConnClosing
502
539
return
503
540
}
504
541
@@ -511,7 +548,7 @@ func (b *balancer) Get(ctx context.Context, opts grpc.BalancerGetOptions) (addr
511
548
a := b .addrs [next ]
512
549
next = (next + 1 ) % len (b .addrs )
513
550
if a .connected {
514
- if ! a .dropRequest {
551
+ if ! a .dropForRateLimiting && ! a . dropForLoadBalancing {
515
552
addr = a .addr
516
553
b .next = next
517
554
b .mu .Unlock ()
@@ -520,7 +557,7 @@ func (b *balancer) Get(ctx context.Context, opts grpc.BalancerGetOptions) (addr
520
557
if ! opts .BlockingWait {
521
558
b .next = next
522
559
b .mu .Unlock ()
523
- err = grpc . Errorf (codes .Unavailable , "%s drops requests" , a .addr .Addr )
560
+ err = Errorf (codes .Unavailable , "%s drops requests" , a .addr .Addr )
524
561
return
525
562
}
526
563
}
@@ -533,7 +570,7 @@ func (b *balancer) Get(ctx context.Context, opts grpc.BalancerGetOptions) (addr
533
570
if ! opts .BlockingWait {
534
571
if len (b .addrs ) == 0 {
535
572
b .mu .Unlock ()
536
- err = grpc . Errorf (codes .Unavailable , "there is no address available" )
573
+ err = Errorf (codes .Unavailable , "there is no address available" )
537
574
return
538
575
}
539
576
// Returns the next addr on b.addrs for a failfast RPC.
@@ -559,7 +596,7 @@ func (b *balancer) Get(ctx context.Context, opts grpc.BalancerGetOptions) (addr
559
596
b .mu .Lock ()
560
597
if b .done {
561
598
b .mu .Unlock ()
562
- err = grpc . ErrClientConnClosing
599
+ err = ErrClientConnClosing
563
600
return
564
601
}
565
602
@@ -572,7 +609,7 @@ func (b *balancer) Get(ctx context.Context, opts grpc.BalancerGetOptions) (addr
572
609
a := b .addrs [next ]
573
610
next = (next + 1 ) % len (b .addrs )
574
611
if a .connected {
575
- if ! a .dropRequest {
612
+ if ! a .dropForRateLimiting && ! a . dropForLoadBalancing {
576
613
addr = a .addr
577
614
b .next = next
578
615
b .mu .Unlock ()
@@ -581,7 +618,7 @@ func (b *balancer) Get(ctx context.Context, opts grpc.BalancerGetOptions) (addr
581
618
if ! opts .BlockingWait {
582
619
b .next = next
583
620
b .mu .Unlock ()
584
- err = grpc . Errorf (codes .Unavailable , "drop requests for the addreess %s" , a .addr .Addr )
621
+ err = Errorf (codes .Unavailable , "drop requests for the addreess %s" , a .addr .Addr )
585
622
return
586
623
}
587
624
}
@@ -603,7 +640,7 @@ func (b *balancer) Get(ctx context.Context, opts grpc.BalancerGetOptions) (addr
603
640
}
604
641
}
605
642
606
- func (b * balancer ) Notify () <- chan []grpc. Address {
643
+ func (b * balancer ) Notify () <- chan []Address {
607
644
return b .addrCh
608
645
}
609
646
0 commit comments