微服务架构--SpringCloud(5)

                                        *Ribbon

 

  *Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具。前端

  *简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务链接在一块儿。Ribbon客户端组件提供一系列完善的配置项如:链接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面全部的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机链接等)去链接这些机器。咱们也很容易使用Ribbon实现自定义的负载均衡算法。java

 

*LB(负载均衡)git

    *在微服务或分布式集群中常常使用的一种应用。github

    *负载均衡简单的说就是将用户的请求平摊的分配到多个服务商,从而达到系统的HA(高可用)算法

    *常见的负载均衡有软件Nginx,LVS,硬件F5等spring

    *相应的在中间件,例如:dubbo和SpringCloud中君给咱们提供了负载均衡,SpringCloud的负载均衡算法能够自定义数据库

    *集中式LB 偏硬件服务器

        *即在服务的消费方和提供方之间使用独立的LB设施(可使硬件,如F5,也能够是软件,如Nginx),由该设施负责把访问请求经过某种策略转发至服务的提供方;(F5很强大,可是贵)负载均衡

    *进程内LB 偏软件dom

        *将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,而后本身再从这些地址中选择一个合适发服务器。

        *Ribbon就属于进程内LB,它只是一个类库,集成与消费方进程,消费方经过它来获取到服务提供方的地址。

 

*Ribbon初步配置

 

**修改pom.xml 添加依赖

<!-- Ribbon相关 -->

<!-- Ribbon要与Eureka整合 -->

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-eureka</artifactId>

</dependency>

 

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-ribbon</artifactId>

</dependency>

<!-- 与Eureka有关 Eureka与Ribbon有关 -->

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-config</artifactId>

</dependency>

1.修改消费者yml配置文件

server:

port: 80

eureka:

client:

register-with-eureka: false

service-url:

defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

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

@Configuration

public class ConfigBean {

 

@Bean

@LoadBalanced //Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具。

public RestTemplate getRestTemplate(){

return new RestTemplate();

}

//选择其余算法

@Bean

public IRule myRule(){

//用咱们从新选择的随机算法覆盖默认的轮询

return new RandomRule();

}

 

}

3.修改启动类

name为服务名 configuration 读取配置MySelfRule类 可暂时不配 自定义算法所用 下面配置

@RibbonClient(name = "MICROSERVICECLOUD-DEPT",configuration = MySelfRule.class)

 

4.修改DeptController_Consumer 直接用服务名字

*完成真正的经过微服务名字从Eureka上找到并访问

private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT";

 

5.启动测试

 

*小结:Ribbon和Eureka整合后Consumer能够直接调用服务而不用再关心地址和端口号

 

 

1.*建立项目microservicecloud-provider-dept-8002

*建立项目microservicecloud-provider-dept-8003

2.修改yml配置,建立新的数据库cloudDB0二、cloudDB03

*复制粘贴8001,修改部分配置,端口,url等

3.简单测试 02,03

4.启动80,Ribbon默认轮询复杂均衡算法

 

 

*Ribbon在工做时分红两步

     *选择EurekaServer,优先选择在用一个区域内负载较少的Server

     *根据用户指定的策略,在从Server取到的服务注册列表中选择一个地址;不指定则轮询

 

*Ribbon就是一个负载均衡的客户端组件,能够和其余所需请求的客户端结合使用,和Eureka结合只是其中的一个实例

 

*Ribbon核心组件:IRule

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

 

*七种负载均衡算法

 

*自定义Ribbon

 

*在启动该微服务的时候就能去加载咱们的自定义Ribbon配置类,从而使配置生效,形如:

@RibbonClient(name = "MICROSERVICECLOUD-DEPT",configuration = MySelfRule.class)

*建立MySelfRule类 自定义算法:每一个服务器要求被调用五次

@Configuration

public class MySelfRule {

@Bean

public IRule myRule(){

// return new RandomRule();//Ribbon默认是轮询,自定义为随机

//指向自定义的算法类RandomRule_***

return new RandomRule_***();

}

}

*建立RandomRule_***

*源码地址:

 https://github.com/Netflix/ribbon/blob/master/ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/RandomRule.java

 

import java.util.List;

 

public class RandomRule_*** extends AbstractLoadBalancerRule{

 

//total = 0 //当前total==5之后,咱们指针才能往下走

//index = 0 //当前对外提供服务的服务器地址,

//total须要从新置为零,可是已经达到过一次5,index= 1

//分析:咱们定义5次,可是微服务只有8001,8002,8003三台

//index<=3

 

private int total = 0; //总共被调用的次数,目前要求每台被调用5次

private int currentIndex = 0; //当前提供服务的机器号

//是netflix.loadbalancer的service包

public Server choose(ILoadBalancer lb , Object key) {

if(lb == null){

return null;

}

//设置初始服务端口为null

Server server = null;

//while循环判断

while (server == null){

//若是线程中断 则返回null

if(Thread.interrupted()){

return null;

}

//获取可用端口

List<Server> uplist = lb.getReachableServers();

//获取所有端口

List<Server> allList = lb.getAllServers();

//获取当前端口数量

int serverCount = allList.size();

//若是为0 则返回null

if(serverCount == 0){

return null;

}

 

// private int total = 0; //总共被调用的次数,目前要求每台被调用5次

// private int currentIndex = 0; //当前提供服务的机器号

//自定义算法

//若是被调用次数小于5

if(total < 5){

//第一次 total < 5 0号机被调用

server = uplist.get(currentIndex);

total++;

}else{ //调用次数>=5

//初始化total调用次数

total = 0;

//当前提供服务的机器号++

currentIndex++;

//服务器号是否大于机器总数量

if(currentIndex >= uplist.size()){

//当服务器号>服务总台数 重置为0

currentIndex = 0;

}

}

//server为空

if(server == null){

//停掉走下一次

Thread.yield();

continue;

}

//server还活着

if(server.isAlive()){

//返回当前server

return (server);

}

//走完上面程序若是还没不返回server,就返回null 并

server = null;

//使当前线程从执行状态(运行状态)变为可执行态(就绪状态)

Thread.yield();

 

}

return server;

}

 

@Override

public Server choose(Object key) {

//调用choose

return choose(getLoadBalancer(),key);

}

 

@Override

public void initWithNiwsConfig(IClientConfig iClientConfig) {

 

}

}

 

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

*这个自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下,不然咱们自定义的这个配置类就会被全部的Ribbon客户端所共享,也就是说咱们达不到特殊化制定的目的了。

 

*而@SpringBootApplication 就包含了@ComponentScan注解,因此,不能在主启动类下的包内建立