Spring Cloud微服务解决方案③:Ribbon的使用

 

先来一段介绍:

Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。Spring Cloud Ribbon虽然只是一个工具类框架,它不像服务注册中心、配置中心、API网关那样需要独立部署,但是它几乎存在于每一个Spring Cloud构建的微服务和基础设施中。因为微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的,包括后续我们将要介绍的Feign,它也是基于Ribbon实现的工具。所以,对Spring Cloud Ribbon的理解和使用,对于我们使用Spring Cloud来构建微服务非常重要。

实现Ribbon的客户端负载其实很简单,项目地址在我的Spring Cloud微服务解决方案1的文件里面的microservice-consumer-movie-ribbon模块。demo下载地址:https://download.csdn.net/download/qq_22075041/10851487

<!--此依赖已经集成了Ribbon,无需额外-->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

然后再在restTemplate上面加一个@LoadBalanced注解就可以了

  @LoadBalanced
  public RestTemplate restTemplate() {
    return new RestTemplate();
  }

但是有时候 我们客户端负载有很多的方式  比如随机轮训等,这时候我们就需要自定义负载的方案,如下

@Configuration
public class TestConfiguration {
  //  @Autowired
  //  IClientConfig config;

  @Bean
  public IRule ribbonRule() {
    return new RandomRule();//随机
  }
}
//还需要在类上面加一个注解申明一下,下面的microservice-provider-user是注册到eurake一个服务的虚拟IP
@RibbonClient(name = "microservice-provider-user", configuration = TestConfiguration.class)

这里有个警告:就是@Configuration注解不能放在@ComponentScan、@SpringBootApplication包以及子包下。破解办法在下面 我们接着说

microservice-provider-user只是我们一个服务ip,但是我们一个项目可能有很多个服务,但是我又不想让所有的服务随机。那么我们可以这样自定义配置负载。

package com.itmuch.cloud.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.itmuch.cloud.entity.User;

@RestController
public class MovieController {
  @Autowired
  private RestTemplate restTemplate;
  @Autowired
  private LoadBalancerClient loadBalancerClient;//注意这个地方

  @GetMapping("/movie/{id}")
  public User findById(@PathVariable Long id) {
    // http://localhost:7900/simple/
    // VIP virtual IP
    // HAProxy Heartbeat
    return this.restTemplate.getForObject("http://microservice-provider-user/simple/" + id, User.class);
  }

  @GetMapping("/test")
  public String test() {
    //访问测试microservice-provider-user是随机方式
    ServiceInstance serviceInstance = this.loadBalancerClient.choose("microservice-provider-user");
    System.out.println("111" + ":" + serviceInstance.getServiceId() + ":" + serviceInstance.getHost() + ":" + serviceInstance.getPort());
    //访问测试microservice-provider-user2不是随机方式
    ServiceInstance serviceInstance2 = this.loadBalancerClient.choose("microservice-provider-user2");
    System.out.println("222" + ":" + serviceInstance2.getServiceId() + ":" + serviceInstance2.getHost() + ":" + serviceInstance2.getPort());

    return "1";
  }
}

接上面的警告,我就是要放到这个包下面,那我们可以@ComponentScan忽略这个自定义TestConfiguration类,怎么

做呢,我们写一个自定义注解@ExcludeFromComponentScan,加在TestConfiguration类上,然后再启动类上面加上这一句

@ComponentScan(excludeFilters = { @ComponentScan.Filter(type = FilterType.ANNOTATION, value = ExcludeFromComponentScan.class) })

其实对于这种自定义方式的负载均衡还有支持更方便的方式就是写入配置文件当中。、

官方说的优先级是 配置文件方式  > 代码  > 默认

参考的代码模块在microservice-consumer-movie-ribbon-properties-customizing

在配置文件中加入这一行

microservice-provider-user: #服务名
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 随机规则,感兴趣的可以再在这个包路径下自己找负载的更多规则

还没有完,如果我们只要ribbon服务,不要eurake呢?在配置文件这样写(代码参考microservice-consumer-movie-ribbon-without-eureka模块):

ribbon:
  eureka:
   enabled: false #禁用eurake
microservice-provider-user: #服务名
  ribbon:
    listOfServers: localhost:7900 #服务地址,可以是多个

 

 

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页