mirror of
https://github.com/chai2010/advanced-go-programming-book.git
synced 2025-05-24 12:32:21 +00:00
update lb
This commit is contained in:
parent
97f38305c1
commit
4ceca84578
@ -82,11 +82,29 @@ func request(params map[string]interface{}) error {
|
|||||||
|
|
||||||
## 修正后的洗牌算法
|
## 修正后的洗牌算法
|
||||||
|
|
||||||
从数学上得到过证明的还是经典的 fisher-yates 算法,在 Go 的标准库中实际上已经为我们内置了该算法:
|
从数学上得到过证明的还是经典的 fisher-yates 算法,主要思路为每次随机挑选一个值,放在数组末尾。然后在 n-1 个元素的数组中再随机挑选一个值,放在数组末尾,以此类推。
|
||||||
|
|
||||||
|
在 Go 的标准库中实际上已经为我们内置了该算法:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
func init() {
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
}
|
||||||
|
|
||||||
|
func shuffle(n int) []int {
|
||||||
|
b := rand.Perm(n)
|
||||||
|
return b
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
在当前的场景下,我们只要用 rand.Perm 就可以得到我们想要的索引数组了。
|
||||||
|
|
||||||
## zk 集群的随机节点挑选问题
|
## zk 集群的随机节点挑选问题
|
||||||
|
|
||||||
|
本节中的场景是从 N 个节点中选择一个节点发送请求,初始请求结束之后,后续的请求会重新对数组洗牌,所以每两个请求之间没有什么关联关系。因此我们上面的洗牌算法,理论上不初始化随机库的种子也是不会出什么问题的。
|
||||||
|
|
||||||
|
但在一些特殊的场景下,例如使用 zk 时,客户端初始化从多个服务节点中挑选一个节点后,是会向该节点建立长连接的。并且之后如果有请求,也都会发送到该节点去。直到该节点不可用,才会在 endpoints 列表中挑选下一个节点。在这种场景下,我们的初始连接节点选择就要求必须是“真”随机了。否则,所以客户端起动时,都会去连接同一个 zk 的实例,根本无法起到负载均衡的目的。如果在日常开发中,你的业务也是类似的场景,也务必考虑一下是否会发生类似的情况。
|
||||||
|
|
||||||
|
之所以会有上面这些结论,是因为某个使用较广泛的开源 zk 库的早期版本就犯了上述错误,直到 2016 年早些时候,这个问题才被修正。
|
||||||
|
|
||||||
## 故障节点摘除
|
## 故障节点摘除
|
||||||
|
Loading…
x
Reference in New Issue
Block a user