SpringCloud Fegin组件

01、Feign:介绍与使用

在前面的学习中,使用了Ribbon的负载均衡功能,大大简化了远程调用时的代码:

// 定义服务实例访问URL
String url = "http://user-service/user/" + id;
return restTemplate.getForObject(url, String.class);

但是我们要思考一个问题? 微服务 与 微服务 之间调用问题

  • 调用URL问题 (我们自己拼接,代码不够优雅)
  • 请求参数问题 (我们自己封装请求参数?如果请求参数多,封装起来就会变得特别麻烦,何况不同的请求封装请求参数格式还不一样)

这就是我们接下来要学习Feign的目的,它可以把这些问题全部伪装成一个Feign的http客户端接口,默认集成RestTemplate和Ribbon。Feign存在的目的就是为了简化微服务之间的调用

1.1 介绍

Feign也叫伪装:

Feign可以把Rest的请求进行隐藏,伪装SpringMVC的Controller一样,又类似于Mybatis的Mapper接口。你不用再自己拼接url,拼接参数等等操作,一切的一切都交给Feign去做。

项目主页:https://github.com/OpenFeign/feign

1.2 使用【掌握】

目标:使用Feign客户端调用微服务

操作步骤

  • 第一步:配置依赖(在user-consumer中添加如下依赖):

    <!-- 配置openfeign启动器 -->
    <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
  • 第二步:开启Feign的支持(在ConsumerApplication启动类上,添加@EnableFeignClients注解)

    package cn.itcast.consumer;import org.springframework.boot.SpringApplication;
    import org.springframework.cloud.client.SpringCloudApplication;
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.client.RestTemplate;/** @SpringBootApplication@EnableDiscoveryClient@EnableCircuitBreaker */
    @SpringCloudApplication
    @EnableFeignClients // 开启Feign客户端
    public class ConsumerApplication {public static void main(String[] args){SpringApplication.run(ConsumerApplication.class, args);}@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}
    }
    

    说明:Feign中已经自动集成了Ribbon负载均衡,因此不需要自己定义RestTemplate进行负载均衡的配置。

  • 第三步:编写Feign的客户端(在user-consumer中编写Feign客户端接口类):

    package cn.itcast.consumer.client;import cn.itcast.consumer.pojo.User;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;@FeignClient("user-service")//生成一个代理对象, 并生成bean
    public interface UserClient {@GetMapping("/user/{id}")User findOne(@PathVariable("id") Long id);
    }
    
    • Feign客户端必须是一个接口,Feign会通过JDK动态代理,创建代理对象,并生成一个Bean。
    • @FeignClient注解:声明一个Feign客户端,value或name属性指定服务id。
  • 第四步:编写控制器(创建新的控制器类ConsumerFeignController,注入UserClient访问)

    package cn.itcast.consumer.controller;import cn.itcast.consumer.client.UserClient;
    import cn.itcast.consumer.pojo.User;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;@RestController
    @RequestMapping("/cf")
    public class ConsumerFeignController {@Autowired(required = false)private UserClient userClient;@GetMapping("/{id}")public User findOne(@PathVariable("id") Long id){return userClient.findOne(id);}
    }
    
    • 第五步:启动测试,访问地址 http://localhost:8080/cf/1

02、Feign:Ribbon的支持

  • Feign中本身已经集成了Ribbon依赖和自动配置:

    Fegin内置的Ribbon默认设置了请求超时时长,可以通过手动配置来修改这个超时时长,同时负载均衡策略在轮询的基础上增加了服务节点重试机制,一旦超时,会自动向下一个服务节点重新发起请求
ribbon:ConnectTimeout: 2000 # 建立连接的超时时长(默认,注意这是连接微服务超时时间,不能更改)ReadTimeout: 1000 # 读取响应数据超时时长(注意这是调用微服务获取响应数据超时时间,默认1000)MaxAutoRetries: 0 # 调用的第一个节点的重试次数(默认)MaxAutoRetriesNextServer: 1 # 其他节点会重试多少个服务节点(默认)OkToRetryOnAllOperations: false # true所有超时请求都重试(默认false,代表只重试Get请求),如果不能保证被调用服务的幂等性,请设置为false。

什么是幂等性?例如user-consumer调用user-service新增一个用户,但是因为网络波动,没有及时响应数据,这时如果重试,导致又插入一个同样的用户,这样岂不是数据重复?幂等性指的便是发送多次同样的请求,产生的结果是唯一的。

说明:com.netflix.client.config.DefaultClientConfigImpl.java类中的默认配置



测试重试机制步骤:

  • 修改user-consumer配置:

    ribbon:ConnectTimeout: 2000 # 建立连接的超时时长(默认,注意这是连接微服务超时时间,不能更改)ReadTimeout: 2300 # 读取响应数据超时时长(注意这是调用微服务获取响应数据超时时间)MaxAutoRetries: 0 # 当前服务器的重试次数(默认)MaxAutoRetriesNextServer: 1 # 重试多少个服务节点(默认)OkToRetryOnAllOperations: false # true所有超时请求都重试(默认false,代表只重试Get请求),如果不能保证被调用服务的幂等性,请设置为false。
    
  • user-service添加睡眠时间2秒,并只启动一个节点

    @GetMapping("/{id}")
    public User findOne(@PathVariable("id") Long id)  {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}return userService.findOne(id);
    }
    
  • 访问user-consumer的http://localhost:8080/cf/1

  • F12打开浏览器控制台,network中可以发现,偶尔访问时需要用时4s多,偶尔只需要2s多(user-service睡眠了2s),出现4s多是因为刚好第一次访问的是停止的节点,进行重试机制,去访问第二个节点。

    结果一:

03、Feign:Hystrix的支持

  • Feign默认也对Hystrix做了集成(只不过,默认情况下是关闭的):

  • 需要通过下面的参数来开启:

    feign:hystrix:enabled: true # 开启Feign的熔断功能(线程隔离与熔断) # 线程隔离超时时间
    hystrix:command:default:execution:isolation:thread:timeoutInMilliseconds: 1000
    
  • 定义UserClientFallback实现类,实现UserClient客户端接口,作为服务降级处理类,并生成Bean

    package cn.itcast.consumer.client.fallback;import cn.itcast.consumer.client.UserClient;
    import cn.itcast.consumer.pojo.User;
    import org.springframework.stereotype.Component;@Component // 生成bean
    public class UserClientFallback implements UserClient {@Overridepublic User findOne(Long id) {User user = new User();user.setId(1L);user.setName("用户异常");return user;}
    }
    
  • 在UserClient客户端接口中指定服务降级处理类

    @FeignClient(value = "user-service", fallback = UserClientFallback.class)
    public interface UserClient {@GetMapping("/user/{id}")User findOne(@PathVariable("id") Long id);
    }
    
  • 测试(关闭user-service所有节点服务,然后在页面访问):

注意
1、在Feign 中使用 Hystrix 是对调用 user-service 那一小段做熔断,而原生的hystrix 是对 user-consumer的某接口整一段做熔断,两者可以并存。

2、若想要保证重试机制可用,Hystrix线程隔离的超时时间应该比 Ribbon 重试的总时间要大,比如当前案例中,Hystrix线程隔离的超时时间应该 >=(ReadTimeout * 调用节点总次数(当前节点调用次数 + 重试节点调用次数):2300 * 2 = 4600 (连接时间不计算在内)

04、Feign:日志级别【了解】

前面讲过,通过 logging.level.xx=debug 来设置日志级别。然而这个对Fegin客户端而言不会产生效果。Fegin的日志由fegin.Logger.Level实例来输出。我们只需要创建一个fegin.Logger.Level日志级别的Bean即可。

  • 在user-consumer的配置文件中设置cn.itcast包下的日志级别都为debug

    logging:level:cn.itcast: debug
    
  • 在user-consumer启动类中,定义fegin.Logger.Level实例

    @SpringCloudApplication
    @EnableFeignClients // 开启Feign客户端
    public class ConsumerApplication {public static void main(String[] args){// 运行spring应用SpringApplication.run(ConsumerApplication.class, args);}@Bean@LoadBalanced // 负载均衡注解public RestTemplate restTemplate(){return new RestTemplate();}// Feign日志级别@Beanpublic Logger.Level feignLoggerLevel(){return Logger.Level.FULL;}
    }
    

    这里指定的Level级别是FULL,feign.Logger.Level支持4种级别:

    • NONE:不记录任何日志信息,这是默认值。
    • BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
    • HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
    • FULL:记录所有请求和响应的明细,包括请求头、请求体、响应头、响应体。
  • 重启项目,Fegin客户端调用微服时,就可以输出访问的日志:

Memorial Day is 514 days
I miss you
xiaokeai

SpringCloud Fegin组件相关推荐

  1. SpringCloud常见组件有哪些?

    问题说明:这个题目主要考察对SpringCloud的组件基本了解 难易程度:简单 参考话术: SpringCloud包含的组件很多,有很多功能是重复的.其中最常用组件包括: •注册中心组件:Eurek ...

  2. Java生鲜电商平台-深入理解微服务SpringCloud各个组件的关联与架构

    Java生鲜电商平台-深入理解微服务SpringCloud各个组件的关联与架构 概述 毫无疑问,Spring Cloud是目前微服务架构领域的翘楚,无数的书籍博客都在讲解这个技术.不过大多数讲解还停留 ...

  3. SpringCloud主要组件

    SpringCloud主要组件 SpringCloud组件停更说明

  4. 微服务架构案例(05):SpringCloud 基础组件应用设计

    本文源码:GitHub·点这里 || GitEE·点这里 更新进度(共6节): 01:项目技术选型简介,架构图解说明 02:业务架构设计,系统分层管理 03:数据库选型,业务数据设计规划 04:中间件 ...

  5. springcloud整合php,详细讲解springcloud的组件之RestTemplate集成的Ribbbon

    本文讲的是springcloud是如何集成ribbon的,不同的springcloud的组件(feign,zuul,RestTemplate)集成ribbon有所不同,这篇文章先来看看RestTemp ...

  6. 学习 SpringCloud 五大组件后的总结 一

    学习 SpringCloud 五大组件后的总结 一 1.什么是微服务? 把某一功能独立出来单独作为一个进程类似的微小的服务.独立做某件事,与其他的服务直接不影响. 微服务之间的优缺点? 优点:每个服务 ...

  7. 一看就会的SpringCloud五大组件

    SpringCloud五大组件(一看就会) 前言   Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置 ...

  8. SpringCloud一代组件+nginx实现简单的登录注册

    SpringCloud一代组件+Nginx实现简单的登录注册 1.要求 2.实现步骤 1. 首先将项目骨架创建出来 2.然后将每个功能对应的子项目创建出来 3.导入对应的数据库和配置全局配置 4.配置 ...

  9. (基础篇20-xxx)SpringCloud Alibaba组件

    配置中心(SpringCloud config) 注册中心(SpringCloud netflix eurka) API网关(SpringCloud netflix zuul) 1.SpringClo ...

最新文章

  1. eplices如何导入外部代码_java环境配置的理解
  2. C#提取TXT文档指定内容
  3. 别再叫我 Sql boy!
  4. 第三章:Python基础の函数和文件操作实战
  5. Fixed: MacOS Mojave(10.14) 解决终端用Crontab报权限问题(不管是Root还是普通用户)及Linux基础(shell)...
  6. [图解]ARP协议(一)
  7. 关系抽取、时间抽取,实践项目推荐
  8. python operator 多属性排序_Python爬取高颜值美女(爬虫+人脸检测+颜值检测)你能打几分?...
  9. java版本对应jdk版本_jdk版本对应数字
  10. BPSK_QPSK_16QAM _64QAM _MATLAB
  11. 使用labview制作漂亮的按钮
  12. macbook硬盘读写速度测试(Disk Speed Test 测速贴图)
  13. 移动硬盘只显示盘符,拒绝访问解决方法
  14. 是什么原因才导致网站打开速度慢?
  15. 【GNN】高被引图神经网络(GNN)全面综述论文
  16. 【笃行】Button的选中与改变
  17. 高斯混合模型(GMM--Gaussian mixture model)
  18. Lazada代运营分享—Lazada新手运营快速提升流量交易额的三大核心技巧
  19. Mybatis教程之Mybatis配置篇
  20. Driver——同相运算放大器

热门文章

  1. MIT6.S081 2021 Copy-on-Write Fork for xv6
  2. 苹果备忘录删除了怎么恢复?iPhone用户必备的备忘录恢复方法
  3. springboot springcloud oauth2 jwt redis 框架脚手架
  4. string 中文乱码
  5. IT行业人均年薪11万,阁瑞钛伦特软件分析程序员工资为什么这么高?
  6. java lambda示例_Java Lambda 常用语法示例
  7. 《武林外传》产品体验总结
  8. Baeldung Java 周评 | 第一百零五弹(关键词:如果 Java 是今天设计的、内容丰富的 Spring 会议、JPA 测试用例模版、高性能 Java 持久化、自动化订购午餐、前端五强)
  9. python中[-1] [:-1] [::-1] [n::-1] 切片的用法
  10. HTML用div做春联样式,制作中式风格节日贺卡的代码及实例2款【恭贺新春】