Ribbon负载均衡(三)

1.Ribbon配置初步

 servicecloud-consumer-dept-80工程 修改pom.xml文件

<!-- Ribbon相关 -->
<!—springboot2.0—>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>



修改application.yml   追加eureka的服务注册地址

eureka: 
   client: 
     register-with-eureka:   false 
     service-url:   
       defaultZone:  http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/ 

对ConfigBean进行新注解@LoadBalanced    获得Rest时加入Ribbon的配置

package com.goolecloud.springcoud.cfgBean;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration

public class ConfigBen {
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

主启动类ServicecloudConsumerDept80Application添加@EnableEurekaClient

修改DeptController_Consumer客户端访问类

将private static  final String REST_URL_PREFIX =  "http://localhost:8001" ;改为
private static  final String REST_URL_PREFIX =  "http://SERVICECLOUD-DEPT" ;SERVICECLOUD-DEPT 为服务名称

先启动3个eureka集群后,再启动servicecloud-provider-dept-8001并注册进eureka

启动servicecloud-consumer-dept-80

启动microservicecloud-consumer-dept-80

测试

http://localhost/consumer/dept/get/1

http://localhost/consumer/dept/list

http://localhost/consumer/dept/add?dname=大数据部

2.Ribbon负载均衡

参考servicecloud-provider-dept-8001,新建两份,分别命名为8002,8003

新建8002/8003数据库,各自微服务分别连各自的数据库(

 
DROP  DATABASE IF  EXISTS  cloudDB02; 
  
CREATE  DATABASE cloudDB02  CHARACTER   SET  UTF8; 


USE cloudDB02; 


CREATE   TABLE  dept 
( 
  deptno BIGINT  NOT   NULL   PRIMARY   KEY  AUTO_INCREMENT, 
  dname  VARCHAR (60), 
  db_source    VARCHAR (60) 
); 
  
INSERT   INTO  dept(dname,db_source)  VALUES ( '开发部' ,DATABASE()); 
INSERT   INTO  dept(dname,db_source)  VALUES ( '人事部' ,DATABASE()); 
INSERT   INTO  dept(dname,db_source)  VALUES ( '财务部' ,DATABASE()); 
INSERT   INTO  dept(dname,db_source)  VALUES ( '市场部' ,DATABASE()); 
INSERT   INTO  dept(dname,db_source)  VALUES ( '运维部' ,DATABASE()); 
  
SELECT  *  FROM  dept; 
 
DROP  DATABASE IF  EXISTS  cloudDB03; 


CREATE  DATABASE cloudDB03  CHARACTER   SET  UTF8; 


USE cloudDB03; 




CREATE   TABLE  dept 
( 
  deptno BIGINT  NOT   NULL   PRIMARY   KEY  AUTO_INCREMENT, 
  dname  VARCHAR (60), 
  db_source    VARCHAR (60) 
); 


INSERT   INTO  dept(dname,db_source)  VALUES ( '开发部' ,DATABASE()); 
INSERT   INTO  dept(dname,db_source)  VALUES ( '人事部' ,DATABASE()); 
INSERT   INTO  dept(dname,db_source)  VALUES ( '财务部' ,DATABASE()); 
INSERT   INTO  dept(dname,db_source)  VALUES ( '市场部' ,DATABASE()); 
INSERT   INTO  dept(dname,db_source)  VALUES ( '运维部' ,DATABASE()); 


SELECT  *  FROM  dept; 

)

启动servicecloud-consumer-dept-80

客户端通过Ribbo完成负载均衡并访问上一步的Dept微服务

http://localhost/consumer/dept/list

注意观察看到返回的数据库名字,各不相同,负载均衡实现

3.Ribbon核心组件IRule

IRule:根据特定算法中从服务列表中选取一个要访问的服务

RoundRobinRule

轮询

RandomRule

随机

AvailabilityFilteringRule

会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,

还有并发的连接数量超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问

WeightedResponseTimeRule

根据平均响应时间计算所有服务的权重,响应时间越快服务权重越大被选中的概率越高。

刚启动时如果统计信息不足,则使用RoundRobinRule策略,等统计信息足够,

会切换到WeightedResponseTimeRule

RetryRule

先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用的服务

BestAvailableRule

会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务

ZoneAvoidanceRule

默认规则,复合判断server所在区域的性能和server的可用性选择服务器

 
  
  

 

4.Ribbon自定义

修改servicecloud-consumer-dept-80

主启动类添加@RibbonClient

在启动该微服务的时候就能去加载我们的自定义Ribbon配置类,从而使配置生效,形如: 
 
@RibbonClient (name= "MICROSERVICECLOUD-DEPT" ,configuration=MySelfRule. class ) 
 //MySelfRule自定义

官方文档明确给出了警告: 

这个自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下, 

否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,也就是说 

我们达不到特殊化定制的目的了。 

新建package com.goolecloud.myrule

新建自定义Robbin规则类

package com.goolecloud.myrule;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class myIRule {
    @Bean
    public IRule getIRbule(){
 return   new  RandomRule(); //Ribbon默认是轮询,我自定义为随机 
        //return new myIRuble_DY();
    }
}

启动类:

package com.goolecloud.springcoud;

import com.goolecloud.myrule.myIRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;

@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "SERVICECLOUD-DEPT",configuration = myIRule.class)
public class ServicecloudConsumerDept80Application {

    public static void main(String[] args) {
        SpringApplication.run(ServicecloudConsumerDept80Application.class, args);
    }

}

测试

http://localhost/consumer/dept/list

问题:依旧轮询策略,但是加上新需求,每个服务器要求被调用5次。也即

以前是每台机器一次,现在是每台机器5次

参考源码修改为我们需求要求的RandomRule_ZY.java

package com.goolecloud.myrule;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;


import java.util.List;


public class myIRuble_DY extends AbstractLoadBalancerRule {
    private int total=0;
    private int indexcount=0;
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        }
        Server server = null;

        while (server == null) {
            if (Thread.interrupted()) {
                return null;
            }
            List<Server> upList = lb.getReachableServers();
            List<Server> allList = lb.getAllServers();

            int serverCount = allList.size();
            if (serverCount == 0) {

                return null;
            }

            //int index = chooseRandomInt(serverCount);
            //server = upList.get(index);
            if (total<5){
                server=upList.get(indexcount);
                total++;
            }else {
                total=0;
                indexcount++;
                if (indexcount>=upList.size()){
                    indexcount=0;
                }
            }
            if (server == null) {

                Thread.yield();
                continue;
            }

            if (server.isAlive()) {
                return (server);
            }

            // Shouldn't actually happen.. but must be transient or a bug.
            server = null;
            Thread.yield();
        }

        return server;

    }

    @Override
    public Server choose(Object key) {
        return choose(getLoadBalancer(), key);
    }

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }
}
package com.goolecloud.myrule;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class myIRule {
    @Bean
    public IRule getIRbule(){

        return new myIRuble_DY();
    }
}

 

测试:http://localhost/consumer/dept/list

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值