diff --git a/ch6-cloud/ch6-05-load-balance.md b/ch6-cloud/ch6-05-load-balance.md index e91233e..fb3075a 100644 --- a/ch6-cloud/ch6-05-load-balance.md +++ b/ch6-cloud/ch6-05-load-balance.md @@ -68,7 +68,7 @@ func request(params map[string]interface{}) error { 我们循环一遍 slice,两两交换,这个和我们平常打牌时常用的洗牌方法类似。看起来没有什么问题。 -## 有没有什么问题? +### 错误的洗牌导致的负载不均衡 真的没有问题么?实际上还是有问题的。这段简短的程序里有两个隐藏的隐患: @@ -80,7 +80,7 @@ func request(params map[string]interface{}) error { 显然,这里给出的洗牌算法对于任意位置的元素来说,有 30% 的概率不对其进行交换操作。所以所有元素都倾向于留在原来的位置。因为我们每次对 shuffle 数组输入的都是同一个序列,所以第一个元素有更大的概率会被选中。在负载均衡的场景下,也就意味着 endpoints 数组中的第一台机器负载会比其它机器高不少(这里至少是 3 倍以上)。 -## 修正后的洗牌算法 +### 修正洗牌算法 从数学上得到过证明的还是经典的 fisher-yates 算法,主要思路为每次随机挑选一个值,放在数组末尾。然后在 n-1 个元素的数组中再随机挑选一个值,放在数组末尾,以此类推。