首页 > 技术文章 > 负载均衡

tommaoxiaoqi 2020-04-03 11:48 原文

一张图:

 

一、API网关:

API网关的作用:将内部的API注册成外部的API,提供给用户使用。它的核心功能是提供统一门户, 其次可以提供统一鉴权,服务限流等功能。

在注册API接口的时候需要提供,外部url和对应的内部url,协议(https),方法(POST),内部端口,(https协议的外部端口默认是443)和服务名等。

在微服务的架构里,各个低耦合的微服务虽然易于开发部署和维护但客户确难以快速访问所需服务。API网关可以充当统一的门户,客户不用访问数十个不同的微服务,而是向API网关发送请求,API网关中聚集着不同微服务。由API网关根据服务名,接口等信息进行路由转发。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

弹性负载均衡(Elastic Load Balancing )是一个用来做网络负载均衡的网络组件,主要是通过4层(网络层)的开源组件LVS和7层(应用层)的开源组件NGINX实现。通过将访问流量自动分发到多台弹性云主机,扩展应用系统对外的服务能力,实现更高水平的应用程序容错性能

负载均衡服务主要由3个基本概念组成:

1.  LoadBalancer代表一个SLB实例,SLB(Server Load Balancer)服务通过设置虚拟服务地址(IP),将位于同一地域(Region)的多台云服务器(ECS)资源虚拟成一个高性能、高可用的应用服务池;再根据应用指定的方式,将来自客户端的网络请求分发到云服务器池中。

2.  Listener代表用户定制的负载均衡策略和转发规则

3.  Instance是后端的服务实例(VM或应用容器)。

来自外部的访问请求,通过负载均衡器,并根据相关的策略和转发规则分发到后端instance进行处理。

所谓四层负载均衡,也就是主要通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。以常见的TCP为例,负载均衡设备在接收到第一个来自客户端的SYN 请求时,即通过上述方式选择一个最佳的服务器,并对报文中目标IP地址进行修改(改为后端服务器IP),直接转发给该服务器。TCP的连接建立,即三次握手是客户端和服务器直接建立的,负载均衡设备只是起到一个类似路由器的转发动作。在某些部署情况下,为保证服务器回包可以正确返回给负载均衡设备,在转发报文的同时可能还会对报文原来的源地址进行修改。

所谓七层负载均衡,也称为“内容交换”,也就是主要通过报文中的真正有意义的应用层内容,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。以常见的TCP为例,负载均衡设备如果要根据真正的应用层内容再选择服务器,只能先代理最终的服务器和客户端建立连接(三次握手)后,才可能接受到客户端发送的真正应用层内容的报文,然后再根据该报文中的特定字段,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。负载均衡设备在这种情况下,更类似于一个代理服务器。负载均衡和前端的客户端以及后端的服务器会分别建立TCP连接。所以从这个技术原理上来看,七层负载均衡明显的对负载均衡设备的要求更高,处理七层的能力也必然会低于四层模式的部署方式。

 

第一张图中:ELB一般LVS配四层,SLB一般nginx配7层

二、 LVS:

LVS(Linux Virtual Server)。目前LVS已经被集成到Linux内核模块中。

通过一个VIP(虚拟IP,节点上增加一个公网网卡)接收请求,路由到真实的服务器。

 

 

 

内网IP:RFC1918规定了三个保留地址段落:10.0.0.0-10.255.255.255;172.16.0.0-172.31.255.255;192.168.0.0-192.168.255.255。这三个范围分别处于A,B,C类的地址段,不向特定的用户分配,被IANA作为私有地址保留。这些地址可以在任何组织或企业内部使用,和其他Internet地址的区别就是,仅能在内部使用,不能作为全球路由地址。

通常来说,局域网是属于链路层的,也就是说,通过交换机就能够搭建起一个简单的局域网,在这个局域网内通信,我们称为内网通信。

那么如何判断是否在一个局域网内呢?

tcp/ip协议的网际层的ip协议为每个电脑都分配了一个ip地址,我们可以通过ip地址与子网掩码进行运算,得出的结果相同,就证明在一个局域网内,需要明确的是,局域网内是可以直接通信的,因为局域网属于第二层,不需要经过网络层转发数据包。

NAT(Network Address Translation)即网络地址转换,其作用是通过数据报头的修改,使得位于企业内部的私有IP地址可以访问外网,以及外部用用户可以访问位于公司内部的私有IP主机。LVS负载调度器可以使用两块网卡配置不同的IP地址,eth0设置为私钥IP与内部网络通过交换设备相互连接,eth1设备为外网IP与外部网络联通。

 LVS三种模式:

1、基于NAT的LVS模式负载均衡 

第一步,用户通过互联网DNS服务器解析到公司负载均衡设备上面的外网地址,相对于真实服务器而言,LVS外网IP又称VIP(Virtual IP Address),用户通过访问VIP,即可连接后端的真实服务器(Real Server)

第二步,用户将请求发送至124.126.147.168,此时LVS将根据预设的算法选择后端的一台真实服务器(192.168.0.1~192.168.0.3),将数据请求包转发给真实服务器,并且在转发之前LVS会修改数据包中的目标地址以及目标端口,目标地址与目标端口将被修改为选出的真实服务器IP地址以及相应的端口。

第三步,真实的服务器将响应数据包返回给LVS调度器,调度器在得到响应的数据包后会将源地址和源端口修改为VIP及调度器相应的端口,修改完成后,由调度器将响应数据包发送回终端用户。(第一张图里应该采用该方法,内外网分隔也是经此)

此种方式Direct Server有一个外网卡和一个内网卡。Real Server只有一个内网卡。DS和RS必须在同一网段。

 

 

2、基于TUN的LVS负载均衡

在LVS(NAT)模式的集群环境中,由于所有的数据请求及响应的数据包都需要经过LVS调度器转发,如果后端服务器的数量大于10台,则调度器就会成为整个集群环境的瓶颈。我们知道,数据请求包往往远小于响应数据包的大小,因为响应数据包中包含有客户需要的具体数据,所以LVS(TUN)的思路就是将请求与响应数据分离,让调度器仅处理数据请求,而让真实服务器响应数据包直接返回给客户端。

IP隧道(IP tunning)是一种数据包封装技术,它可以将原始数据包封装并添加新的包头(内容包括新的源地址及端口、目标地址及端口),从而实现将一个目标为调度器的VIP地址的数据包封装,通过隧道转发给后端的真实服务器(Real Server),通过将客户端发往调度器的原始数据包封装,并在其基础上添加新的数据包头(修改目标地址为调度器选择出来的真实服务器的IP地址及对应端口),LVS(TUN)模式要求真实服务器可以直接与外部网络连接,真实服务器在收到请求数据包后直接给客户端主机响应数据。

DS和RS都在公网,可在不同的区域,如一个在北京一个在广东。

 

 

 

3、基于DR的LVS负载均衡

在LVS(TUN)模式下,由于需要在LVS调度器与真实服务器之间创建隧道连接,这同样会增加服务器的负担。与LVS(TUN)类似,DR模式也叫直接路由模式,该模式中LVS依然仅承担数据的入站请求以及根据算法选出合理的真实服务器,最终由后端真实服务器负责将响应数据包发送返回给客户端。与隧道模式不同的是,直接路由模式(DR模式)要求调度器与后端服务器必须在同一个局域网内,VIP地址需要在调度器与后端所有的服务器间共享,因为最终的真实服务器给客户端回应数据包时需要设置源IP为VIP地址,目标IP为客户端IP,这样客户端访问的是调度器的VIP地址,回应的源地址也依然是该VIP地址(真实服务器上的VIP),客户端是感觉不到后端服务器存在的。

由于多台计算机都设置了同样一个VIP地址,所以在直接路由模式中要求调度器的VIP地址是对外可见的,客户端需要将请求数据包发送到调度器主机,而所有的真实服务器的VIP地址必须配置在Non-ARP的网络设备上,也就是该网络设备并不会向外广播自己的MAC及对应的IP地址,真实服务器的VIP对外界是不可见的,但真实服务器却可以接受目标地址VIP的网络请求,并在回应数据包时将源地址设置为该VIP地址。调度器根据算法在选出真实服务器后,在不修改数据报文的情况下,将数据帧的MAC地址修改为选出的真实服务器的MAC地址,通过交换机将该数据帧发给真实服务器。整个过程中,真实服务器的VIP不需要对外界可见。走二层链路层协议,不通过IP层,省去IP隧道。

 

 

https://blog.csdn.net/Ki8Qzvka6Gz4n450m/article/details/79119665

最常用的是DR,Direct Server和Real Server在同一机房(局域网)。和NAT的不同是一个RS是在内网,请求通过Direct Server原路返回;一个是RS可在公网也可在内网,通过VIP之接返回客户端。

以此演示DR:

客户端通过VIP访问Direct Server。如:LVS节点是141节点即Direct Server,创建虚拟ip130,两台真实服务器节点是135,139(只演示LVS原理,IP都是内网IP)。

按照ipvsadmin软件后,在lVS节点执行脚本创建虚拟网卡;

 

执行完后添加了虚拟网卡eth0:0 和虚拟IP130。

 

 

 在两台real Server上分别执行脚本添加VIP。(arpignore,不对外广播VIP地址)

 

 

 

通过虚拟地址访问就会路由到真实服务器。

 

 

 

三、Nginx:

 

 

 

 

正向代理: 代理客户端,服务器不知道真实客户端的存在。如代理访问外网。

反向代理:代理服务端。

upstream server 上游服务器,配置被代理的真实服务器;

负载均衡:

负载均衡算法: 默认轮询(可设权重)。哈希映射(ip,url等)。

基本配置:https://nginx.org/en/docs/

http {
    upstream myapp1 {
        server srv1.example.com weight=3; 
        server srv2.example.com;
        server srv3.example.com;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://myapp1;
        }
    }
}

数据库服务器存储数据,采用哈希算法落点会对所有节点取模,当有一台新增或故障时候,总数变,所有的key映射结果可能都会变化,可能会涉及大量数据的迁移。 所以采用一致性哈希只影响少数key的映射结果。

将服务器映射到一个圆环,请求的key(如ip)通过hash映射到圆环顺时针找最接近的服务器。有一个服务器节点宕机或新加可以只影响该节点上下游的数据,其他节点映射结果不变。

每个key可以通过hash算法转化成32位的二进制数。圆环的大小是2的32次方。IPV4最大是 2的32次方,这样就能保证对所有IP取膜不重复。

若服务器较少,为了均衡分批,由服务器node派生出虚拟节点映射到圆环上,请求key映射到虚拟节点后实际找的是真实节点来处理。

 

 

 一致性哈希:https://blog.csdn.net/cywosp/article/details/23397179

 

对于数据分库存储的场景需要一致性哈希保持扩展性。

对于ngnix负载均衡算法采用一致性哈希可以解决session不一致问题。https://my.oschina.net/u/3370769/blog/2887101 (除了一致性哈希把每个ip的请求都映射到同一台服务器,还可以通过tomcat配置进行session复制,和redis共享session)

 

缓存:

缓存在nginx本地,一般是静态页面,不需要回调数据库的请求,通过html等后缀过滤需要缓存的请求。在没有CDN加速的时候,通过ngnix缓存达到类似的效果。

服务器正常响应的状态为200。304则表示有缓存的响应,304不应该是一种错误。

 配置:

#缓存存放路径;缓存区名称;缓存占内存最大10M,占硬盘空间最大30G;
proxy_cache_path /data/nginx/cache keys_zone=cache_zone:10m max_size=30g;

server {
    ...
    location / {
        proxy_pass http://backend;
        proxy_cache cache_zone;
        proxy_cache_key $uri;#以url为key
    }
}
https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache
https://www.cnblogs.com/zyxnhr/p/10725245.html

Nginx是热启动,修改配置不用重启。
健康检查:
Nginx对上游服务器的健康检查可以通过TCP心跳和http请求方式(http接口请求,2XX状态码判断成功)。
SSL:
Nginx也可以支撑SSL,将证书放到nginx上,即对外提供的https接口,在nginx上下证书,服务器是http接口。


推荐阅读