Atitit 数据库 负载均衡 方法总结
目录
5.1. com.netflix.loadbalancer.ILoadBalancer接口实现的。 3
5.1.1. com.netflix.loadbalancer.BaseLoadBalancer 4
5.1.2. DynamicServerListLoadBalancer 4
5.1.3. ZoneAwareLoadBalancer 5
更具userid 选择服务器
根据 读写sql实现选择数据库服务器
一般是驱动已经实现了。也可以使用Ribbon自己实现
6.1. F5 dns lvs Nginx 4
6.2. Ngnix apache dubbo 4
6.3. Springcloud Zuul服务端 负载均衡 4
6.4. 客户端负载均衡Springcloud Ribbon简介 4
6.5. Location指令客户端跳转也可以 4
总结一下:
ILoadBalancer接口实现类做了以下的一些事情:
1.维护了存储服务实例Server对象的二个列表。一个用于存储所有服务实例的清单,一个用于存储正常服务的实例清单
2.初始化得到可用的服务列表,启动定时任务去实时的检测服务列表中的服务的可用性,并且间断性的去更新服务列表,结合注册中心。
3.选择可用的服务进行调用(这个一般交给IRule去实现,不同的轮询策略)
三个很重要的概念
- ServerList接口:定义用于获取服务器列表的方法的接口,主要实现DomainExtractingServerList接口,每隔30s种执行getUpdatedListOfServers方法进行服务列表的更新。
- ServerListUpdater接口:主要实现类EurekaNotificationServerListUpdater和PollingServerListUpdater(默认使用的是PollingServerListUpdater,结合Eureka注册中心,定时任务的方式进行服务列表的更新)
- ServerListFilter接口:根据LoadBalancerStats然后根据一些规则去过滤部分服务,比如根据zone(区域感知)去过滤。(主要实现类ZonePreferenceServerListFilter的getFilteredListOfServers会在更新服务列表的时候去执行)。
com.netflix.loadbalancer.BaseLoadBalancer类是Ribbon负载均衡器的基础实现类,在该类中定义了很多关于负载均衡器相关的基础内容。
定义并维护了两种存储服务实例Server对象的列表。一个用于存储所有服务实例的清单,一个用于存储正常服务的实例清单。
负载均衡的处理原则IRule对象,从BaseLoadBalancer中chooseServer(Object key)的实现源码可以知道,负载均衡器实际将服务实例选择的任务委托给IRule实例中的choose函数来实现。
默认初始化了RoundRobinRule实现,RoundRobinRule实现了最基本且常用的线性负载均衡规则。
getReachableServers():获取可用的服务实例列表。由于BaseLoadBalancer中单独维护了一个正常服务的实例清单,所以直接返回即可
@Overridepublic List<Server> getReachableServers() {
return Collections.unmodifiableList(upServerList);}
getAllServers():获取所有的服务实例列表。由于BaseLoadBalancer中单独维护了一个正常服务的实例清单,所以直接返回即可。
com.netflix.loadbalancer.DynamicServerListLoadBalancer类继承com.netflix.loadbalancer.BaseLoadBalancer类,它是对基础负载均衡器的扩展。
该负载均衡器中,实现了服务实例清单在运行期的动态更新能力;同时,它还具备了对服务实例清单的过滤功能,也就是说,我们可以通过过滤器来选择性的获取一批服务实例清单。
ZoneAffinityServerListFilter:该过滤器基于"区域感知(Zone Affinity)"的方式实现服务实例的过滤,也就说,它会根据提供服务的实例所处于的区域(Zone)与消费者自身所处区域(Zone)进行比较,过滤掉那些不是同处一个区域的实例
ZoneAwareLoadBalancer负载均衡器是对DynamicServerListLoadBalancer的扩展。在DynamicServerListLoadBalancer中,我们可以看到它并没有重写选择具体服务实例的chooseServer函数,所以它依然会采用在BaseLoadBalancer中实现的算法。使用RoundRobinRule规则,以线性轮询的方式来选择调用的服务实例,该算法实现简单并没有区域(Zone)的概念,所以它会把所有实例视为一个Zone下的节点来看待,这样就会周期性的跨区域(Zone)访问的情况,由于跨区域会产生更高的延迟,这些实例主要以防止区域性故障实现高可用为目的而不能作为常规访问的实例,所以在多区域部署的情况会出现一定的性能问题,而该负载均衡器则可以规避这样的问题。
spring cloud ribbon学习三:负载均衡器ILoadBalancer接口及其实现 - 简书
import java.util.ArrayList;
import java.util.List;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.DynamicServerListLoadBalancer;
import com.netflix.loadbalancer.RandomRule;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
public class LoadBalanceTest {
public class KeyServerRule extends AbstractLoadBalancerRule{
@Override
public Server choose(Object key) {
List<Server> allServerList =this.getLoadBalancer().getAllServers();
for (Server server : allServerList) {
// System.out.println(server.getZone());
if (server.getZone().toString().toLowerCase().equals(key.toString().toLowerCase()))
return server;
}
return null;
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
// TODO Auto-generated method stub
}
}
public static void main(String[] args) {
// extracted();
// 带key的实现机制
//LoadbalanceImp blb = new LoadBalanceTest().new LoadbalanceImp();
// DynamicServerListLoadBalancer blb=new DynamicServerListLoadBalancer();
BaseLoadBalancer blb=new BaseLoadBalancer();
Server svr1 = new Server("svr1");
svr1.setZone("key1");
Server svr2 = new Server("svr2");
svr2.setZone("key2");
List li = new ArrayList<>();
li.add(svr2);
li.add(svr1);
blb.addServer(svr1);
blb.addServer(svr2);
blb.setRule( new LoadBalanceTest(). new KeyServerRule());
// blb.addServers(li);
// System.out.println(blb.choose("key1"));
System.out.println(blb.getAllServers());
System.out.println(blb.chooseServer("key1"));
}
private static void extracted() {
BaseLoadBalancer blb = new BaseLoadBalancer();
blb.addServer(new Server("host0", 80));
blb.addServer(new Server("host1", 81));
blb.addServer(new Server("host2", 82));
blb.setRule(new RandomRule());
System.out.println(blb.chooseServer() + " ");
;
}