SpringCloud入门(2)Ribbon

Ribbon是客户端的负载均衡器,消费者能够经过服务别名调用服务时,须要Ribbon作负载均衡来以某种机制访问实际的服务调用地址。java

简单类比,咱们去找Tony老师,通常理发店都会有多个Tony老师。可是也会有一个相似前台的工做人员为咱们安排有空的Tony老师理发。工做人员就是相似Ribbon,是按照顺序安排呢,仍是随机安排呢。算法

Ribbon + Eureka

建立项目

一样建立一个Ribbon的空模块,而后在Ribbon空模块下建立一个ribbon-consume9101 子模块。在父类也就是空模块的pom文件中加入依赖spring

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>
</dependencies>

当你引入了Eureka相关的依赖的时候其实就已经把Ribbon的依赖引入进来了,因此若是使用的是Ribbon + Eureka,能够不用写上面的依赖也能运行。服务器

建立完成后总体的项目结构如图所示app

配置文件

application.yml负载均衡

server:
  port: 9101

spring:
  application:
    name: ribbon-consume
eureka:
  client:
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaultZone: http://localhost:8001/eureka/
  instance:
    instance-id: ribbon-consume9101

启动和业务类

注意咱们的服务的提供者是eureka-provide 服务,这个服务名字可能单取provide 更准确点,之后项目重构的时候可能会修改。dom

涉及到服务与服务之间的调用,通常会选择使用RestTemplate ,同时须要把它注入Spring容器中,因此选择使用配置类ide

@Configuration
public class ApplicationContextConfig {

    @Bean
    @LoadBalanced       //负载均衡须要的注解
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

接下来就是主启动类测试

@SpringBootApplication
@EnableEurekaClient
@RestController
public class RibbonConsume9101 {
    final String PROVIDE_URL = "http://eureka-provide";

    RestTemplate restTemplate;

    public RibbonConsume9101(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @GetMapping("/ribbon/consume")
    public String getInfo() {
        return "i am consumer, but actually invoke other service: [" + restTemplate.getForObject(PROVIDE_URL + "/eureka/provide", String.class) + "]";
    }

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

测试

  1. 开启Eureak注册中心EurekaServer8001
  2. 开启3个不一样端口的服务提供者EurekaProvide7001EurekaProvide7002 , EurekaProvide7003
  3. 开启刚刚创建的Ribbon消费者RibbonConsume9101

首先看下Eureka注册中心,能够看到3个服务提供者,1个消费者都已经注册到Eureka。fetch

接着消费端访问接口轮询,也是默认规则)。>http://localhost:9101/ribbon/...

自定义配置类

上述调用服务的时候明显是轮询的方式,那若是想要其它方式去调用呢,这时候就须要自定义配置类。

Ribbon主要有6个组件

  • ServerList: 定义获取服务器列表
  • ServerListFilter: 对ServerList列表进行二次过滤
  • ServerListUpdater: 定义服务更新策略
  • Iping: 检查服务列表是否存活
  • IRlue: 根据算法选择调用服务列表中的某一个服务
  • ILoadBalancer: 软件负载均衡器入口,整合以上全部的组件实现负载功能
@Configuration
public class RibbonCustomConfig {
    @Bean
   public IRule ribbonRule() {
       return new RandomRule();
   }
}

IRlue 接口就是以什么样的规则调用服务提供者,能够看下该接口的实现类

怎么让这个配置文件被Ribbon感知到呢,就须要利用@RibbonClient 注解。创建一个空的注解类,加上注解和配置类就可以自定义Ribbon配置。

@Configuration
@RibbonClient(name = "eureka-provide", configuration = RibbonCustomConfig.class)
public class RibbonConfig {
}

这里的名字就是咱们须要调用的服务端的配置文件中的springcloud.application.name 的值。须要注意的是,在官方文档里面有这样一段话

在这个例子中翻译过来就是RibbonCustomConfig 若是和主启动类在同一个包下,就会被扫描进Spring中,这样会致使配置文件会被全部的@RibbonClients 所共享。固然也能够用@ComponentScan 把配置文件排除在外。

重启RibbonConsume9101 服务,其它的不用动,一样调用消费端访问接口http://localhost:9101/ribbon/...

点的时候,啥,怎么一直调用的是7001端口,难道其它服务挂掉了,能够看到后面明显加快了点的速度,最后还好没有翻车,确实是改为了随机规则。

自定义配置文件

除了经过配置类来自定义Ribbon外,还能够经过配置文件来自定义

这里clientName 一样是须要调用的服务端的配置文件中的springcloud.application.name 的值。 若是是彻底本身写的类呢,须要实现对应的接口,这里一样采用Netflix写好的RandomRule 类。

RibbonCustomConfigRibbonConfig删掉或者所有注释掉均可以,修改配置文件

server:
  port: 9101

spring:
  application:
    name: ribbon-consume
eureka:
  client:
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaultZone: http://localhost:8001/eureka/
  instance:
    instance-id: ribbon-consume9101

#其实就是加了下面的内容
eureka-provide:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

其中eureka-provide 就是clientName。接着同样重启RibbonConsume9101 服务,其它的不用动,一样调用消费端访问接口http://localhost:9101/ribbon/...

值得注意的是,在配置文件中配置的变量是要比配置类中的优先级要高的。

Ribbon

上面是消费者端和服务端都注册进了Eureka,至关于消费者经过Eureka去找到了其它服务提供者的服务。那在真正业务中接受了新的消费者端,并无注册进Eureka,怎么解决这个问题呢?

先来看看没有注册进去会发生什么状况,想都不用想确定是直接报错了

建立项目

一样在Ribbon父模块下面创建一个子模块

配置文件

由于不用注册进Eureka,因此配置文件也要作相应的修改

server:
  port: 9102

spring:
  application:
    name: ribbon-consume-without-eureka

#禁用掉Eureka,其实禁用不由用都不影响,由于根本就没导入
ribbon:
  eureka:
    enabled: false

启动和业务类

一样须要导入RestTemplate 因此能够直接复制上一个子模块

@Configuration
public class ApplicationContextConfig {

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

主启动类也能够直接复制,不须要用到Eureka,去掉@EnableEurekaClient 注解并修改类名便可

@SpringBootApplication
@RestController
public class RibbonConsumeWithoutEureka9102 {
    final String PROVIDE_URL = "http://eureka-provide";

    RestTemplate restTemplate;
    
    public RibbonConsumeWithoutEureka9102(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @GetMapping("/ribbon/consume")
    public String getInfo() {
        return "i am consumer, but actually invoke other service: [" + restTemplate.getForObject(PROVIDE_URL + "/eureka/provide", String.class) + "]";
    }

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

那怎样消费者调用的时候怎么知道去哪找提供者的服务呢,就须要动配置文件了

server:
  port: 9102

spring:
  application:
    name: ribbon-consume-without-eureka
ribbon:
  eureka:
    enabled: false

#如下为增长内容
eureka-provide:
  ribbon:
    listOfServers: localhost:7001, localhost:7002, localhost:7003

其中eureka-provide 就是须要调用的服务端的配置文件中的springcloud.application.name 的值

开启RibbonConsume9102 服务,其它的不用动,调用消费端访问接口http://localhost:9102/ribbon/... ,能够看到也是可以按照默认轮询的方式调用服务。

创做不易,若是对你有帮助,欢迎点赞,收藏和分享啦!

下面是我的公众号,有兴趣的能够关注一下,说不定就是你的宝藏公众号哦,基本2,3天1更技术文章!!!

相关文章
相关标签/搜索