1
0
mirror of https://github.com/chai2010/advanced-go-programming-book.git synced 2025-05-24 20:52:22 +00:00

update lb

This commit is contained in:
Xargin 2018-08-14 15:22:54 +08:00
parent 195beabb3f
commit 2c58b35013

View File

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