6.Feign

前面我们使用的RestTemplate实现REST API调用,代码大致如下:
@GetMapping("/buy/{id}")
public Product order() {
   Product product = restTemplate.getForObject("http://shop-service
product/product/1", Product.class);
   return product;
}
由代码可知,我们是使用拼接字符串的方式构造URL的,该URL只有一个参数。但是,在现实中,URL
中往往含有多个参数。这时候我们如果还用这种方式构造URL,那么就会非常痛苦。那应该如何解决?
我们带着这样的问题进入到本章的学习。

1.1 Feign简介

Feign是Netflflix开发的声明式,模板化的HTTP客户端,其灵感来自Retrofifit,JAXRS-2.0以及WebSocket.
Feign可帮助我们更加便捷,优雅的调用HTTP API。
在SpringCloud中,使用Feign非常简单——创建一个接口,并在接口上添加一些注解,代码就完
成了。
Feign支持多种注解,例如Feign自带的注解或者JAX-RS注解等。
SpringCloud对Feign进行了增强,使Feign支持了SpringMVC注解,并整合了Ribbon和Eureka,
从而让Feign的使用更加方便。

1.2 基于Feign的服务调用

(1)引入依赖

在服务消费者 shop_service_order 添加Fegin依赖
    <!--引入feign依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

(2)启动类添加Feign的支持

@SpringBootApplication
@EntityScan("cn.itcast.product.order")
@EnableFeignClients//通过@EnableFeignClients注解开启Spring Cloud Feign的支持功能
public class OrderApplication {

    /**
     * 使用spring的RestTemplate发送http请求到商品服务
     * 1.创建RestTemplate对象交给容器管理
     * 2.在使用的时候调用其方法完成操作
     */
    /**
     * 基于Ribbon的服务调用与负载均衡
     */
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class,args);
    }
}

(3)配置调用微服务的接口

/**
 * 1.声明需要调用的微服务名称
 */
@FeignClient(name = "service-product")
public interface ProductFeignClient {
    /**
     * 2.配置需要调用的微服务接口
     */
    @RequestMapping(value = "/product/findById/{id}", method = RequestMethod.GET)
    public Product findById(@PathVariable("id") Long id);//注意,这里@PathVariable后面一定要配置参数名
}
定义各参数绑定时,@PathVariable@RequestParam@RequestHeader等可以指定参数属
性,在Feign中绑定参数必须通过value属性来指明具体的参数名,不然会抛出异常
@FeignClient:注解通过name指定需要调用的微服务的名称,用于创建Ribbon的负载均衡器。
然后Ribbon会把 service-product 解析为注册到注册中心的服务。 

(4)调用微服务

    @Autowired
    ProductFeignClient productFeignClient;

    @RequestMapping(value = "/buybuybuybuy/{id}", method = RequestMethod.GET)
    public Product findById4(@PathVariable Long id) {
//        Product product = restTemplate.getForObject("http://127.0.0.1:9001/product/findById/1", Product.class);
//        Product product = restTemplate.getForObject("http://service-product/product/findById/1", Product.class);
        Product product = productFeignClient.findById(id);
        return product;
    }

1.3 FeignRibbon的联系

Ribbon是一个基于 HTTP TCP 客户端 的负载均衡的工具。它可以 在客户端 配置
RibbonServerList(服务端列表),使用 HttpClient RestTemplate 模拟http请求,步骤相当繁琐。
Feign 是在 Ribbon的基础上进行了一次改进,是一个使用起来更加方便的 HTTP 客户端。采用接口的
方式, 只需要创建一个接口,然后在上面添加注解即可 ,将需要调用的其他服务的方法定义成抽象方
法即可, 不需要自己构建http请求。然后就像是调用自身工程的方法调用,而感觉不到是调用远程方
法,使得编写客户端变得非常容易

1.4 负载均衡

Feign中本身已经集成了Ribbon依赖和自动配置,因此我们不需要额外引入依赖,也不需要再注册
RestTemplate 对象。另外,我们可以像上节课中讲的那样去配置Ribbon,可以通过 ribbon.xx 来进
行全局配置。也可以通过 服务名.ribbon.xx 来对指定服务配置:
启动两个 shop_service_product ,重新测试可以发现使用Ribbon的轮询策略进行负载均衡

2 服务调用Feign高级

2.1 Feign的配置

Spring Cloud Edgware开始,Feign支持使用属性自定义Feign。对于一个指定名称的Feign
Client(例如该Feign Client的名称为 feignName ),Feign支持如下配置项: 
feign:
  client:
    config:
      feignName: ##定义FeginClient的名称
        connectTimeout: 5000 # 相当于Request.Options
        readTimeout: 5000 # 相当于Request.Options
# 配置Feign的日志级别,相当于代码配置方式中的Logger
        loggerLevel: full
# Feign的错误解码器,相当于代码配置方式中的ErrorDecoder
        errorDecoder: com.example.SimpleErrorDecoder
# 配置重试,相当于代码配置方式中的Retryer
        retryer: com.example.SimpleRetryer
# 配置拦截器,相当于代码配置方式中的RequestInterceptor
        requestInterceptors: 
          - com.example.FooRequestInterceptor
          - com.example.BarRequestInterceptor
        decode404: false
feignNameFeginClient的名称
connectTimeout : 建立链接的超时时长
readTimeout : 读取超时时长
loggerLevel: Fegin的日志级别
errorDecoder Feign的错误解码器
retryer : 配置重试
requestInterceptors : 添加请求拦截器
decode404 : 配置熔断不处理404异常 

2.2请求压缩

Spring Cloud Feign 支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。通过下面的参数
即可开启请求与响应的压缩功能:
 
feign:
  compression:
    request:
      enabled: true # 开启请求压缩 
    response: 
      enabled: true # 开启响应压缩
同时,我们也可以对请求的数据类型,以及触发压缩的大小下限进行设置: 
feign:
  compression:
    request:
      enabled: true # 开启请求压缩
      mime-types: text/html,application/xml,application/json # 设置压缩的数据类型
      min-request-size: 2048 # 设置触发压缩的大小下限
注:上面的数据类型、压缩大小下限均为默认值。

2.3 日志级别

在开发或者运行阶段往往希望看到Feign请求过程的日志记录,默认情况下Feign的日志是没有开启的。
要想用属性配置方式来达到日志效果,只需在 application.yml 中添加如下内容即可:
feign:
  client:
    config:
      service-product:  #这里是被调用的服务名称
        loggerLevel: FULL
logging:
  level:
    cn.itcast.order.fegin.ProductFeginClient: debug
logging.level.xx : debug : Feign日志只会对日志级别为debug的做出响应
feign.client.config.shop-service-product.loggerLevel : 配置Feign的日志Feign有四种
日志级别:
NONE【性能最佳,适用于生产】:不记录任何日志(默认值)
BASIC【适用于生产环境追踪问题】:仅记录请求方法、URL、响应状态代码以及执行时间
HEADERS:记录BASIC级别的基础上,记录请求和响应的header
FULL【比较适用于开发及测试环境定位问题】:记录请求和响应的headerbody和元数
据。
打印日志:
: [ProductFeignClient#findById] <--- HTTP/1.1 200 (822ms)
: [ProductFeignClient#findById] content-type: application/json;charset=UTF-8
: [ProductFeignClient#findById] date: Fri, 28 Aug 2020 08:17:12 GMT
: [ProductFeignClient#findById] transfer-encoding: chunked
: [ProductFeignClient#findById] 
: [ProductFeignClient#findById] {"id":1,"productName":"访问的服务地址:192.168.137.19011","status":1,"price":111.00,"productDesc":"第一间商铺","caption":"贵族商品","inventory":1111}
: [ProductFeignClient#findById] <--- END HTTP (164-byte body)
: Flipping property: service-product.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647

 

 
 
 
 
@PathVariable("id")
posted @ 2020-08-28 16:29  指尖下的世界  阅读(248)  评论(0编辑  收藏  举报
/* 看板娘 */ /*炸泡*/
/* 鼠标点击求赞文字特效 */