Feign概述

  1. 前面的可以发现当我们通过RestTemplate调用其它服务的API时,所需要的参数须在请求的URL中进行拼接,如果参数少的话或许我们还可以忍受,一旦有多个参数的话,这时拼接请求字符串就会效率低下,并且显得好傻。
  2. Feign是一个声明式的Web Service客户端,它的**目的就是让Web Service调用更加简单**。Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。而Feign则会完全代理HTTP请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。Feign整合了RibbonSentinel(关于Sentinel我们后面再讲),可以让我们不再需要显式地使用这两个组件

Feign具有如下特性:

  1. 可插拔的注解支持,包括Feign注解和JAX-RS注解;
  2. 支持可插拔的HTTP编码器和解码器;
  3. 支持Sentinel和它的Fallback;
  4. 支持Ribbon的负载均衡;
  5. 支持HTTP请求和响应的压缩;

     这看起来有点像我们springmvc模式的Controller层的RequestMapping映射。这种模式是我们非常喜欢的。Feign是用@FeignClient来映射服务的。
    

Feign是以接口方式进行调用,而不是通过RestTemplate来调用,feign底层还是ribbon,它进行了封装,让我们调用起来更加happy.总结,就是feign通过一个本地对服务接口的代理,进行对注册到注册中心的服务调用,对于调用者来说,就像调用本地接口一样。

Feign的操作

  1. 导包

    <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
  2. feign接口编写

    @FeignClient(name = "接口对应需要调用的服务名")
    public interface UserFeignClient {
    
             @GetMapping("/getUser")
             public String getUserByNewsId(@RequestParam(required = false) Integer nid);
    
             @GetMapping("/test1")
             public String test1(@RequestParam("p1") String p1, @RequestParam("p2") Integer p2);
    
             @GetMapping("/query")
             public List<UserDto> query(@SpringQueryMap/*表单参数注解*/ UserDto user);
    
             @PostMapping("/queryJson")
             public UserDto queryJson(@RequestBody UserDto user);
    
             @GetMapping("/list")
             public List<UserDto> list();
    
             @GetMapping("/getById/{id}")
             public UserDto getById(@PathVariable Integer id);
    }
    
  3. 调用 ```java @Autowired private UserFeignClient userFeignClient;

UserDto user = userFeignClient.getById(1);

  4.启动类
```java
@SpringBootApplication
@MapperScan("com.woniuxy.mapper")
@EnableFeignClients(basePackages = "com.woniuxy.client")
public class ProductServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductServerApplication.class, args);
    }

}

Feign的配置

Java配置

  1. 编写配置类

    @Configuration
    public class FeignConfig {    
         //Feign的日志级别配置
         @Bean
         public Level createLevel() {
             return Level.FULL;
         }
    }
    
  2. 在主配置类指定

    @FeignClient(configuration = FeignConfig.class)
    public class BaseConfig {}
    

    3、传递token

    @Configuration
    public class FeignConfiguration implements RequestInterceptor {
     @Override
     public void apply(RequestTemplate requestTemplate) {
         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
         String token = request.getHeader("token");
         if (!StringUtils.isEmpty(token)) {
             // header添加token
             requestTemplate.header("token", token);
         }
    
     }
    }
    

属性配置

feign:
  client:
     config:
       default: #这里可以换成服务名进行局部配置
         logger-level: full 
  httpclient:
    enabled: true                 #开启httpclient连接池配置   
    max-connections: 200          #最大连接数
    max-connections-per-route: 50 #最大的路由数量
    connection-timeout: 200000    #连接超时时间

logging: #配置spring的日志级别
  level:
    com.woniuxy.client: debug

Sentinel

雪崩效用

服务雪崩效应是一种因“服务提供者的不可用”(原因)导致“服务调用者不可用”(结果),并将不可用逐渐放大的现象。如下图所示:

Feign and Sentinel - 图1

服务容错

    我们没办法预防雪崩效应的发生,只能尽可能的去做好容错。容错就是提供服务不可用的一种处理方式,避免雪崩。常见的服务容错的机制如下:
  1. 超时
    超时模式,是一种最常见的容错模式,常见的有设置网络连接超时时间,一次RPC的响应超时时间等。在分布式服务调用的场景中,它主要解决了当依赖服务出现建立网络连接或响应延迟,不用无限等待的问题,调用方可以根据事先设计的超时时间中断调用,及时释放关键资源,如Web容器的连接数,数据库连接数等,避免整个系统资源耗尽出现拒绝对外提供服务这种情况。
  2. 限流
    限流是指在一段时间内,定义某个客户或应用可以接收或处理多少个请求的技术。例如,通过限流,你可以过滤掉产生流量峰值的客户和微服务,或者可以确保你的应用程序在自动扩展(Auto Scaling)失效前都不会出现过载的情况。你还可以阻止较低优先级的流量,以便为关键事务提供足够的资源
  3. 断路器
    当在短时间内多次发生指定类型的错误,断路器会开启。开启的断路器可以拒绝接下来更多的请求 – 就像防止真实的电子流动一样。断路器通常在一定时间后关闭,以便为底层服务提供足够的空间来恢复。
    Feign and Sentinel - 图2
  4. 仓壁模式
    在工业领域中,常使用舱壁将划分为几个部分,以便在有某部分船体发生破裂时,其他部分依然能密封安然无恙。舱壁的概念也可以在软件开发中用于隔离资源。通过使用舱壁模式,我们可以保护有限的资源不被用尽。例如,如果我们有两种类型的操作的话,它们都是和同一个数据库实例进行通信,并且数据据库限制连接数,这时我们可以使用两个连接池而不是使用一个共享的连接池。由于这种客户端和资源分离,超时或过度使用池的操作不会令所有其他操作失效。泰坦尼克号沉没的主要原因之一是其舱壁设计失败,水可以通过上面的甲板倒在舱壁的顶部,最后整个船淹没。

引入sentinel

    Sentinel 是面向分布式服务架构的**轻量级**流量控制产品,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助您保护服务的稳定性。
  1. 导包

    <dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    
  2. 下载控制台
    https://github.com/alibaba/Sentinel/releases
    下载下来是一个jar包 直接通过 java命令启动

  3. 配置跟控制台的通信
    spring:
    cloud:
     sentinel:
       transport:
         dashboard: localhost:8080 #控制台地址        
       web-context-unify:false     #支持链路追踪,默认为聚合,设置为非聚合