分布式理论系列java
从ACID到CAP到BASElinux
复制、分片和路由web
副本更新策略算法
负载均衡算法及手段segmentfault
本文主要讲述负载均衡的一些基本东西。缓存
冷备份(cool standby),指配备平时不运行的备用设备,当运行设备发生故障时,使用备用设备替换。安全
热备份(hot standby),指在设备运行的同时运行备用设备,当运行设备发生故障时,可以自动替换备用设备。服务器
fail-over,在空余结构中,中止运行设备,使用备用设备进行工做的过程称为替换,英文称为fail-over或者switch-over。
fail-back,替换后再次恢复到原来的运行设备,也就是从运行状态的备用设备再切换到原来的运行设备的过程,称为回退,英文称为fail-back或switch-back。
1.主备方式(Active-Standby)
准备两台路由器,其中一台做为正常运行业务的活跃设备(active),也能够称为主设备(master)或者首要设备(primary)。另外一台做为发生故障时替换的备用设备(standby),也能够称为备机(backup)、从设备(slave)、必要设备(secondary)。活跃设备和备用设备必须共享关于设备的设置信息。
2.双活方式(Active-Active)
准备两台路由器,其中一台做为首要设备(primary),另外一台做为次要设备(secondary),两者同时运行来组成冗余结构。这种方式能够经过与负载均衡设备并用或者设置DNS、客户端一侧的路由信息来达到负载均衡的目的。
3.集群方式(Cluster)
在主备方式或双活方式中,使用3台以上的硬件协同组成冗余结构的方式。
L2基于数据链路层,L3基于网络层,具备IP分组与路由选择功能。
L2能够经过使用VLAN分割广播域,但终端之间的数据帧交换必须位于同一VLAN范围内。 不一样VLAN上的终端若有相互通讯需求,则必须使用路由器。
L3交换机与路由器都可以实现跨VLAN路由,但L3交换机多用于在以太网构筑的Intranet内部转发分组,而路由器则大多做为链接互联网与Intranet内网之间的网关来使用。
L4交换机
可以支持到TCP层级访问控制的交换机,称为L4交换机。
L7交换机
可以基于HTTP和HTTPS这类应用层L7参数进行负载均衡等操做的产品,称为L7交换机。
能够是专用设备,也能够是在通用服务器上运行的应用程序。 分散请求到拥有相同内容或提供相同服务的服务器。 专用设备通常只有以太网接口,能够说是多层交换机的一种。 负载均衡器通常会被分配虚拟IP地址,全部来自客户端的请求都是针对虚拟IP地址完成的。负载均衡器经过负载均衡算法未来自客户端的请求转发到服务器的实际IP地址上。
private Map<String,Integer> serverMap = new HashMap<String,Integer>(){{ put("192.168.1.100",1); put("192.168.1.101",1); put("192.168.1.102",4); put("192.168.1.103",1); put("192.168.1.104",1); put("192.168.1.105",3); put("192.168.1.106",1); put("192.168.1.107",2); put("192.168.1.108",1); put("192.168.1.109",1); put("192.168.1.110",1); }};
Random
随机,按权重设置随机几率。在一个截面上碰撞的几率高,但调用量越大分布越均匀,并且按几率使用权重后也比较均匀,有利于动态调整提供者权重。
public void random(){ List<String> keyList = new ArrayList<String>(serverMap.keySet()); Random random = new Random(); int idx = random.nextInt(keyList.size()); String server = keyList.get(idx); System.out.println(server); }
WeightRandom
public void weightRandom(){ Set<String> keySet = serverMap.keySet(); List<String> servers = new ArrayList<String>(); for(Iterator<String> it = keySet.iterator();it.hasNext();){ String server = it.next(); int weithgt = serverMap.get(server); for(int i=0;i<weithgt;i++){ servers.add(server); } } String server = null; Random random = new Random(); int idx = random.nextInt(servers.size()); server = servers.get(idx); System.out.println(server); }
轮询(Round Robbin)
当服务器群中各服务器的处理能力相同时,且每笔业务处理量差别不大时,最适合使用这种算法。 轮循,按公约后的权重设置轮循比率。存在慢的提供者累积请求问题,好比:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,长此以往,全部请求都卡在调到第二台上。
private Integer pos = 0; public void roundRobin(){ List<String> keyList = new ArrayList<String>(serverMap.keySet()); String server = null; synchronized (pos){ if(pos > keyList.size()){ pos = 0; } server = keyList.get(pos); pos++; } System.out.println(server); }
加权轮询(Weighted Round Robbin)
为轮询中的每台服务器附加必定权重的算法。好比服务器1权重1,服务器2权重2,服务器3权重3,则顺序为1-2-2-3-3-3-1-2-2-3-3-3- ......
public void weightRoundRobin(){ Set<String> keySet = serverMap.keySet(); List<String> servers = new ArrayList<String>(); for(Iterator<String> it = keySet.iterator();it.hasNext();){ String server = it.next(); int weithgt = serverMap.get(server); for(int i=0;i<weithgt;i++){ servers.add(server); } } String server = null; synchronized (pos){ if(pos > keySet.size()){ pos = 0; } server = servers.get(pos); pos++; } System.out.println(server); }
最少链接(Least Connections)
在多个服务器中,与处理链接数(会话数)最少的服务器进行通讯的算法。即便在每台服务器处理能力各不相同,每笔业务处理量也不相同的状况下,也可以在必定程度上下降服务器的负载。
加权最少链接(Weighted Least Connection)
为最少链接算法中的每台服务器附加权重的算法,该算法事先为每台服务器分配处理链接的数量,并将客户端请求转至链接数最少的服务器上。
普通哈希
public void hash(){ List<String> keyList = new ArrayList<String>(serverMap.keySet()); String remoteIp = "192.168.2.215"; int hashCode = remoteIp.hashCode(); int idx = hashCode % keyList.size(); String server = keyList.get(Math.abs(idx)); System.out.println(server); }
一致性哈希
一致性Hash,相同参数的请求老是发到同一提供者。当某一台提供者挂时,本来发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引发剧烈变更。
经过管理发送方IP和目的地IP地址的散列,未来自同一发送方的分组(或发送至同一目的地的分组)统一转发到相同服务器的算法。当客户端有一系列业务须要处理而必须和一个服务器反复通讯时,该算法可以以流(会话)为单位,保证来自相同客户端的通讯可以一直在同一服务器中进行处理。
经过管理客户端请求URL信息的散列,将发送至相同URL的请求转发至同一服务器的算法。
DNS->数据链路层->IP层->Http层
)延迟
)利用DNS处理域名解析请求的同时进行负载均衡是另外一种经常使用的方案。在DNS服务器中配置多个A记录,如:www.mysite.com IN A 114.100.80.一、www.mysite.com IN A 114.100.80.二、www.mysite.com IN A 114.100.80.3.
每次域名解析请求都会根据负载均衡算法计算一个不一样的IP地址返回,这样A记录中配置的多个服务器就构成一个集群,并能够实现负载均衡。
DNS域名解析负载均衡的优势是将负载均衡工做交给DNS,省略掉了网络管理的麻烦,缺点就是DNS可能缓存A记录,不受网站控制。
事实上,大型网站老是部分使用DNS域名解析,做为第一级负载均衡手段,而后再在内部作第二级负载均衡。
LVS
)数据链路层负载均衡是指在通讯协议的数据链路层修改mac地址进行负载均衡。
这种数据传输方式又称做三角传输模式,负载均衡数据分发过程当中不修改IP地址,只修改目的的mac地址,经过配置真实物理服务器集群全部机器虚拟IP和负载均衡服务器IP地址同样,从而达到负载均衡,这种负载均衡方式又称为直接路由方式(DR).
在上图中,用户请求到达负载均衡服务器后,负载均衡服务器将请求数据的目的mac地址修改成真是WEB服务器的mac地址,并不修改数据包目标IP地址,所以数据能够正常到达目标WEB服务器,该服务器在处理完数据后能够通过网管服务器而不是负载均衡服务器直接到达用户浏览器。
使用三角传输模式的链路层负载均衡是目前大型网站所使用的最广的一种负载均衡手段。在linux平台上最好的链路层负载均衡开源产品是LVS(linux virtual server)。
SNAT
)IP负载均衡:即在网络层经过修改请求目标地址进行负载均衡。
用户请求数据包到达负载均衡服务器后,负载均衡服务器在操做系统内核进行获取网络数据包,根据负载均衡算法计算获得一台真实的WEB服务器地址,而后将数据包的IP地址修改成真实的WEB服务器地址,不须要经过用户进程处理。真实的WEB服务器处理完毕后,相应数据包回到负载均衡服务器,负载均衡服务器再将数据包源地址修改成自身的IP地址发送给用户浏览器。
这里的关键在于真实WEB服务器相应数据包如何返回给负载均衡服务器,一种是负载均衡服务器在修改目的IP地址的同时修改源地址,将数据包源地址改成自身的IP,即源地址转换(SNAT),另外一种方案是将负载均衡服务器同时做为真实物理服务器的网关服务器,这样全部的数据都会到达负载均衡服务器。
IP负载均衡在内核进程完成数据分发,较反向代理均衡有更好的处理性能。但因为全部请求响应的数据包都须要通过负载均衡服务器,所以负载均衡的网卡带宽成为系统的瓶颈。
少见
)HTTP重定向服务器是一台普通的应用服务器,其惟一的功能就是根据用户的HTTP请求计算一台真实的服务器地址,并将真实的服务器地址写入HTTP重定向响应中(响应状态吗302)返回给浏览器,而后浏览器再自动请求真实的服务器。
这种负载均衡方案的优势是比较简单,缺点是浏览器须要每次请求两次服务器才能拿完成一次访问,性能较差;使用HTTP302响应码重定向,多是搜索引擎判断为SEO做弊,下降搜索排名。重定向服务器自身的处理能力有可能成为瓶颈。所以这种方案在实际使用中并不见多。
nginx
)传统代理服务器位于浏览器一端,代理浏览器将HTTP请求发送到互联网上。
而反向代理服务器则位于网站机房一侧,代理网站web服务器接收http请求。
反向代理的做用是保护网站安全,全部互联网的请求都必须通过代理服务器,至关于在web服务器和可能的网络攻击之间创建了一个屏障。
除此以外,代理服务器也能够配置缓存加速web请求。当用户第一次访问静态内容的时候,静态内存就被缓存在反向代理服务器上,这样当其余用户访问该静态内容时,就能够直接从反向代理服务器返回,加速web请求响应速度,减轻web服务器负载压力。
另外,反向代理服务器也能够实现负载均衡的功能。
因为反向代理服务器转发请求在HTTP协议层面,所以也叫应用层负载均衡。优势是部署简单,缺点是可能成功系统的瓶颈。