相信熟悉过Nginx的都知道,Nginx其中有一个功能是负载均衡。
Nginx的负载均衡里可以配置一个服务器列表,如:
- upstream detecotr_server {
- #ip_hash;
- #这里指定多个源服务器,ip:端口,80端口的话可写可不写
- server 192.168.154.1:8080 weight=1;# max_fails=2 fails_time=2;
- server 192.168.154.2:8088 weight=2;# max_fail2=2 fails_time=2;
- }
当负载均衡策略为加权轮询,如果的3个请求,则会有1个请求分发到192.168.154.1服务器上,2个请求分发到192.168.154.2服务器上。加权轮询的算法实现以下:
Java实现
- public class WeightRoundRobin {
- /**上次选择的服务器*/
- private int currentIndex = -1;
- /**当前调度的权值*/
- private int currentWeight = 0;
- /**最大权重*/
- private int maxWeight;
- /**权重的最大公约数*/
- private int gcdWeight;
- /**服务器数*/
- private int serverCount;
- private List
servers = new ArrayList(); - public int greaterCommonDivisor(int a, int b){
- BigInteger aBig = new BigInteger(String.valueOf(a));
- BigInteger bBig = new BigInteger(String.valueOf(b));
- return aBig.gcd(bBig).intValue();
- }
- public int greatestCommonDivisor(List
servers){ - int divisor = 0;
- for(int index = 0, len = servers.size(); index < len - 1; index++){
- if(index ==0){
- divisor = greaterCommonDivisor(
- servers.get(index).getWeight(), servers.get(index + 1).getWeight());
- }else{
- divisor = greaterCommonDivisor(divisor, servers.get(index).getWeight());
- }
- }
- return divisor;
- }
- public int greatestWeight(List
servers){ - int weight = 0;
- for(Server server : servers){
- if(weight < server.getWeight()){
- weight = server.getWeight();
- }
- }
- return weight;
- }
- /**
- * 算法流程:
- * 假设有一组服务器 S = {S0, S1, …, Sn-1}
- * 有相应的权重,变量currentIndex表示上次选择的服务器
- * 权值currentWeight初始化为0,currentIndex初始化为-1 ,当第一次的时候返回 权值取最大的那个服务器,
- * 通过权重的不断递减 寻找 适合的服务器返回,直到轮询结束,权值返回为0
- */
- public Server getServer(){
- while(true){
- currentIndex = (currentIndex + 1) % serverCount;
- if(currentIndex == 0){
- currentWeight = currentWeight - gcdWeight;
- if(currentWeight <= 0){
- currentWeight = maxWeight;
- if(currentWeight == 0){
- return null;
- }
- }
- }
- if(servers.get(currentIndex).getWeight() >= currentWeight){
- return servers.get(currentIndex);
- }
- }
- }
- public void init(){
- servers.add(new Server("192.168.1.101", 1));
- servers.add(new Server("192.168.1.102", 2));
- servers.add(new Server("192.168.1.103", 3));
- servers.add(new Server("192.168.1.104", 4));
- servers.add(new Server("192.168.1.105", 5));
- maxWeight = greatestWeight(servers);
- gcdWeight = greatestCommonDivisor(servers);
- serverCount = servers.size();
- }
- public static void main(String[] args){
- WeightRoundRobin weightRoundRobin = new WeightRoundRobin();
- weightRoundRobin.init();
- for(int i = 0; i < 15; i++){
- Server server = weightRoundRobin.getServer();
- System.out.println("server " + server.getIp() + " weight=" + server.getWeight());
- }
- }
- }
- class Server{
- private String ip;
- private int weight;
- public Server(String ip, int weight) {
- this.ip = ip;
- this.weight = weight;
- }
- public String getIp() {
- return ip;
- }
- public void setIp(String ip) {
- this.ip = ip;
- }
- public int getWeight() {
- return weight;
- }
- public void setWeight(int weight) {
- this.weight = weight;
- }
- @Override
- public boolean equals(Object obj) {
- if(this == obj) return true;
- if(obj instanceof Server){
- Server server = (Server)obj;
- return getIp().equals(server.getIp());
- }
- return false;
- }
- @Override
- public int hashCode() {
- return getIp().hashCode();
- }
- }
结果:
server 192.168.1.105 weight=5
server 192.168.1.104 weight=4
server 192.168.1.105 weight=5
server 192.168.1.103 weight=3
server 192.168.1.104 weight=4
server 192.168.1.105 weight=5
server 192.168.1.102 weight=2
server 192.168.1.103 weight=3
server 192.168.1.104 weight=4
server 192.168.1.105 weight=5
server 192.168.1.101 weight=1
server 192.168.1.102 weight=2
server 192.168.1.103 weight=3
server 192.168.1.104 weight=4
server 192.168.1.105 weight=5
转