如何解决grpc v1.34.1 的客户端负载均衡,不推荐使用 nameResolverFactory
我将 grpc v1.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),50002)
);
channel = ManagedChannelBuilder.forTarget("localhost")
.nameResolverFactory(nameResolverFactory)
.defaultLoadBalancingPolicy("round_robin")
.usePlaintext()
.build();
客户端负载平衡有效。但是,较新的 API 已弃用 nameResolverFactory。
任何人都可以指出我在较新版本中使用 nameResolverFactory 的替代方案,以便与不同的服务器(主机和端口)进行客户端负载平衡。
解决方法
经过grpc-java内部实现后,我发现新版本接受NameResolver.Factory
对象的方式略有不同。它被封装到 NameResolverProvider
中,需要注册到默认的 NameResolverRegistry
。下面分享了在较新版本中执行此操作的示例代码:
NameResolverProvider nameResolverFactory = new MultiAddressNameResolverFactory(
new InetSocketAddress("localhost",50000),new InetSocketAddress("localhost",50001),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;
}
}
默认情况下,您对 NameResolver.Factory 的自定义实现将由通道获取以连接到服务器。根据负载平衡策略,将选择一个 SocketAddress
以连接到服务器。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。