grpc-go 解析 dns:/// 目标时,到底查了什么、什么时候重新查、TTL 起不起作用?域名不存在时调用会怎样?这篇在本机起了一个小 DNS 服务器,把每个查询都记下来。
passthrough:///svc.test:7000 → DNS 查询:0 个查询;dialer 收到的地址:svc.test:7000;失败 code=Unavailable message="connection error: desc = \"transport: Error while dialing: 没有这个假地址的后端:svc.test:7000\"" dns://<本机DNS>/svc.test:7000 → DNS 查询:A 1、AAAA 1、TXT 2;dialer 收到的地址:10.9.0.1:7000;成功,后端 0 dns://<本机DNS>/svc.test → DNS 查询:A 1、AAAA 1、TXT 2;dialer 收到的地址:10.9.0.1:443;成功,后端 0 dns:///10.9.0.1:7000 → DNS 查询:0 个查询;dialer 收到的地址:10.9.0.1:7000;成功,后端 0 svc.test:7000 → DNS 查询:0 个查询;dialer 收到的地址:;失败 code=Unavailable message="name resolver error: produced zero addresses"
passthrough 不解析,把名字原样交给 dialer;dns 解析成 IP,一个域名下的所有 A 记录都成为地址。没有 scheme 的 target,NewClient 当作 dns。
90 次调用各后端收到 [30 30 30];dialer 收到的地址:10.9.0.1:7000 10.9.0.3:7000 10.9.0.2:7000 DNS 服务器收到的查询:A 1、AAAA 1、TXT 2 查询的名字:TypeAAAA svc.test.;TypeA svc.test.;TypeTXT _grpc_config.svc.test.;TypeTXT _grpc_config.svc.test.lan.
启动时对域名发 A、AAAA 查询,另外还会查 _grpc_config.<域名> 的 TXT(服务配置)。不写端口时默认 443。
默认环境 30 次调用各后端收到 [9 10 11];DNS 查询:A 1、AAAA 1、TXT 1 GRPC_ENABLE_TXT_SERVICE_CONFIG=false 30 次调用各后端收到 [30 0 0];DNS 查询:A 1、AAAA 1
在这个版本里默认读取并应用 DNS TXT 里的服务配置(如负载均衡策略)。不想让 DNS 改变客户端行为,用 GRPC_ENABLE_TXT_SERVICE_CONFIG=false 关掉。
DNS 的 A 查询时刻(秒,相对 t0):[30.0] 0–2 秒(记录 [1 2 3]):后端集合 [1 2 3],失败 0 次 2–6 秒(记录已换成 [3 4 5],后端 1 还在):后端集合 [1 2 3],失败 0 次 6 秒起(后端 1 已停掉),到最后一次 A 查询之前:[6, 30.0) 后端集合 [2 3],失败 0 次 最后一次 A 查询之后:后端集合 [3 4 5],失败 0 次
解析成功后,解析器只等连接管理发来的“重新解析”请求,并且两次解析至少隔 30 秒(可用 dns.SetMinResolutionInterval 调整)。DNS 记录改了,客户端不会马上知道。
DNS 的 A 查询时刻(秒,相对 t0):[6.0 7.0] 0–2 秒(记录 [1 2 3]):后端集合 [1 2 3],失败 0 次 2–6 秒(记录已换成 [3 4 5],后端 1 还在):后端集合 [1 2 3],失败 0 次 6 秒起(后端 1 已停掉),到最后一次 A 查询之前:[6, 7.0) 后端集合 [2 3 4 5],失败 0 次 最后一次 A 查询之后:后端集合 [3 4 5],失败 0 次
改成 1 秒后,连接出问题的当下就会重新解析并用上新地址。但没有连接问题时仍然不会主动查询。
fail-fast 调用:2.3 ms 后返回 code=Unavailable message="name resolver error: produced zero addresses" 3 秒时 DNS 加上记录;这时 A 查询时刻(相对 t0)[0.0 0.0 1.7 1.7] WaitForReady 调用:4.0 秒后返回 code=OK 整个过程 A 查询时刻(秒):[0.0 0.0 1.7 1.7 4.0] A 查询的名字依次是:svc.test. svc.test.lan. svc.test. svc.test.lan. svc.test.
域名不存在时,调用立即以 Unavailable 失败;解析器按指数退避重试。WaitForReady 的调用会等到某次重试成功。
fail-fast 调用:0.7 ms 后返回 code=Unavailable message="name resolver error: produced zero addresses"
域名存在但没有 A 记录,与域名不存在的错误信息相同(produced zero addresses)。