我需要将数据发送到具有以下 DNS 结构的服务 (service.example.com)(IP 地址和名称已化名):
$ dig service.example.com
; <<>> DiG xxxxxxx <<>> service.example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32008
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;service.example.com. IN A
;; ANSWER SECTION:
service.example.com. 740 IN CNAME service.example.com.some.internal.service.com.
service.example.com.some.internal.service.com. 290 IN A 300.402.251.65
service.example.com.some.internal.service.com. 290 IN A 300.402.250.1
service.example.com.some.internal.service.com. 290 IN A 300.402.249.65
service.example.com.some.internal.service.com. 290 IN A 300.402.248.1
;; Query time: 0 msec
;; SERVER: 10.0.0.102#53(10.0.0.102)
;; WHEN: Mi Apr 10 08:27:42 CEST 2024
;; MSG SIZE rcvd: 158
我正在使用 Quarkus,但 Quarkus 的其余客户端似乎无法处理不同的 IP 地址,这意味着如果第一个地址无法访问,则其余客户端无法找到其他地址。 这就是为什么有人向我求婚 Stork。我试图实现最简单的请求,但即使这样也行不通。我总是得到:
2024-04-12 13:51:17.596 ERROR [io.sm.st.im.CachingServiceDiscovery:72] [] [] Failed to fetch service instances: java.lang.RuntimeException: No DNS server was able to resolve 'service.example.com'
这是我在 Quarkus application.properties 中的设置(我什至分配了从成功的 nslookup -debug service.example.com 获得的 DNS):
quarkus.stork.my-service.service-discovery.type=dns
quarkus.stork.my-service.service-discovery.hostname=service.example.com
quarkus.stork.my-service.service-discovery.port=8443
quarkus.stork.my-service.service-discovery.secure=true
quarkus.stork.my-service.service-discovery.dns-timeout=8s
quarkus.stork.my-service.service-discovery.dns-servers=dns.dns1.de
quarkus.stork.my-service.service-discovery.record-type=A
我最初尝试不设置 dns-servers,但出现同样的问题。 我也尝试过记录类型 AAAA 或 SRV,但没有变化。 我也尝试过 https://service.example.com:8443 或 service.example.com:8443,但没有变化。
在 Quarkus 中,我是这样构建客户端的:
RestClientBuilder.newBuilder()
.baseUri(URI.create("stork://my-service"))
.build(ServiceHealthInterface.class);
我的第一个想法是 CNAME 是问题所在,但我也尝试过另一个网站,例如 x.com。条目看起来像这样:
$ dig x.com
; <<>> DiG xxxxxxx <<>> x.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28082
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;x.com. IN A
;; ANSWER SECTION:
x.com. 292 IN A 300.144.42.1
x.com. 292 IN A 300.144.42.129
x.com. 292 IN A 300.144.42.193
x.com. 292 IN A 300.144.42.65
;; Query time: 0 msec
;; SERVER: 10.1.1.102#53(10.1.1.102)
;; WHEN: Fr Apr 12 16:02:59 CEST 2024
;; MSG SIZE rcvd: 98
但我得到相同的结果:无法获取服务实例:java.lang.RuntimeException:没有 DNS 服务器能够解析“x.com”
我对这个框架的理解有误吗?这不是为了我的需要而设计的吗?
我现在找到了解决方案:
首先,我打开了所有本地端口,因此超时问题消失了(我仍然需要缩小问题所在的端口范围)。
其次,我必须创建一些标头处理程序(实现 org.eclipse.microprofile.rest.client.ext.ClientHeadersFactory),通过“Host: service.example.com”扩展标头。这是必要的,因为否则请求会运行到“错误的位置”,或者换句话说,就像在浏览器中调用IP(显然这并不一定意味着“真实”网站就是登陆页面)