
我刚刚做了个测试,测试环境如下:
服务器 A ,IP 192.168.0.3
服务器 B IP 192.168.0.4
两台服务器都启动了一个 http 服务,端口是 7891
然后,我在本地 hosts 文件添加了以下的信息
192.168.0.3 test.com 192.168.0.4 test.com 在这个环境下,我 curl test.com:7891 当然是能访问的。这时候基本上都是访问了 192.168.0.3:7891 了。
curl 的输出符合预期。
然后我现在把 A 的 http 服务关了,超出我预期的情况发生了。curl 依然能返回 http 服务的返回数据。
我 curl -v 看了下,出现了类似这样的信息:
Trying 192.168.0.3:7891... * connect to 192.168.0.3 port 7891 failed: 拒绝连接* Trying 192.168.0.4:7891... * Connected to test.com (192.168.0.4) port 7891 (#0) 这超出我的意料了。而后我也尝试了下最新版本的 chrome ,也有这样的特性。
这是一直以来所有的 http 客户端都有的特性吗?
1 Admstor Oct 24, 2022 不能 多解析实际上更多用在负载平衡里(手段之一) |
2 jifengg Oct 24, 2022 看一些架构师的文章,会提到这个技巧,当你的一个出口负载已经完全无法承载压力了,就让 DNS 服务器来帮你分流吧。 但是,走到这一步的话,要考虑的事情也是很多的。不到迫不得已,没必要这么做。比如数据一致性等。 另一个,“尝试一个 host 下所有的 ip”,应该不是所有 http 客户端的特性,还是要看语言具体的实现的。 |
4 Admstor Oct 24, 2022 你这个只是本机测试,你感觉可以用 但是放到线上环境 你的客户的并不一定支持尝试其他解析 IP 此外你的业务也不可能是单一页面单一节点 |
6 Seulgi Oct 24, 2022 这不是客户端的功能. 这是 dns 解析服务器的功能. 云服务厂商都提供了这个服务, dns 可以解析多个 ip, 而且可以指定入网的 ip 段来制定解析对应的 ip, 具体就是我指定联通网请求 dns 返回 123 的 ip, 电信网请求 dns 返回 456 的 ip. |
7 eason1874 Oct 24, 2022 浏览器在好多年前就会自动切换了,多 IP 的网站,浏览器访问一个 IP 超时之后,自动刷新使用到下一个 IP 但是 DNS 解析多个 IP 一般只用来做负载均衡,不用来做高可用,因为超时要等待好几秒,用户有可能还没等到切换 IP ,就以为网站打不开从而关掉页面了 |
8 MartinWu OP @Admstor 不是,我只是第一次知道了有些 http 客户端有此特性,因此想求证下此特性是否是一个比较旧的 http rfc 了。 还不打算用于线上环境的。 |
10 MartinWu OP |
11 isno Oct 24, 2022 看看我写的高可用? https://isno.github.io/ 下一章节:负载均衡和网关 |
12 opengps Oct 24, 2022 这里的目的,是分散可用,从而表现成一种高可用.你的测试仅代表你一个客户端,不适合这个解释。 在公网下很显然全球各地,每个区域都有不同的可用性结论,多 dns 解析可以经过一些逻辑,就近选用 dns |
13 ThirdFlame Oct 24, 2022 这应该是 curl 和 chrome 自己加戏了。 正常情况下,取得解析结果中的某一个结果,例如 192.168.0.3 。 然后尝试连接,如果出错,那就停止。 并没有规定要去尝试其他的解析结果。 另外如果 192.168.0.3 端口能够正常连接,但是返回 500 ,而 192.168.0.4 正常,返回 200 。 这个时候 curl 和 chrome 并不会去尝试连接 192.168.0.4 。 所以仅仅依靠 dns 解析,无法实现高可靠。 |
14 eason1874 Oct 24, 2022 @MartinWu 客户端吧,而且不同客户端的超时时间不一样,它们也不会特意缓存 IP 有效性,现在 A 超时自动切换到 B ,过一会儿 DNS 缓存失效了,它再次解析再次使用 A 地址也是可能的,然后再等超时再切换 |
15 cheng6563 Oct 24, 2022 DNS 可以用来做负载均衡,但做不了高可用。 因为 DNS 层层缓存,更新起来非常慢,有些垃圾网络环境甚至一天不更新的。 |
16 Ansen Oct 24, 2022 你的 hosts 貌似只第一个生效,你可以 ping 一下看看 |
17 MartinWu OP @ThirdFlame 你的回答是最直接,最全面解答了我的疑问了。。感谢。 |
19 optional Oct 24, 2022 via iPhone 这个只能负载均衡降低单 ip 负载,其它甚至会导致 sSLA 降低 |
21 slowman Oct 24, 2022 via iPhone @MartinWu 可以去看 getaddrinfo 文档,建议也思考下 ipv6 浏览器如何使用。再了解下 happy eyeball 有哪些方案 |
24 bobryjosin Oct 24, 2022 这相当于把负载均衡交给 dns 了,客户端随机从解析值挑一个 ip ,只能作为分流手段,高可用不太现实,如果 dns 返回了一个已经挂掉的 ip ,dns 也没办法知道,除非你前置一个检测手段检测服务挂了自动更改 dns 解析,差不多可以实现基础高可用。 |
25 Tumblr Oct 24, 2022 这个叫 DNS round-robin ,或者叫 DNS 轮询。 https://en.wikipedia.org/wiki/Round-robin_DNS |
26 flynaj Oct 24, 2022 via Android 这个是客户端功能,不是 DNS ,DNS 正常情况把一堆 IP 给客户端,你这个还只是简单的多 IPv4,目前客户端要处理的是 v6,v4 优先级. |
27 guyeu Oct 25, 2022 via iPhone 感觉这个特性还真能做到某种层面的高可用,比如我们曾有服务 IP 地址被运营商封掉,如果方式那个服务的域名绑定了两个 IP ,哪怕是同一个主机,也不会导致某省用户全面掉线+我们花了整整一天排查这个问题 |
28 gamexg Oct 25, 2022 chrome 、curl 自己实现的自动重试下一个连接。 不过为了支持 ipv6 ,应该不少软件都会有类似的实现了。 ipv6 一般都是一个协议短期未成功则立刻同步另一个协议尝试。 顺便加上同协议多个 ip 地址并不麻烦。 另外 go 标准库我记得也是实现了单 ip 失败自动切换到另一个 ip 尝试。 |
29 MartinWu OP @gamexg 因为我记得以前是没有这个特性的。看到 chrome 和 curl 都实现了,我猜应该是某个时候开始出现的一个共识,然后楼上就提到了 happy eyeball 。应该就是当时为了解决 ipv4 和 ipv6 并存的问题而被提出的,然后逐渐大家都这么干了。 |
30 DefoliationM Oct 25, 2022 不能,因为要看客户端实现,可能客户端就是随机选择其中一个 |