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