英文:
Java Grpc: invalidate dns cache
问题
我有一个指向解析为2个IP地址的URL的gRPC客户端。
问题是,当一个服务器节点宕机然后恢复时,gRPC客户端不会选择它,而是所有负载都发送到一个单独的节点。
我尝试了更改networkaddress.cache.ttl
属性的建议,但没有帮助。
我的代码(Scala版)
java.security.Security.setProperty("networkaddress.cache.ttl", "30")
System.setProperty("networkaddress.cache.ttl", "30")
val channel = NettyChannelBuilder.forAddress(host, port).nameResolverFactory(
new DnsNameResolverProvider).usePlaintext().build
val client = MyServiceGrpc.newStub(channel)
gRPC版本:1.32.1
英文:
I have a grpc client pointing to a url which resolves to 2 IP addresses.
The problem is when one server node goes down and then gets back, it's not picked by the grpc client and all the load goes to a single node.
I tried recommendation to change networkaddress.cache.ttl
propetty but it didn't help.
My code (in Scala)
java.security.Security.setProperty("networkaddress.cache.ttl", "30")
System.setProperty("networkaddress.cache.ttl", "30")
val channel = NettyChannelBuilder.forAddress(host, port).nameResolverFactory(
new DnsNameResolverProvider).usePlaintext().build
val client = MyServiceGrpc.newStub(channel)
grpc version: 1.32.1
答案1
得分: 2
假设DNS每次都返回两个IP地址(可能会重新排序),那么问题不在DNS缓存上。问题在于gRPC已经建立了一个工作连接,所以它不会选择重新连接,也不会执行DNS查询。
你应该使用 MAX_CONNECTION_AGE
来配置你的服务器,强制客户端偶尔重新连接以重新平衡负载。当客户端与服务器断开连接时,它们会触发新的DNS解析,因此这也可以用于查找新的地址(尽管重新连接不会等待DNS解析完成)。
在Java中,通过 NettyServerBuilder.maxConnectionAge()
可以设置 MAX_CONNECTION_AGE
:
NettyServerBuilder.forPort(yourPort)
.maxConnectionAge(30, TimeUnit.MINUTES)
....
你应该选择尽可能大的时间间隔。例如设置为30分钟,这样每个客户端将每30分钟重新平衡一次。因此,在服务器重新启动后的前15分钟,该服务器将承担大约四分之一的负载,在30分钟后,它将承担大约一半的负载。
英文:
Assuming that DNS returns both IPs all the time (probably shuffled), then the problem is not the DNS cache. The problem is that gRPC has a working connection and so won't choose to reconnect and won't perform DNS queries.
You should configure your server with MAX_CONNECTION_AGE
to force clients to reconnect occasionally to rebalance the load. When clients are disconnected from the server they trigger a new DNS resolution, so this can also be used to find new addresses (although reconnections do not wait for the DNS resolution to complete).
In Java, MAX_CONNECTION_AGE
is available via NettyServerBuilder.maxConnectionAge()
:
NettyServerBuilder.forPort(yourPort)
.maxConnectionAge(30, TimeUnit.MINUTES)
....
You want to use as large of age as you can accept. With a time like 30 minutes, then each client will rebalance every 30 minutes. So after 15 minutes of the server restarting that server would have ¼ of the load and after 30 minutes it would have roughly ½.
答案2
得分: 1
似乎配置负载均衡策略就可以完成任务:
NettyChannelBuilder.forAddress(host, port).defaultLoadBalancingPolicy("round_robin").usePlaintext().build()
英文:
Seems that configuring load-balancing policy does the job:
NettyChannelBuilder.forAddress(host, port).defaultLoadBalancingPolicy("round_robin").usePlaintext().build()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论