关于openfeign

可以认为OpenFeign是Feign的增强版,不同的是OpenFeign支持Spring MVC注解。OpenFeign和Feign底层都内置了Ribbon负载均衡组件,在导入OpenFeign依赖后无需专门导入Ribbon依赖,用做客户端负载均衡,去调用注册中心服务。

关于hystrix

Hystrix是一个用于处理分布式系统的延迟和容错的开源库,可以保证一个服务出现故障时,不会导致整个系统出现雪崩效应,以提高分布式系统弹性;

作为“断路器”,在一个服务出现故障时,可以通过短路器监控,返回一个可以处理的响应结果,保证服务调用线程不会长时间被占用,避免故障蔓延。

  • 实现后备策略的示意图

openfeign微服务接口调用

本项目使用nacos作为注册中心,实现了一个服务提供者:user-service和一个服务调用者(客户端)open-feign,整体调用流程如图所示:

服务提供方

  • 创建模块:microservice-user
  • 引入依赖:
<!-- 引入 Web 功能 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring cloud alibaba nacos discovery 依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
  • 编写bootstrap.yml配置文件
server:
port: 9001
servlet:
context-path: /user-service
spring:
application:
name: user-service
cloud:
nacos:
discovery:
enabled: true # 如果不想使用 Nacos 进行服务注册和发现, 设置为 false 即可
server-addr: 192.168.56.101:8848
# server-addr: 127.0.0.1:8848,127.0.0.1:8849,127.0.0.1:8850 # Nacos 服务器地址
namespace: f687d65c-41a5-44b8-8e0c-80188f8a6ba5
  • 编写service(省略)
  • 编写controller
@RestController
public class UserController {
@Autowired
UserService userService; @GetMapping("/users")
List<User> getUsers(){
return userService.getUsers();
} @GetMapping("/user/{id}")
public User getUserById(@PathVariable Integer id){
return userService.getUserById(id);
} }
  • 启动项目,测试接口
    浏览器访问:http://localhost:9001/user-service/user/3

服务调用方

  • 创建模块:microservice-openfeign
  • 添加依赖:
<dependencies>
<!-- 引入 Web 功能 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring cloud alibaba nacos discovery 依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- feign 替换 JDK 默认的 URLConnection 为 okhttp -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
<!-- 集成 hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!--公共依赖-->
<dependency>
<groupId>com.laoxu.java</groupId>
<artifactId>microservice-common</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
  • 编写启动文件bootstrap.yml
server:
port: 8000
servlet:
context-path: /open-feign
spring:
application:
name: open-feign # nacos中注册的服务名,用于微服务间调用
cloud:
nacos:
discovery:
enabled: true # 如果不想使用 Nacos 进行服务注册和发现, 设置为 false 即可
server-addr: 192.168.56.101:8848
# server-addr: 127.0.0.1:8848,127.0.0.1:8849,127.0.0.1:8850 # Nacos 服务器地址
namespace: f687d65c-41a5-44b8-8e0c-80188f8a6ba5
metadata:
management:
context-path: ${server.servlet.context-path}/actuator feign:
hystrix:
enabled: true # 开启hystrix
okhttp:
enabled: true # 使用okhttp替代默认httpclient
httpclient:
enabled: false # 禁用httpclient
  • 编写启动类
@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
public class OpenFeignApp {
public static void main(String[] args) {
SpringApplication.run(OpenFeignApp.class);
}
}
  • 编写FeignConfig配置类

主要配置了Feign调用时的接口打印信息、接口调用超时时间配置。

/**
* <h1>OpenFeign 配置类</h1>
* */
@Configuration
public class FeignConfig { /**
* <h2>开启 OpenFeign 日志</h2>
* */
@Bean
public Logger.Level feignLogger() {
return Logger.Level.FULL; // 需要注意, 日志级别需要修改成 debug
} /**
* <h2>OpenFeign 开启重试</h2>
* period = 100 发起当前请求的时间间隔, 单位是 ms
* maxPeriod = 1000 发起当前请求的最大时间间隔, 单位是 ms
* maxAttempts = 5 最多请求次数
* */
@Bean
public Retryer feignRetryer() {
return new Retryer.Default(
100,
SECONDS.toMillis(1),
5
);
} public static final int CONNECT_TIMEOUT_MILLS = 5000;
public static final int READ_TIMEOUT_MILLS = 5000; /**
* <h2>对请求的连接和响应时间进行限制</h2>
* */
@Bean
public Request.Options options() { return new Request.Options(
CONNECT_TIMEOUT_MILLS, TimeUnit.MICROSECONDS,
READ_TIMEOUT_MILLS, TimeUnit.MILLISECONDS,
true
);
}
}
  • 编写feign客户端
    用于调用user-service提供的用户服务接口,其实就是个接口,代码很简单。
    其中path参数为统一调用路径的前缀,value为注册中心中服务提供方的服务名。fallback为指定的hystrix后备策略类。
@FeignClient(value = "user-service",path = "user-service",fallback = UserClientFallback.class)
public interface UserClient {
/**
* <h2>通过 OpenFeign 访问 user-service 获取用户列表</h2>
* */
@GetMapping(value = "/users")
List<User> getUsers(); @GetMapping(value = "/user/{id}")
User getUserById(@PathVariable("id") Integer id);
}
  • 编写用户控制器

有了上一步中创建的Feign客户端,在controller中可以通过@Autowired注入使用

@RestController
@RequestMapping("/userapi")
public class UserController {
@Autowired
UserClient userClient; @GetMapping("/users")
public List<User> getUsers(){
return userClient.getUsers();
} @GetMapping("/user/{id}")
public User getUserById(@PathVariable("id") Integer id){
return userClient.getUserById(id);
}
}
  • 启动项目,进行测试
    浏览器输入:http://localhost:8000/open-feign/userapi/users

    说明可以正常通过feign客户端实现微服务接口调用。

与hystrix集成实现后备策略

当openfeign接口调用出现异常,例如接口调用超时,去执行预先设置好的代码逻辑。

创建后备策略类

当feign客户端接口调用异常时,执行对应方法。此处均返回空。

@Slf4j
@Component
public class UserClientFallback implements UserClient {
@Override
public List<User> getUsers() {
log.info("userclient getUsers接口调用失败,执行回退方法");
return null;
} @Override
public User getUserById(Integer id) {
log.info("userclient getUserById接口调用失败,执行回退方法");
return null;
}
}

模拟调用超时

注意:因为hystrix默认超时时间为1s,此处我们将服务提供方接口响应时间设置只要大于1s均能模拟接口超时。

  • 修改服务提供方UserController接口
    在获取用户列表方法中添加睡眠4s逻辑代码:

启用hystrix

在服务调用方bootstrap.yml文件中添加以下配置即可:

feign:
hystrix:
enabled: true # 开启hystrix

重启项目,测试

浏览器输入:http://localhost:8000/open-feign/userapi/users
此时观察浏览器输出为空:

项目控制台打印日志,说明成功执行了后备代码。

项目代码

https://gitee.com/indexman/microservice-learn

Spring Cloud Openfeign微服务接口调用与Hystrix集成实战的更多相关文章

  1. 微服务架构 | 4.2 基于 Feign 与 OpenFeign 的服务接口调用

    目录 前言 1. OpenFeign 基本知识 1.1 Feign 是什么 1.2 Feign 的出现解决了什么问题 1.3 Feign 与 OpenFeign 的区别与对比 2. 在服务消费者端开启 ...

  2. Spring Cloud构建微服务架构(一)服务注册与发现

    Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁 ...

  3. Spring Cloud构建微服务架构(二)服务消费者

    Netflix Ribbon is an Inter Process Communication (IPC) cloud library. Ribbon primarily provides clie ...

  4. Spring Cloud构建微服务架构(五)服务网关

    通过之前几篇Spring Cloud中几个核心组件的介绍,我们已经可以构建一个简略的(不够完善)微服务架构了.比如下图所示: 我们使用Spring Cloud Netflix中的Eureka实现了服务 ...

  5. Spring Cloud构建微服务架构 - 服务网关

    通过之前几篇Spring Cloud中几个核心组件的介绍,我们已经可以构建一个简略的(不够完善)微服务架构了.比如下图所示: alt 我们使用Spring Cloud Netflix中的Eureka实 ...

  6. 【微服务】使用spring cloud搭建微服务框架,整理学习资料

    写在前面 使用spring cloud搭建微服务框架,是我最近最主要的工作之一,一开始我使用bubbo加zookeeper制作了一个基于dubbo的微服务框架,然后被架构师否了,架构师曰:此物过时.随 ...

  7. 基于Spring Cloud的微服务入门教程

    (本教程的原地址发布在本人的简书上:http://www.jianshu.com/p/947d57d042e7,若各位看官有什么问题或不同看法请在这里或简书留言,谢谢!) 本人也是前段时间才开始接触S ...

  8. 干货|基于 Spring Cloud 的微服务落地

    转自 微服务架构模式的核心在于如何识别服务的边界,设计出合理的微服务.但如果要将微服务架构运用到生产项目上,并且能够发挥该架构模式的重要作用,则需要微服务框架的支持. 在Java生态圈,目前使用较多的 ...

  9. 基于Spring Cloud的微服务落地

    微服务架构模式的核心在于如何识别服务的边界,设计出合理的微服务.但如果要将微服务架构运用到生产项目上,并且能够发挥该架构模式的重要作用,则需要微服务框架的支持. 在Java生态圈,目前使用较多的微服务 ...

  10. Spring Cloud与微服务构建:Spring Cloud简介

    Spring Cloud简介 微服务因该具备的功能 微服务可以拆分为"微"和"服务"二字."微"即小的意思,那到底多小才算"微&q ...

随机推荐

  1. OpenKruise :Kubernetes背后的托底

    本文分享自华为云社区<OpenKruise核心能力和工作原理>,作者:可以交个朋友. 一. 诞生背景 Kubernetes 自身提供的应用部署管理功能,无法满足大规模应用场景的需求,例如应 ...

  2. 远程连接-ssh

  3. [转帖]带你重走 TiDB TPS 提升 1000 倍的性能优化之旅

    https://tidb.net/blog/29074d86#TiDB%20%E6%80%A7%E8%83%BD%E5%92%8C%E7%A8%B3%E5%AE%9A%E6%80%A7%E7%9A%8 ...

  4. 【转帖】nginx变量使用方法详解-2

    https://www.diewufeiyang.com/post/576.html 关于 Nginx 变量的另一个常见误区是认为变量容器的生命期,是与 location 配置块绑定的.其实不然.我们 ...

  5. 记一次 .NET某工控自动化系统 崩溃分析

    一:背景 1. 讲故事 前些天微信上有位朋友找到我,说他的程序偶发崩溃,分析了个把星期也没找到问题,耗费了不少人力物力,让我能不能帮他看一下,给我申请了经费,哈哈,遇到这样的朋友就是爽快,刚好周二晚上 ...

  6. vim 从嫌弃到依赖(14)——快速跳转

    之前介绍过众多的motion,根据移动范围来排序的话有 l.e.w.j等等,但是面对那么长的代码文件,仅仅使用这几个简单的motion不知道要移动多少次才能找到我想要的代码,这个速度有时候还不如我用鼠 ...

  7. 微信小程序-双线程渲染模型

    微信小程序双线程渲染模型 小程序的运行环境分成渲染层和逻辑层: WXML 模板和 WXSS 样式工作在渲染层,通过 WebView 进行渲染 小程序会为每一个界面都创建一个 WebView 来渲染这个 ...

  8. 设计模式学习-使用go实现解释器模式

    解释器模式 定义 优点 缺点 适用范围 代码实现 参考 解释器模式 定义 解释器模式(interpreter):给定一种语言,定义它的文法的一种表示,并定一个解释器,这个解释器使用该表示来解释语言中的 ...

  9. 遇到一个bug,组件不更新内容

    解决办法 当v-if的值发生变化时,组件都会被重新渲染一遍.因此,利用v-if指令的特性,可以达到强制刷新组件的目的. <template> <comp v-if="upd ...

  10. 领域知识图谱的医生推荐系统:利用BERT+CRF+BiLSTM的医疗实体识别,建立医学知识图谱,建立知识问答系统

    领域知识图谱的医生推荐系统:利用BERT+CRF+BiLSTM的医疗实体识别,建立医学知识图谱,建立知识问答系统 本项目主要实现了疾病自诊和医生推荐两个功能并构建了医生服务指标评价体系.疾病自诊主要通 ...