clientside load balancing for grpc v1.34.1,nameresolverfactory

yc0p9oo0  于 2021-06-29  发布在  Java
关注(0)|答案(1)|浏览(669)

我将grpcv1.34.1与java一起使用,很难配置客户端负载平衡,因为在这个版本中有些方法是不推荐的。在早期版本中,通过以下方式配置客户端负载平衡非常简单:

final ManagedChannel channel = ManagedChannelBuilder.forTarget(target)
    .nameResolverFactory(new DnsNameResolverProvider())  // this is on by default
    .loadBalancerFactory(RoundRobinLoadBalancerFactory.getInstance())
    .usePlaintext(true)
    .build();

或者这个https://sultanov.dev/blog/grpc-client-side-load-balancing/
但是,对于已弃用nameresolverfactory并删除方法loadbalancerfactory的较新版本,没有任何可用的引用。

NameResolver.Factory nameResolverFactory = new MultiAddressNameResolverFactory(
                new InetSocketAddress("localhost", 50000),
                new InetSocketAddress("localhost", 50001),
                new InetSocketAddress("localhost", 50002)
        );

    channel = ManagedChannelBuilder.forTarget("localhost")
            .nameResolverFactory(nameResolverFactory)
            .defaultLoadBalancingPolicy("round_robin")
            .usePlaintext()
            .build();

客户端负载平衡工作。但是,较新的api已弃用nameresolverfactory。
有没有人能告诉我更新版本的namesolverfactory的替代方案,用于不同服务器(主机和端口)的客户端负载平衡。

yb3bgrhw

yb3bgrhw1#

在经历了grpcjava内部实现之后,我发现更新的版本接受 NameResolver.Factory 以稍微不同的方式。它被封装成 NameResolverProvider 需要注册为默认 NameResolverRegistry . 在较新版本中执行此操作的示例代码共享如下:

NameResolverProvider nameResolverFactory = new MultiAddressNameResolverFactory(
                new InetSocketAddress("localhost", 50000),
                new InetSocketAddress("localhost", 50001),
                new InetSocketAddress("localhost", 50002)
        );

NameResolverRegistry nameResolverRegistry = NameResolverRegistry.getDefaultRegistry();
nameResolverRegistry.register(nameResolverFactory);
channel = ManagedChannelBuilder.forTarget("localhost")
          .defaultLoadBalancingPolicy("round_robin")
          .usePlaintext()
          .build();

public class MultiAddressNameResolverFactory extends NameResolverProvider {
    final List<EquivalentAddressGroup> addresses;

    MultiAddressNameResolverFactory(SocketAddress... addresses) {
        this.addresses = Arrays.stream(addresses)
                .map(EquivalentAddressGroup::new)
                .collect(Collectors.toList());
    }

    public NameResolver newNameResolver(URI notUsedUri, NameResolver.Args args) {
        return new NameResolver() {
            @Override
            public String getServiceAuthority() {
                return "fakeAuthority";
            }
            public void start(Listener2 listener) {
                listener.onResult(ResolutionResult.newBuilder().setAddresses(addresses).setAttributes(Attributes.EMPTY).build());
            }
            public void shutdown() {
            }
        };
    }

    @Override
    public String getDefaultScheme() {
        return "multiaddress";
    }

    @Override
    protected boolean isAvailable() {
        return true;
    }

    @Override
    protected int priority() {
        return 0;
    }
}

默认情况下,namesolver.factory的自定义实现将由连接到服务器的通道获取。基于负载均衡策略 SocketAddress 将被提取以连接到服务器。

相关问题