系统设计之负载均衡
系统设计之负载均衡
针对分布式系统横向扩展,通常使用集群,可以使web应用服务器集群,也可以
将负载(访问请求)“均衡”地分配到多个处理节点,这样可以减少单个处理节点的请求量,提升整体系统的性能。
- DNS负载均衡
- 代理类的负载均衡
- 客户端的负载均衡
DNS 负载均衡
A记录, 将特定的主机名映射到对应主机的IP地址上。
域名配置多个A记录,每次域名解析请求都会根据对应的负载均衡算法计算出一个不同的IP地址并返回,这样A记录中配置多个服务器就可以构成一个集群,并可以实现负载均衡
优点:
省去了网站管理维护负载均衡服务器的麻烦,技术实现比较灵活、方便,简单易行,成本低,使用于大多数TCP/IP应用。
DNS可以支持基于地理位置的域名解析,会将域名解析成距离用户地理最近的一个服务器地址,这样就可以加速用户访问,改善性能。
缺点:
DNS是多级解析的,每一级DNS都可能缓存A记录,当某台服务器下线之后,即使修改了A记录,要使其生效也需要较长的时间,这段时间,DNS仍然会将域名解析到已下线的服务器上,最终导致用户访问失败。
不能够按服务器的处理能力来分配负载。DNS负载均衡采用的是简单的轮询算法,不能区分服务器之间的差异,不能反映服务器当前运行状态,所以负载均衡效果并不是太好。
异地多活
灾备,持续可用。
常用两地三中心,数据中心A,数据中心B位于同城,用户访问随机访问到A或B。A和B同步数据复制,保持consistency。由于同步复制,对数据中心距离有要求,需要两个数据中心必须在同城,或者距离很近的另一城市。异地备份通过异步,正常情况下不对外提供服务。
对于数据一致性要求不高的情况,多地的数据中心同步,并且均提供对外服务。可用DNS作为一级负载均衡到不同数据中心,数据中心再使用二级负载均衡器。
代理类的负载均衡
- HAProxy
- LVS ( Linux Virtual Server )
- nginx
HAProxy
HAProxy 支持两种代理模式 TCP(四层)和HTTP(七层)
HAProxy 跟 LVS 类似,本身就只是一款负载均衡软件;单纯从效率上来讲 HAProxy 会比 Nginx 有更出色的负载均衡速度,在并发处理上也是优于 Nginx 的。
HAProxy 支持 TCP 协议的负载均衡转发,可以对 MySQL 读进行负载均衡,对后端的 MySQL 节点进行检测和负载均衡,大家可以用 LVS+Keepalived 对 MySQL 主从做负载均衡。
LVS
LVS 是四层(传输层)负载均衡,要通过报文中的目标地址和端口,效率高。因为是在传输层,因此几乎可以针对所有应用场景做负载均衡,http,数据库流量等等。。。
缺点:不能针对url做更为细致的分发,无法探测后端服务示范存活
(OSI 网络模型把整个网络分成了七层,自下而上分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层)
Nginx
七层(应用层)的负载均衡,适用于http,以反向代理的方式进行负载均衡。
(反向代理:接受公网的请求,nginx将请求转发到内部网络的服务器,将服务器得到的结果返回;内部网络的服务器不暴露给公网访问)
优点:配置灵活,可以感知后端健康状态。
缺点:性能低于四层负载均衡。
如何探测服务节点可用
阿里开源nginx_upstream_check_module
定期地探测后端服务的一个指定的接口,然后根据返回的状态码来判断服务是否还存活。当探测不存活的次数达到一定阈值时,就自动将这个后端服务从负载均衡服务器中摘除。
upstream server { |
负载均衡策略:
Round robin
轮询,nginx的默认负载均衡策略。例如三台服务器A、B、C,请求依次分发到A、B、C。
Weighted_Round_Robin
轮询的策略可以做到将请求尽量平均地分配到所有服务节点上,但是,它没有考虑服务节点的具体配置情况。比如,你有三个服务节点,其中一个服务节点的配置是 8 核 8G,另外两个节点的配置是 4 核 4G,那么如果使用轮询的方式来平均分配请求的话,8 核 8G 的节点分到的请求数量和 4 核 4G 的一样多,就不能发挥性能上的优势
加权轮询, 如下配置
upstream backend { |
IP_hash
对IP进行hash,某个IP来的请求会分配到固定的节点
Least Connection
选择连接数最少的服务器节点优先负载
第三方
url_hash是nginx的第三方模块, 按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器
fail,按后端服务器的响应时间来分配请求,响应时间短的优先分配。
LVS + Nginx
可以使用LVS+nginx 做负载均衡,LVS在入口处承担大流量的分发,Nginx 要部署在业务服务器之前做更细维度的请求分发。
客户端负载均衡
针对微服务,尤其是RPC调用,通常服务节点存储在注册中心中(服务发现),代理类的负载均衡很难结合服务注册中心获取完整、最新的节点列表。
客户端可以从注册中心获取最新的节点列表,根据一定策略选取合适的节点,发送请求。

eg:Spring Cloud的 ribbon的weightedResponseTimeRule 是使用响应时间给每个服务节点计算一个权重,然后依据这个权重,来给调用方分配服务节点。
Reference
https://zhuanlan.zhihu.com/p/76918261