负载均衡(LoadBalance),它的职责是将网络请求,或者其余形式的负载“均摊”到不一样的机器上。避免集群中部分服务器压力过大,而另外一些服务器比较空闲的状况。经过负载均衡,可让每台服务器获取到适合本身处理能力的请求。服务器
常见的负载均衡的实现方法有多种,如随机、轮询、hash一致性等。本文使用随机法实现负载均衡。网络
随机数法就是几个数中随机获取一个数字,而后获取这个数据对应的服务器。负载均衡
/** * 服务器类 */ public class Server { private String serverName; public Server(String name) { this.serverName = name; } public String getServerName() { return serverName; } public void setServerName(String serverName) { this.serverName = serverName; } @Override public String toString() { return "Server{serverName:"+this.getServerName()+"}"; } }
public class LoadBalance_Random { //用来存放全部的服务器 static List<Server> ServerList = new ArrayList<Server>(); //随机数生成器 private static final Random r = new Random(); //初始化 模拟集群中提供服务的服务器 static{ Server server1 = new Server("server1"); Server server2 = new Server("server2"); Server server3 = new Server("server3"); ServerList.add(server1); ServerList.add(server2); ServerList.add(server3); } public static void main(String[] args) { //模拟10个请求来获取对应的服务器 for(int i=0;i<10;i++){ Server server_random = doSelect(ServerList); System.out.println(server_random); } } /** * 选择服务器 * @param serverList * @return */ private static Server doSelect(List<Server> serverList) { Server server = null; //服务器的个数 int serverNum = serverList.size(); //随机获取一个 int serverIndex = r.nextInt(serverNum); server = serverList.get(serverIndex); return server; } }
执行main方法测试,结果以下:dom
在每台服务器的配置性能等各方面都同样时,使用这种随机方法也是可取的,由于每台服务器获取的要处理的请求的数据量的几率是同样的。可是有时候,咱们的服务器不必定都是相同的配置,每一台服务器的性能都有必定的差别性,致使服务器提供服务的能力的差别,好比上边咱们有3台服务器,Server1每秒可处理5个请求,Server2每秒只能处理3个请求,Server3每秒只能处理2个请求,此时若是咱们有10个请求过来了,咱们分别给3个Server3个请求处理,因为Server3只能处理2个请求,这时就会致使服务3不可用。ide
对这种不一样服务能力的服务实现负载均衡,咱们可使用加权随机法。对每一个服务标记权重,提升处理能力强的服务器的权重,下降服务能力若的服务器的权重,即根据能力的大小分配对应比例的请求数。性能
修改上述代码,给服务加权重测试
/** * 服务器类 */ public class Server { private String serverName; private int weight;//权重 public Server(String name, int weight) { this.serverName = name; this.weight = weight; } @Override public String toString() { return "Server{serverName:"+this.getServerName()+",weight:"+this.getWeight()+"}"; } // 省略getter 和 setter方法 }
初始化时指定服务器的权重this
//初始化 模拟集群中提供服务的服务器 static{ Server server1 = new Server("server1", 5); Server server2 = new Server("server2", 3); Server server3 = new Server("server3", 2); ServerList.add(server1); ServerList.add(server2); ServerList.add(server3); }
根据权重值获取服务code
private static Server doSelectWithWeight(List<Server> serverList) { Server server = null; int totalWeight = 0; //全部服务器的总权重 boolean isSame = true;//默认全部服务器的权重都相同 for(int i=0; i<serverList.size(); i++){ //获取当前服务器得权重 int serverWeight = serverList.get(i).getWeight(); //权重累加 totalWeight = totalWeight + serverWeight; //i = 0时默认仍是权重都同样 //从第二个开始检测每一个服务器得权重是否是都同样,只须要与它得前一个服务得权重相比就能够了 if(isSame && i>0){ int preServerWeight = serverList.get(i-1).getWeight(); if(serverWeight != preServerWeight){//当前服务器权重和前一个服务器得权重不相同 isSame = false; } } } if(!isSame){//服务器得权重不是都同样 //在总权重下获取一个随机数 int index = r.nextInt(totalWeight); // for(int i=0;i<serverList.size();i++){ int serverWeight = serverList.get(i).getWeight(); //判断获取得随机数落在总权重得哪个区间 //3台服务器得得权重分别为5 3 2 总和为10 [0到5)这个区间属于服务器1 [5到8)这个区间属于服务器2 【8到10)这个区间属于服务器3 //如 获取到得随机数是6 6-5=1 大于0 说明不在服务器1得区间,遍历 1-3= -2 小于0 说明它落在了服务器2所在得区间 就能够得对应服务器 index = index - serverWeight; if(index < 0){ return serverList.get(i); } } }else{ //全部服务器权重都同样时,按照彻底随机法随机获取一个服务器 server = doSelect(serverList); } return server; }
使用main方法测试server
public static void main(String[] args) { //模拟20个请求获取对应的服务 for(int i=0;i<20;i++){ Server server_random_weight = doSelectWithWeight(ServerList); System.out.println(server_random_weight); } }
测试结果以下
从测试结果图中能够看到,权重大的获取到的请求数多,相反权重小的获取到的请求数越小。