diff --git a/notes/pics/lb-dns.png b/notes/pics/lb-dns.png new file mode 100644 index 00000000..19345683 Binary files /dev/null and b/notes/pics/lb-dns.png differ diff --git a/notes/pics/lb-http-redirect.png b/notes/pics/lb-http-redirect.png new file mode 100644 index 00000000..da0c3fa9 Binary files /dev/null and b/notes/pics/lb-http-redirect.png differ diff --git a/notes/pics/lb-ip-hash.png b/notes/pics/lb-ip-hash.png new file mode 100644 index 00000000..c9cbe07d Binary files /dev/null and b/notes/pics/lb-ip-hash.png differ diff --git a/notes/pics/lb-least-conn-problem.png b/notes/pics/lb-least-conn-problem.png new file mode 100644 index 00000000..989050fa Binary files /dev/null and b/notes/pics/lb-least-conn-problem.png differ diff --git a/notes/pics/lb-least-conn.png b/notes/pics/lb-least-conn.png new file mode 100644 index 00000000..a18dbccd Binary files /dev/null and b/notes/pics/lb-least-conn.png differ diff --git a/notes/pics/lb-random.png b/notes/pics/lb-random.png new file mode 100644 index 00000000..78ec1e84 Binary files /dev/null and b/notes/pics/lb-random.png differ diff --git a/notes/pics/lb-round-robin-weak.png b/notes/pics/lb-round-robin-weak.png new file mode 100644 index 00000000..7a3250a4 Binary files /dev/null and b/notes/pics/lb-round-robin-weak.png differ diff --git a/notes/pics/lb-round-robin.png b/notes/pics/lb-round-robin.png new file mode 100644 index 00000000..b4d2f008 Binary files /dev/null and b/notes/pics/lb-round-robin.png differ diff --git a/notes/pics/lb-weighted-round-robin.png b/notes/pics/lb-weighted-round-robin.png new file mode 100644 index 00000000..cbbbd79d Binary files /dev/null and b/notes/pics/lb-weighted-round-robin.png differ diff --git a/notes/集群.md b/notes/集群.md index df93c17c..0a0125ce 100644 --- a/notes/集群.md +++ b/notes/集群.md @@ -45,14 +45,14 @@ 轮询算法把每个请求轮流发送到每个服务器上。 -下图中,一共有 6 个客户端产生了 6 个请求,这 6 个请求按 (1, 2, 3, 4, 5, 6) 的顺序发送。(1, 3, 5) 的请求会被发送到服务器 1,(2, 4, 6) 的请求会被发送到服务器 2。 +下图中,6 个请求按 (1, 2, 3, 4, 5, 6) 的顺序到达。(1, 3, 5) 的请求会被发送到服务器 1,(2, 4, 6) 的请求会被发送到服务器 2。 -

+

该算法比较适合每个服务器的性能差不多的场景,如果有性能存在差异的情况下,那么性能较差的服务器可能无法承担过大的负载(下图的 Server 2)。 -

+

#### 2. 加权轮询(Weighted Round Robin) @@ -60,9 +60,9 @@ 例如下图中,服务器 1 被赋予的权值为 5,服务器 2 被赋予的权值为 1,那么 (1, 2, 3, 4, 5) 请求会被发送到服务器 1,(6) 请求会被发送到服务器 2。 -

+

-实际实现(例如 Nginx 的平滑加权轮询)会把请求交错发送,避免连续的请求集中到同一台服务器上。 +实际实现(例如 Nginx 的平滑加权轮询)会把请求交错发送,避免连续的请求集中到同一台服务器上,上图最后一行是按 Nginx 源码中的算法计算出的顺序。 #### 3. 最少连接(Least Connections) @@ -70,13 +70,13 @@ 例如下图中,(1, 3, 5) 请求会被发送到服务器 1,但是 (1, 3) 很快就断开连接,此时只有 (5) 请求连接服务器 1;(2, 4, 6) 请求被发送到服务器 2,只有 (2) 的连接断开,此时 (6, 4) 请求连接服务器 2。该系统继续运行时,服务器 2 会承担过大的负载。 -

+

最少连接算法就是将请求发送给当前最少连接数的服务器上。 例如下图中,服务器 1 当前连接数最小,那么新到来的请求 6 就会被发送到服务器 1 上。 -

+

#### 4. 加权最少连接(Weighted Least Connection) @@ -88,7 +88,7 @@ 和轮询算法类似,该算法比较适合服务器性能差不多的场景。 -

+

#### 6. 源地址哈希法 (IP Hash) @@ -96,9 +96,9 @@ 可以保证同一 IP 的客户端的请求会转发到同一台服务器上,用来实现会话粘滞(Sticky Session)。 -

+

-缺点是同一出口 IP 后面的大量用户会落到同一台服务器上,造成负载不均;服务器数量变化时取模结果会全部改变,可以改用一致性哈希。 +缺点是同一出口 IP 后面的大量用户会落到同一台服务器上,造成负载不均;服务器数量变化时大部分客户端的取模结果都会改变,可以改用一致性哈希。需要注意的是,Nginx 的 ip_hash 只用 IPv4 地址的前 3 个字节计算哈希,同一个 /24 网段的客户端都会落到同一台服务器上。 ### 转发实现 @@ -113,7 +113,7 @@ HTTP 重定向负载均衡服务器使用某种负载均衡算法计算得到服 该负载均衡转发的缺点比较明显,实际场景中很少使用它。 -

+

#### 2. DNS 域名解析 @@ -129,7 +129,7 @@ HTTP 重定向负载均衡服务器使用某种负载均衡算法计算得到服 大型网站基本使用了 DNS 作为第一级负载均衡手段,然后在内部使用其它方式做第二级负载均衡。也就是说,域名解析的结果为内部的负载均衡服务器 IP 地址。 -

+

#### 3. 反向代理服务器 @@ -174,7 +174,9 @@ HTTP 重定向负载均衡服务器使用某种负载均衡算法计算得到服 参考: - [Comparing Load Balancing Algorithms](http://www.jscape.com/blog/load-balancing-algorithms) -- [Redirection and Load Balancing](http://slideplayer.com/slide/6599069/#) +- [Nginx: ngx_http_upstream_module](https://nginx.org/en/docs/http/ngx_http_upstream_module.html) +- [Nginx 源码:ngx_http_upstream_round_robin.c](https://github.com/nginx/nginx/blob/master/src/http/ngx_http_upstream_round_robin.c) +- [Redirection and Load Balancing](https://web.archive.org/web/20250420002753/http://slideplayer.com/slide/6599069/) ## 二、集群下的 Session 管理 @@ -229,5 +231,5 @@ HTTP 重定向负载均衡服务器使用某种负载均衡算法计算得到服 参考: -- [Session Management using Spring Session with JDBC DataStore](https://sivalabs.in/2018/02/session-management-using-spring-session-jdbc-datastore/) +- [Session Management using Spring Session with JDBC DataStore](https://web.archive.org/web/20230602191402/https://www.sivalabs.in/2018/02/session-management-using-spring-session-jdbc-datastore/) diff --git a/tools/diagram/src/lb-dns.svg b/tools/diagram/src/lb-dns.svg new file mode 100644 index 00000000..fc4f41a5 --- /dev/null +++ b/tools/diagram/src/lb-dns.svg @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + DNS 负载均衡:解析域名时选出服务器 + + + + + 客户端 + + + + + + + DNS 服务器 + 按地域或轮询返回 IP + + + + + + + + + + Server 2 + 203.0.113.12 + + ① 查询 www.example.com + + ② A 203.0.113.12,TTL 600 + + ③ GET http://www.example.com/ + 600 秒内本地和各级 DNS 缓存都直接返回这个地址,下线 Server 2 后要等缓存过期才生效。 + diff --git a/tools/diagram/src/lb-http-redirect.svg b/tools/diagram/src/lb-http-redirect.svg new file mode 100644 index 00000000..4b447498 --- /dev/null +++ b/tools/diagram/src/lb-http-redirect.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + HTTP 重定向:负载均衡器只返回目标地址 + + + + + 浏览器 + + + + + + + 负载均衡器 + www.example.com + + + + + + + + + + Server 2 + 203.0.113.12 + + ① GET http://www.example.com/ + + ② 302 Found + Location: http://203.0.113.12/ + + ③ GET http://203.0.113.12/ + 浏览器要发两次请求,之后直接访问 203.0.113.12,负载均衡器无法再调整。 + diff --git a/tools/diagram/src/lb-ip-hash.svg b/tools/diagram/src/lb-ip-hash.svg new file mode 100644 index 00000000..81291378 --- /dev/null +++ b/tools/diagram/src/lb-ip-hash.svg @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + 源地址哈希:同一个 IP 总是落到同一台服务器 + + + + + 192.0.2.30 + crc32(IP) % 2 = 0 + + + + + + 198.51.100.8 + crc32(IP) % 2 = 0 + + + + + + 203.0.113.11 + crc32(IP) % 2 = 1 + + + + + + 198.51.100.7 + crc32(IP) % 2 = 1 + + + + + + + + + + + Server 1 + 余数为 0 的客户端 + + + + + + + + + + Server 2 + 余数为 1 的客户端 + 示意:用 crc32(IP) % 服务器数 选择服务器。服务器数量变化时,大部分客户端的结果都会改变。 + diff --git a/tools/diagram/src/lb-least-conn-problem.svg b/tools/diagram/src/lb-least-conn-problem.svg new file mode 100644 index 00000000..d78ed0a9 --- /dev/null +++ b/tools/diagram/src/lb-least-conn-problem.svg @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + 轮询不考虑连接的持续时间 + Server 1 + + Server 2 + + + 请求 1 + + 请求 2 + + 请求 3 + + 请求 4 + + 请求 5 + + 请求 6 + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 时间 + + 请求 6 到达时:Server 1 有 1 个连接,Server 2 有 2 个 + 请求 1、3 很快结束,请求 2 结束前又来了 4 和 6:轮询把 6 发给了已有 2 个连接的 Server 2。 + diff --git a/tools/diagram/src/lb-least-conn.svg b/tools/diagram/src/lb-least-conn.svg new file mode 100644 index 00000000..4c7f0e79 --- /dev/null +++ b/tools/diagram/src/lb-least-conn.svg @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + 最少连接:发给当前连接数最少的服务器 + Server 1 + + Server 2 + + + 请求 1 + + 请求 2 + + 请求 3 + + 请求 4 + + 请求 5 + + 请求 6 + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 时间 + + 请求 6 到达时:Server 1 有 1 个连接,Server 2 有 2 个 + 同样的请求,最少连接算法把请求 6 发给只有 1 个连接的 Server 1,两台各有 2 个连接。 + diff --git a/tools/diagram/src/lb-random.svg b/tools/diagram/src/lb-random.svg new file mode 100644 index 00000000..f35835ee --- /dev/null +++ b/tools/diagram/src/lb-random.svg @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + 随机:每个请求随机选一台服务器 + 请求按顺序到达 + + 1 + + 2 + + 3 + + 4 + + 5 + + 6 + + + + + + + + + + + 负载均衡器 + 随机 + + + + + + + + + + + Server 1 + + 1 + + 2 + + 4 + + + + + + + + + + + Server 2 + + 3 + + 5 + + 6 + 请求少时分配可能不均,请求多时接近平均:模拟 10000 个请求,两台分到 5055 和 4945 个。 + diff --git a/tools/diagram/src/lb-round-robin-weak.svg b/tools/diagram/src/lb-round-robin-weak.svg new file mode 100644 index 00000000..569e0be7 --- /dev/null +++ b/tools/diagram/src/lb-round-robin-weak.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + 轮询不考虑服务器的性能 + 请求按顺序到达 + + 1 + + 2 + + 3 + + 4 + + 5 + + 6 + + + + + + + + + + + 负载均衡器 + 轮询 + + + + + + + + + + + Server 1 + + 1 + + 3 + + 5 + 8 核,CPU 30% + + + + + + + + + + + Server 2 + + 2 + + 4 + + 6 + 2 核,CPU 95%,请求排队 + 两台分到的请求一样多,但 Server 2 的处理能力只有 Server 1 的四分之一。 + diff --git a/tools/diagram/src/lb-round-robin.svg b/tools/diagram/src/lb-round-robin.svg new file mode 100644 index 00000000..f8ffe437 --- /dev/null +++ b/tools/diagram/src/lb-round-robin.svg @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + 轮询:请求轮流发给每台服务器 + 请求按顺序到达 + + 1 + + 2 + + 3 + + 4 + + 5 + + 6 + + + + + + + + + + + 负载均衡器 + 轮询 + + + + + + + + + + + Server 1 + + 1 + + 3 + + 5 + + + + + + + + + + + Server 2 + + 2 + + 4 + + 6 + 两台服务器各分到 3 个请求,适合性能相近的服务器。 + diff --git a/tools/diagram/src/lb-weighted-round-robin.svg b/tools/diagram/src/lb-weighted-round-robin.svg new file mode 100644 index 00000000..6d99265e --- /dev/null +++ b/tools/diagram/src/lb-weighted-round-robin.svg @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + 加权轮询:按权重分配请求 + 请求按顺序到达 + + 1 + + 2 + + 3 + + 4 + + 5 + + 6 + + + + + + + + + + + 负载均衡器 + 加权轮询 + + + + + + + + + + + Server 1 + + 1 + + 2 + + 3 + + 4 + + 5 + 权重 5 + + + + + + + + + + + Server 2 + + 6 + 权重 1 + 6 个请求依次发给: + 按权重连续分配 + + S1 + + S1 + + S1 + + S1 + + S1 + + S2 + Nginx 平滑加权轮询 + + S1 + + S1 + + S1 + + S2 + + S1 + + S1 +