注: 本文非原创属转载
抽空自己写了个简易版的 rpc 框架, 想了下怎么搞负载均衡, 最简单的方式就是搞个配置文件放置服务地址, 直接读配置文件, 转而想到配置文件可以放 zk, 相当于用 zk 来做配置中心或者服务发现. 优秀的 dubbo 项目就可以这么做, 马上参考了下谷歌的 grpc, 发现了一篇谷歌很棒的文章, 拜读了下(也借用了谷歌这篇文章的图片), 很不错, 想写一些我自己的见解.
传送门: https://grpc.io/blog/loadbalancing/
rpc 通信本身并不复杂, 只要定好协议怎么处理问题不大, 但是负载均衡的策略是值得推敲的.
一般情况下, 负载均衡的策略有以下两种
1. 代理服务
客户端并不知道服务端的存在, 它所有的请求都打到代理服务, 由代理服务去分发到服务端, 并且实现公平的负载算法. 客户机可能不可信, 这种情况通过用户面向用户的服务, 类似于我们的 nginx 将请求分发到后端机器.
缺点: 客户端不知道后端的存在, 且客户端不可信, 延迟会更高且代理服务会影响服务本身的吞吐量
优点: 在中间层做监控等拦截操作特别棒.
2. 客户端负载均衡
客户端知道有多个后端服务, 由客户端去选择服务端, 并且客户端可以从后端服务器中自己总结出一份负载的信息, 实现负载均衡算法. 这种方式最简单的实现就是我上面说的直接搞个配置文件, 调用的时候随机或者轮询服务端即可.
优点:
高性能, 因为消除了第三方的交互
缺点:
客户端会很复杂, 因为客户端要跟踪服务器负载和健康状况, 客户端实现负载均衡算法. 多语言的实现和维护负担也很麻烦, 且客户端需要被信任, 得是靠谱的客户端.
以上是介绍了两种负载均衡的方案, 下面要说的就是使用代理方式负载均衡的几种详细的方案
代理方式的负载均衡有很多种
代理负载平衡可以是 L3/L4(传输级别) 或 L7(应用程序级别).
在 L3/L4 中, 服务器终止 TCP 连接并打开另一个连接到所选的后端.
L7 只是在客户端连接到服务端端连接之间搞一个应用来做中间人.
L3/L4 级别的负载均衡按设计只做很少的处理, 与 L7 级别的负载均衡相比的延迟会更少, 而且更便宜, 因为它消耗更少的资源.
在 L7(应用程序级)负载平衡中, 负载均衡服务终止并解析协议. 负载均衡服务可以检查每个请求并根据请求内容分配后端. 这就意味监控拦截等操作可以非常方便快捷的做在这里.
L3/L4 vs L7
正确的打开方式有一下几种
1. 这些连接之间的 RPC 负载变化很大: 建议使用 L7.
2. 存储或计算相关性很重要 : 建议使用 L7, 并使用 cookie 或类似的路由请求来纠正服务端.
3. 设备资源少(缺钱): 建议使用 L3/L4.
4. 对延迟要求很严格(就是要快): L3/L4.
下面要说的就是客户端实现负载均衡方式的详细方案:
1. 笨重的客户端
这就意味着客户端中实现负载平衡策略, 客户端负责跟踪可用的服务器以及用于选择服务器的算法. 客户端通常集成与其他基础设施 (如服务发现, 名称解析, 配额管理等) 通信的库, 这就很复杂庞大了.
2. Lookaside 负载均衡 (旁观?)
旁观式负载平衡也称为外部负载平衡, 使用后备负载平衡, 负载平衡的各种功能智能的在一个单独的特殊的负载均衡服务中实现. 客户端只需要查询这个旁观式的负载均衡服务, 这个服务就能给你最佳服务器的信息, 然后你拿这个数据去请求那个服务端. 就像我一开说的比如把服务端的信息注册到 zk, 由 zk 去做负载均衡的事情, 客户端只需要去 zk 取服务端数据, 拿到了服务端地址后, 直接向服务端请求.
以上说了这么多, 到底服务间的负载均衡应该用哪个, 总结以下几点:
1. 客户端和服务器之间非常高的流量, 且客户端是可信的, 建议使用'笨重'的客户端 或者 Lookaside 负载均衡
2. 传统设置 -- 许多客户端连接到代理背后的大量服务, 需要服务端和客户端之间有一个桥梁, 建议使用代理式的负载均衡
3. 微服务 - N 个客户端, 数据中心有 M 个服务端, 非常高的性能要求(低延迟, 高流量), 客户端可以不受信任, 建议使用 Lookaside 负载均衡
往期精彩内容
《 两个月拿到 N 个 offer, 看看我是如何做到的 》
《 面试总结: 2019 年最全面试题资料学习大全 -(含答案) 》
《 淘宝面试回来, 想对程序员们谈谈 》
《 看过太多大厂面试题, 其实考的无非是这 3 点能力 》
《 一篇简单易懂的原理文章, 让你把 JVM 玩弄与手掌之中 》
来源: http://www.jianshu.com/p/dd89ef1a645e