GRPC负载均衡器示例

时间:2017-03-08 21:06:11

标签: protocol-buffers load-balancing rpc grpc

我正在尝试使用GRPC / Java构建具有负载平衡的服务器集管理机制。

通过查看API文档,有以下类: LoadBalancer,RoundRobinLoadBalancerFactory等

通过查看名称,似乎他们应该做我想做的事情。 但是,我找不到使用这些类的任何代码示例,即使我用Google搜索非常努力。

另一方面,我发现了一些像这样的Finagle / Thrift示例:https://github.com/benjumanji/finagle-serverset-example

我想知道是否有人可以分享一些有效的GRPC示例?谢谢!

3 个答案:

答案 0 :(得分:1)

gRPC LoadBalancer适用于NameResolver。 NameResolver向LoadBalancer发送地址,LoadBalancer决定是否为每个请求建立连接(Subchannels)和picking a Subchannel

NameResolver和/或LoadBalancer可以set to ManagedChannelBuilder用于频道。

虽然接口在那里,但是没有很多库存实现,而不是基本的DnsNameResolver和RoundRobinLoadBalancer。 PickFirstBalancerFactory是默认的" LoadBalancer"实际上并没有做到平衡。

如果您的地址在DNS中有多个地址,则在使用RoundRobinLoadBalancer时您将观察到循环行为。但是,我想你想从一些服务发现系统中获取地址,例如ZooKeeper。您需要为此实现NameResolver。如果您熟悉您选择的发现系统,那就不难了。

答案 1 :(得分:0)

我们在这里发布了一个非常简单的例子: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
}

我们希望这可以帮助您,随时询问您是否需要任何东西。

答案 2 :(得分:0)

我刚刚从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);
}

您可以从此存储库中找到更多示例。