【问题标题】:GRPC loadbalancer exampleGRPC 负载均衡器示例
【发布时间】:2017-07-29 15:30:05
【问题描述】:
【问题讨论】:
标签:
protocol-buffers
load-balancing
rpc
grpc
【解决方案1】:
gRPC LoadBalancer 与 NameResolver 一起使用。 NameResolver 向 LoadBalancer 发出地址,LoadBalancer 决定为每个请求建立连接 (Subchannels) 和 picking a Subchannel。
NameResolver 和/或 LoadBalancer 可以是 set to ManagedChannelBuilder 用于通道。
虽然有接口,但现有的实现并不多,而是基本的 DnsNameResolver 和 RoundRobinLoadBalancer。 PickFirstBalancerFactory 是默认的“LoadBalancer”,实际上不做平衡。
如果您的地址在 DNS 中具有多个地址,则在使用 RoundRobinLoadBalancer 时会观察到循环行为。但是,我猜您想从一些服务发现系统(例如 ZooKeeper)中获取地址。您将需要为此实现 NameResolver。如果您熟悉您选择的发现系统,那应该不难。
【解决方案2】:
我刚刚从 Kidong Lee 的 github 存储库中找到了一个 Java 版本示例:
https://github.com/mykidong/grpc-java-load-balancer-using-consul/blob/master/src/test/java/io/shunters/grpc/component/grpc/HelloWorldClientWithNameResolver.java
/**
* Consul NameResolver Usage.
*
*
* @param serviceName consul service name.
* @param consulHost consul agent host.
* @param consulPort consul agent port.
* @param ignoreConsul if true, consul is not used. instead, the static node list will be used.
* @param hostPorts the static node list, for instance, Arrays.asList("host1:port1", "host2:port2")
*/
public HelloWorldClientWithNameResolver(String serviceName,
String consulHost,
int consulPort,
boolean ignoreConsul,
List<String> hostPorts) {
String consulAddr = "consul://" + consulHost + ":" + consulPort;
int pauseInSeconds = 5;
channel = ManagedChannelBuilder
.forTarget(consulAddr)
.loadBalancerFactory(RoundRobinLoadBalancerFactory.getInstance())
.nameResolverFactory(new ConsulNameResolver.ConsulNameResolverProvider(serviceName, pauseInSeconds, ignoreConsul, hostPorts))
.usePlaintext(true)
.build();
blockingStub = GreeterGrpc.newBlockingStub(channel);
}
您可以从这个 repo 中找到更多示例。
【解决方案3】:
我们刚刚发布了一个非常简单的示例,可以在这里找到:https://github.com/cloudtrust/lbclient/blob/master/grpc/staticResolver.go
package grpc
import (
"google.golang.org/grpc/naming"
)
type staticResolver struct{
updates []*naming.Update
}
type staticWatcher struct {
updates chan []*naming.Update
}
func NewStaticResolver(addr []string) naming.Resolver {
var ups []*naming.Update
for _,a := range addr {
ups = append(ups, &naming.Update{naming.Add, a, ""})
}
return &staticResolver{ups}
}
func (w *staticWatcher) Next() ([]*naming.Update, error) {
return <-w.updates, nil
}
func (w *staticWatcher) Close() {
close(w.updates)
}
func (r *staticResolver) Resolve(target string) (naming.Watcher, error) {
var ch chan []*naming.Update = make(chan []*naming.Update, 1)
ch <- r.updates
return &staticWatcher{ch}, nil
}
我们希望这对您有所帮助,如果您需要什么,请随时询问。