spring cloud学习笔记(3)-- ribbon和feign

1.ribbon客户端负载均衡介绍及基本使用

负载均衡想必都是比较清除的,在服务器端的负载均衡主要是通过Nginx实现:

那么客户端的负载均衡呢

  1. Ribbon是一个实现了客户端负载均衡的组件,Netflix开源的,其主要功能是提供客户端侧负载均衡
  2. Ribbon客户端组件提供一系列完善的配置项,如连接超时,重试等配置。简单来说,Ribbon是一个客户端负载均衡器,我们可以在配置文件中列出负载均衡后面所有的机器,Ribbon会自动的帮助你基于某种规则(轮询,随机等)去连接这些机器,我们也可以使用自定义Ribbon实现自己的负载均衡算法

Eureka集成Ribbon架构图

那么具体代码实现是怎么样呢 首先需要引入增加Ribbon依赖(代码还是使用我前面的学习笔记的代码,在这就不陈述了)

本来需要引入spring-cloud-starter-netflix-ribbon,但是由于spring-cloud-starter-netflix-eureka-client中,已经包含了ribbon的包了,所以实际上我们不需要显示的引入ribbon的包就可以直接使用它

负载均衡代码

  @Bean
    @LoadBalanced//增加负载均衡的配置
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }

测试:

1,首先起送Eureka的服务端

2.在启动服务提供者microservice-person

3.再启动服务消费者microservice-order

从Eureka的的管理界面可以看到注册的微服务有三个,一个是消费者和两个消费提供者,现在我们测试一下是否访问消费提供者默认是轮询

从效果上我们发现我们的测试服务端的负载均衡是成功的。

使用Ribbon配置类实现指定微服务负载均衡策略(不常用)

  • spring cloud官方文档中是这样说的,如果要自定义Ribbon配置, 则需要把这个配置类放在@SpringBootApplication扫不到的包中(@ComponentScan),因为如果可以扫到自定义的Ribbon配置类的话,那么会对所有的Riboon都生效
  • 配置步骤
  • 独立新建包,并创建ribbon配置类,例如:src.main.java.com.cym.micreoserviceorder.config
package com.cym.micreoserviceorder.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;

/**
 * 该类为Ribbon的配置类
 * 注意:该类不应该在主应用程序上下文的@ComponentScan 中。
 */
@Configuration
public class RibbonConfiguration {
  @Bean
  public IRule ribbonRule() {
    // 负载均衡规则,改为随机
    return new RandomRule();
  }
}
  • 创建一个空类ProviderPersonConfiguration配置服务的ribbon负载均衡策略
package com.cym.micreoserviceorder.start.congfig;

import com.cym.micreoserviceorder.config.RibbonConfiguration;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.Configuration;

/**
 * 使用RibbonClient,为特定name的Ribbon Client自定义配置.
 * 使用@RibbonClient的configuration属性,指定Ribbon的配置类.
 */
@Configuration
@RibbonClient(name = "microservice-provider-user", configuration = RibbonConfiguration.class)
public class ProviderPersonConfiguration {

}

 

测试:

其实在这里我们已经实现多种轮询方式的配置的,我们就是配置了microservice-provider-user这组服务提供类是随机轮询的,我们可以再启动一组服务提供者如microservice-provider-user111

再Eureka的管理界面可以看到已经有两组服务提供者已经注册了

简单说明一下,再开启一组的可以microservice-person 的配置文件中修改端口和spring.application.name=,的参数或者可以通过将微服务打包通过以下指令运行(可以手动指定参数运行)

启动成功后,让我们测试一样MICROSERVICE-PROVIDER-USER111这组的服务提供者的轮询方式。

结果:MICROSERVICE-PROVIDER-USER111 是按1:1轮询的。

MICROSERVICE-PROVIDER-USER是随机轮询的。

使用Ribbon属性配置实现指定微服务负载均衡策略(常用)

其他什么的不用修改,只是修改microservice-order的配置文件就可以了。

#端口的配置
server.port=8081
#Eureka的相关配置
#eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
spring.application.name=microservice-order
eureka.client.serviceUrl.defaultZone=http://cym:123@localhost:8761/eureka
eureka.instance.prefer-ip-address=true
eureka.instance.instance-id=${spring.application.name}:${spring.application.instance_id:${server.port}}

#配置ribbon的轮询方式
microservice-provider-user.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

测试:随机访问

Ribbon配置的优先级:属性配置 > JAVA配置>Netflix Ribbon默认配置

Ribbon内置负载均衡策略介绍

内置策略

规则描述

实现说明

RoundRobinRule

简单轮询服务列表来选择服务器。

轮询index,选择index对应位置的server

AvailabilityFilteringRule

对以下两种服务器进行忽略:

1)在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为短路状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。

注意:可以通过修改配置loadbalancer.<clientName>.connectionFailureCountThreshold来修改连接失败多少次之后被设置为短路状态。默认是3次。

2)并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabilityFilteringRule规则的客户端也会将其忽略。并发连接数的上线,可以由客户端的<clientName>.<clientConfigNameSpace>.ActiveConnectionsLimit属性进行配置。

使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个server的运行状态

WeightedResponseTimeRule

为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择

一个后台线程定期的从status里面读取评价响应时间,为每个server计算一个weightWeight的计算也比较简单responsetime 减去每个server自己平均的responsetimeserver的权重。当刚开始运行,没有形成status时,使用roubine策略选择server

ZoneAvoidanceRule

以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。

使用ZoneAvoidancePredicateAvailabilityPredicate来判断是否选择某个server,前一个判断判定一个zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉连接数过多的Server

BestAvailableRule 忽略哪些短路的服务器,并选择并发数较低的服务器

逐个考察Server,如果Servertripped了,则忽略,在选择其中ActiveRequestsCount最小的server

RandomRule

随机选择一个可用的服务器。

index上随机,选择index对应位置的server

RetryRule

重试机制的选择逻辑

在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server

 

 

 

 

Ribbon脱离Eureka独立使用

到现在为止,我们看到的Ribbon负载均衡后的后端服务地址,是从EurekaServer中获取的可用微服务列表,那么现在如果我不需要使用Eureka,不从Eureka中获取微服务列表,而是Ribbon自己独立配置可用微服务列表,要如何来做呢?

  • 添加Ribbon的依赖
<!-- 引入ribbon -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
  • 订单微服务application配置中增加如下内容(application.yaml)
#配置脱离Eureka的ribbon
microservice-provider-user:
  ribbon:
    listOfServers: localhost:9091,localhost:9090  #这是服务提供者的ip+端口
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

测试:

Feign介绍

  • Feign是一个声明式的http客户端,使用Feign可以实现声明式REST调用。spring cloudFeign整合了Eureka,Ribbon,以提供服务发现及负载均衡等能力,同时整合了SpringMVC注解
  • Feign默认使用SpringMVC注解提供契约来进行REST访问,例如@RequestMapping,@PathVariable
  • 在之前的订单微服务中,调用用户微服务,我们使用的是RestTemplate.getForObject(),  URL是我们自己拼接的字符串。如果参数较多的情况下,这种URL拼接参数的方式很低效,很不方便的。而Feign就解决了这些问题

Feign基本使用

  • 加入Feign依赖,修改POM文件:
<!-- 添加feign的依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
  • 创建一个Feign接口PersonFeignClient,并在接口上面添加注解@FeignClient
package com.cym.micreoserviceorder.feign;

import com.cym.micreoserviceorder.model.Person;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@FeignClient(name = "microservice-provider-user")
public interface PerosnFeignClient {

    @RequestMapping(value = "/person/getPersonById/{id}",method = RequestMethod.GET)
    public Person getPersonById(@PathVariable("id") Integer id);
}
  • 启动类ConsumerOrderApplication增加@EnableFeignClients注解

  • controller
package com.cym.micreoserviceorder.controller;

        import com.cym.micreoserviceorder.feign.PerosnFeignClient;
        import com.cym.micreoserviceorder.model.Person;
        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.core.annotation.Order;
        import org.springframework.http.ResponseEntity;
        import org.springframework.web.bind.annotation.*;
        import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("/order")
public class OrderController {

    private Logger logger = LoggerFactory.getLogger(OrderController.class);

    @Autowired
    private PerosnFeignClient personFeignClient;

    @GetMapping("/person/{id}")
    public Person findById(@PathVariable Integer id) {
        return personFeignClient.getPersonById(id);
    }
}

测试:

调用过程是:先是通过OrderController中的

然后再到PerosnFeignClient

他就是通过@FeignClient(name = "microservice-provider-user")找到找到提供服务的类然后

根据@RequestMapping(value = "/person/getPersonById/{id}",method = RequestMethod.GET)找到类中具体的方法

猜你喜欢

转载自blog.csdn.net/qq_40368860/article/details/84661164