Java Grpc: 使DNS缓存失效

huangapple go评论65阅读模式
英文:

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()

huangapple
  • 本文由 发表于 2020年9月22日 18:37:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/64007975.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定