Table of Contents1. Foreword 2. Load Balance 3. RELATED LINKS
1 Preface
The previous article analyzed a grpc Call of the general calling process, followed the source went through, but Grpc some features did not analyze, this blog is the main analysis of load balancing this feature. Load balancing allows you to use the Grpc calling method to connect to a different server. At startup, Grpc client establishes a connection to all servers and then uses a polling algorithm to get a different server. 2 Load Balancing
Load balancing is implemented at the client, through the initialization of a GRPC client into a load balancer, the default is through the polling algorithm every time the call to switch to the server, because it is done on the client, so can only let the server split the pressure, can not real-time according to the state of the server to carry out load balancing. For example, at some point, all GRPC clients turn to the same server (here is just an example).
In the Dialcontext function of Clientconn.go Go func() {varAddrs []addressifCc.dopts.balancer = = Nil {//Connect to target directly if Balancer is nil. If the load balancer is not set, direct connection Addrs = Append (Addrs, address{addr:target})}Else{varCredsclone credentials. TransportcredentialsifCreds!= Nil {credsclone = creds.Clone()} config: = balancerconfig{dialcreds:credsclone,}//Start a load balancer, the start function initiates a watch listener address change, and notify Returns a channel with the latest address information after each server address change.ifERR: = Cc.dopts.balancer.Start(target, config); Err!= Nil {WAITC <-err returnCH: = Cc.dopts.balancer.Notify()ifch = = Nil {//There is no Name resolver installed. Addrs = Append (Addrs, address{addr:target})}Else{Addrs, OK = <-chif!ok | | Len (Addrs) = = 0 {WAITC <-errnoaddr returnConnect to each address, because this is the client startup, so all addresses need to be operated on. for_, A: =RangeAddrs {ifERR: = cc.Resetaddrconn(A, false, nil); Err!= Nil {WAITC <-err return} Close (WAITC)} () .....//Omit some code from.ifOK {//Here opens a listening goroutine, mainly listens to the server address change and establishes the connection to the new address, closes the connection to the old address GoCc.Lbwatcher()
}
The above code basically shows how a load balancer is used, and look at the specific structure of load balancing:
type Interface {
//start a load balancing, the inside will start a name server Watcher, constantly listening to the change of address
start(target string, config Balancerconfig) error Up
func(Error))
Get the next connection to the address get
func(), err Error)
//The updated address from the server, this address is updated after all the addresses
Notify () <-chan []address
//Off load balancer close
() error
}
The load balancer has a default implementation in Balancer.go, using the polling algorithm. This implementation contains a name Server service, we can implement a name server interface, and then encapsulated into this load balancer, so that we do not need to implement the entire load balancer. The interface for the name server is as follows:
typeUpdatestruct{//OP indicates the operation of the update. Op Operation//ADDR is the updated address.
It is empty string if there no address update. ADDR string//Metadata is the updated Metadata.
It is nil if there no metadata update.
Metadata is isn't required for a custom naming implementation. MetadataInterface{}}//Resolver creates a watcher for a target to track its resolution changes.typeResolverInterface{///Resolve creates a watcher for target. By a name to get a watcher, listening to server address changes.Resolve(Target string)
(Watcher, error)} Watcher watches for the updates on the specified target.typeWatcherInterface{//Next blocks until an update or error happens. It may return one or more//updates. The "the" should get the "full set of the" results.
It should//return a error if and only if watcher cannot recover. Get the next updated addressNext() ([]*update, error)//close closes the watcher. Close()
}
The full picture of the load balancer is probably that, and there are some details I don't see, and I don't want to go into these details too early. So the load balance is here. 3 RELATED LINKS Http://www.grpc.io/docs/guides/auth.html#overview validation documents
Https://guidao.github.io/grpc_balancer.html