美文网首页
SpringCloud Hello Ribbon

SpringCloud Hello Ribbon

作者: 灰气球 | 来源:发表于2020-06-08 22:52 被阅读0次

原文来自《重新定义Spring Cloud实战》

负载均衡

负载均衡(LoadBalance),即利用特定方式将流量分摊到多个操作单元上的一种手段,它对系统吞吐量与系统处理能力有着质的提升,毫不夸张地说,当今极少有企业没有用到负载均衡器或是负载均衡策略的。

image-20200606201144472.png
  • 服务端负载均衡(硬负载、集中式负载均衡)[例子:Nginx]
image-20200606201144472.png
  • 客户端负载均衡(软负载、进程内负载均衡)[例子:Ribbon]

Ribbon简介

Ribbon是一个客户端负载均衡器,它赋予了应用一些支配HTTP与TCP行为的能力,可以得知,这里的客户端负载均衡(许多人称之为后端负载均衡)也是进程内负载均衡的一种。它在SpringCloud生态内是一个不可缺少的组件,少了它,服务便不能横向扩展,这显然是有违云原生12要素的。此外,Feign与Zuul中已经默认集成了Ribbon,在我们的服务之间凡是涉及调用的,都可以集成它并应用,从而使我们的调用链具备良好的伸缩性。

Hello World Demo

示例环境

  1. JDK8
  2. Maven

示例简介

  1. 服务1 - 注册中心 eureka服务端
  2. 服务2 - 提供接口功能的eureka客户端
  3. 服务3 - 服务2的调用者 ribbon

编码实现

code

  • 服务1 - 注册中心 eureka服务端

maven依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

代码

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

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

配置文件

server:
  port: 8888
eureka:
  instance:
    hostname: localhost
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  • 服务2 - 提供接口功能的eureka客户端

maven依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

编码

@SpringBootApplication
@EnableDiscoveryClient
public class ClientAApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(ClientAApplication.class, args);
    }
}

@RestController
public class TestController {

    @GetMapping("/add")
    public String add(Integer a, Integer b, HttpServletRequest request){
        return " From Port: "+ request.getServerPort() + ", Result: " + (a + b);
    }
}

配置文件

server:
  port: 7070
spring:
  application:
    name: client-a
eureka:
  client:
    serviceUrl:
      defaultZone: http://${eureka.host:127.0.0.1}:${eureka.port:8888}/eureka/
  instance:
    prefer-ip-address: true
  • 服务3 - 服务2的调用者 ribbon (可以修改端口启动两个服务)

maven依赖

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

编码

@SpringBootApplication
@EnableDiscoveryClient
public class RibbonLoadbalancerApplication {

    public static void main(String[] args) {
        SpringApplication.run(RibbonLoadbalancerApplication.class, args);
    }
    
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

@RestController
public class TestController {
    
    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/add")
    public String add(Integer a, Integer b) {
        String result = restTemplate
                .getForObject("http://CLIENT-A/add?a=" + a + "&b=" + b, String.class);
        System.out.println(result);
        return result;
    }
}

测试验证

  • eureka 服务端站点查看服务注册情况是否正常
image-20200608103018051.png
  • 调用 ribbon 客户端服务
curl -X GET \
  'http://127.0.0.1:7777/add?a=1111&b=2222' \
  -H 'Postman-Token: 08f23b90-de98-4145-9f70-0e50c5caa22a' \
  -H 'cache-control: no-cache'
  • 第一次触发
image-20200608103250031.png
  • 第二次触发
image-20200608103305691.png

实战

Ribbon负载均衡策略与自定义配置

  1. ribbon支持的负载均衡策略

    策略类 命名 描述
    RandomRule 随机策略 随机选择server
    RoundRobinRule(默认) 轮询策略 按顺序循环选择server
    RetryRule 重试策略 在一个配置时间段内,当选择server不成功,则尝试选择一个可用的server
    BestAvailableRule 最低并发策略 逐个考察server,如果server断路器打开,则忽略,再选择其中并发连接最低的server
    AvailabilityFilteringRule 可用过滤策略 过滤掉一直连接失败并被标记为circuit tripped的server,过滤掉哪些高并发连接的server(active connections超过设置的阈值)
    ResponseTimeWeightedRule 响应时间加权策略 根据server的响应时间分配权重。响应时间越长,权重越低,被选择到的概率就越低;响应时间越短,权重越高,被选择到的概率就越高。这个策略很贴切,中和了各种因素,如:网络、磁盘、IO等,这些因素直接影响着响应时间。
    ZoneAvoidanceRule 区域权衡策略 综合判断server所在区域的性能和server的可用性轮询选择server,并且判定一个AWS Zone的运行性能是否可用,剔除不可用的Zone中的所有server
  1. 自定义配置

    • 全局策略设置
    @Configuration
    public class TestConfiguration {
     
     @Bean
     public IRule ribbonRule(IClientConfig config) {
         return new RandomRule();
     }
    }
    
    • 基于注解的策略配置(针对某个源服务进行配置)

      • 方式一 : 在@RibbonClients中配置
 **注意 : 这里使用@ComponentScan注解的意思是让Spring不去扫描被@AvoidScan注解标记的配置类,因为我们的配置是对单个源服务生效的,所以不能应用于全局,如果不排除,启动就会报错。**

 

 ```java
 @SpringBootApplication
 @EnableDiscoveryClient
 @RibbonClients(value = {
        @RibbonClient(name = "client-a", configuration = TestConfiguration.class),
        @RibbonClient(name = "client-b", configuration = TestConfiguration.class)
 })
 public class RibbonLoadbalancerApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(RibbonLoadbalancerApplication.class, args);
     }
     
     @Bean
     @LoadBalanced
     public RestTemplate restTemplate() {
         return new RestTemplate();
     }
 }
 ```



 ```
 @Configuration
 @AvoidScan
 public class TestConfiguration {
    
    @Autowired
     IClientConfig config;
 
    @Bean
    public IRule ribbonRule(IClientConfig config) {
        return new RandomRule();
    }
 }
 ```



 * 方式二

 ```java
 @Configuration
 @AvoidScan
 public class TestConfiguration {
    
    @Autowired
     IClientConfig config;
 
    @Bean
    public IRule ribbonRule(IClientConfig config) {
        return new RandomRule();
    }
 }
 ```

 ```java
 @SpringBootApplication
 @EnableDiscoveryClient
 @RibbonClient(name = "client-a", configuration = TestConfiguration.class)
 @ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = {AvoidScan.class})})
 public class RibbonLoadbalancerApplication {
 
     public static void main(String[] args) {
         SpringApplication.run(RibbonLoadbalancerApplication.class, args);
     }
     
     @Bean
     @LoadBalanced
     public RestTemplate restTemplate() {
         return new RestTemplate();
     }
 }
 ```
  • 基于配置文件的策略配置
clienta.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

Ribbon超时与重试

client-a:
  ribbon:
    ConnectTimeout: 3000
    ReadTimeout: 60000
    MaxAutoRetries: 1 #对第一次请求的服务的重试次数
    MaxAutoRetriesNextServer: 1 #要重试的下一个服务的最大数量(不包括第一个服务)
    OkToRetryOnAllOperations: true

Ribbon的饥饿加载

Ribbon在进行客户端负载均衡的时候并不是在启动时就加载上下文,而是在实际请求的时候才去创建,因此这个特性往往会让我们的第一次调用显得颇为疲软乏力,严重的时候会引起调用超时。所以我们可以通过指定Ribbon具体的客户端的名称来开启饥饿加载,即在启动的时候便加载所有配置项的应用程序上下文。

ribbon:
  eager-load:
    enabled: true
    clients: client-a, client-b, client-c

利用配置文件自定义Ribbon客户端

使用配置文件来指定一些默认加载类,从而更改Ribbon客户端的行为方式,并且使用这种方式优先级最高,优先级高于使用注解@RibbonClient指定的配置和源码中加载的相关Bean。

client:
  ribbon:
    NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule

相关文章

网友评论

      本文标题:SpringCloud Hello Ribbon

      本文链接:https://www.haomeiwen.com/subject/anadtktx.html