Resilience4j 知识总结

2024-01-26 03:28
文章标签 总结 知识 resilience4j

本文主要是介绍Resilience4j 知识总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Resilience4j 知识总结

1、服务雪崩

服务与服务之间的依赖性,故障会传播,造成连锁反应,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。

造成雪崩原因是什么

  1. 服务提供者不可用(硬件故障、程序bug、缓存击穿、用户大量请求)
  2. 重试加大流量(用户重试,代码逻辑重试)
  3. 服务调用者不可用(同步等待造成的资源耗尽)

注意:

在高并发访问下,系统所依赖的服务的稳定性对系统的影响非常大,依赖有很多不可控的因素,比如网络连接变慢,资源突然繁忙,暂时不可用,服务脱机等。我们要构建稳定、可靠的分布式系统,就必须要有一套容错方法。

2.服务雪崩解决方案

2.1服务熔断

什么是熔断?

熔断就跟保险丝一样,当一个服务请求并发特别大,服务器已经招架不住了,调用错误率飙升,当错误率达到一定阈值后,就将这个服务熔断了。熔断之后,后续的请求就不会再请求服务器了,以减缓服务器的压力

注意:

2.2服务降级

**两种场景: **

  • 当下游的服务因为某种原因响应过慢,下游服务主动停掉一些不太重要的业务,释放出服务器资源,增加响应速度!
  • 当下游的服务因为某种原因不可用,上游主动调用本地的一些降级逻辑,避免卡顿,迅速返回给用户

**服务降级 fallback **

概念:服务器繁忙,请稍后重试,不让客户端等待并立即返回一个友好的提示。

出现服务降级的情况

  • 程序运行异常
  • 超时
  • 服务熔断触发服务降级
  • 线程池/信号量打满也会导致服务降级
    当失败率(如因网络故障/超时造成的失败率高)达到阀值自动触发降级,熔断器触发的快速失败会进行快速恢复。

2.3服务隔离

做服务隔离的目的就是避免服务之间相互影响。毕竟谁也不能说自己的微服务百分百可用,如果不做隔离,一旦一个服务出现了问题,整个系统的稳定性都会受到影响! 因此,做服务隔离是很有必要的。

线程池隔离
将用户请求线程和服务执行线程分割开来,同时约定了每个服务最多可用线程数。
信号量隔离

小时候我们就知道“红灯停,绿灯行”,跟着交通信号的指示过马路。信号量也是这么一种放行、禁行的开关作用。它和线程池技术一样,控制了服务可以被同时访问的并发数量。

2.4服务限流

服务熔断和服务隔离都属于出错后的容错处理机制,而限流模式则可以称为预防模式。
限流模式主要是提前对各个类型的请求设置最高的QPS阈值,若高于设置的阈值则对该请求直接返回,不再调用后续资源。

**注意: **

限流的目的是通过对并发访问/请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务、排队或等待、降级等处理。

**流量控制 **

  • 网关限流:防止大量请求进入系统,Mq实现流量消峰
  • 用户交流限流:提交按钮限制点击频率限制等

3.服务断路器Resilience4j

Resilience4j 是一个轻量级的容错库,用于在 Java 8 及更高版本的应用程序中实现容错、限流、重试和熔断等功能。它提供了一种简单而强大的方法来处理分布式系统中的故障和延迟。本文将对 Resilience4j 的主要功能进行总结,包括其核心组件、使用方法和一些高级特性。

3.1、核心组件

Circuit Breaker(熔断器)
熔断器是一种保护机制,用于防止系统在出现故障时继续尝试执行操作。当一个服务连续失败达到一定次数时,熔断器会打开,后续请求将直接返回错误,而不是继续尝试调用服务。当服务恢复正常后,熔断器会自动关闭。**Resilience4j 有异常比例熔断降级和慢调用比例熔断降级。**异常比例熔断注重请求异常的比例,慢调用注重请求超时异常的比重。

Resilience4j 提供了 CircuitBreaker 类来实现熔断器功能。以下是一个简单的示例:

CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom().failureRateThreshold(50) // 失败率阈值,超过此值熔断器将打开.waitDurationInOpenState(Duration.ofMillis(100)) // 熔断器打开后的等待时间.permittedNumberOfCallsInHalfOpenState(2) // 半开状态下允许的调用次数.slidingWindowSize(10) // 滑动窗口大小.build();CircuitBreaker circuitBreaker = CircuitBreaker.of("myCircuitBreaker", circuitBreakerConfig);Mono<String> result = Mono.defer(() -> {if (circuitBreaker.isCallPermitted("myCircuitBreaker")) {return Mono.just("Hello, World!");} else {return Mono.error(new RuntimeException("Circuit breaker is open"));}
});

RateLimiter(限流器)
限流器用于限制系统资源的使用,以防止过载。Resilience4j 提供了 RateLimiter 类来实现限流功能。以下是一个简单的示例:

RateLimiterConfig rateLimiterConfig = RateLimiterConfig.custom().limitForPeriod(10) // 每秒允许的请求数量.limitRefreshPeriod(Duration.ofSeconds(1)) // 刷新周期.build();RateLimiter rateLimiter = RateLimiter.of("myRateLimiter", rateLimiterConfig);Mono<String> result = Mono.defer(() -> {if (rateLimiter.tryAcquire()) {return Mono.just("Hello, World!");} else {return Mono.error(new RuntimeException("Rate limit exceeded"));}
});

Retry(重试)
重试是一种策略,用于在操作失败时自动重新尝试执行。Resilience4j 提供了 Retry 类来实现重试功能。以下是一个简单的示例:

RetryConfig retryConfig = RetryConfig.custom().maxAttempts(3) // 最大重试次数.waitDuration(Duration.ofMillis(100)) // 重试之间的等待时间.retryOnException(e -> e instanceof IOException) // 指定需要重试的异常类型.build();Retry retry = Retry.of("myRetry", retryConfig);Mono<String> result = Mono.defer(() -> {if (retry.isRetry()) {return Mono.error(new IOException("Retrying..."));} else {return Mono.just("Hello, World!");}
}).retryWhen(retry);

4、使用方法

依赖添加
在项目的 build.gradle 或 pom.xml 文件中添加 Resilience4j 的依赖:

implementation ‘io.github.resilience4j:resilience4j-core:1.7.0’

创建实例
根据需要创建 CircuitBreaker、RateLimiter 或 Retry 的实例,并配置相应的参数。

使用实例
在需要的地方使用创建的实例,例如在调用远程服务或执行可能失败的操作时。

5、高级特性

自定义注解
Resilience4j 支持自定义注解,可以更方便地应用到方法上。例如,可以创建一个名为 @Retryable 的注解,并在需要重试的方法上使用它:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Retryable {int maxAttempts() default 3;Duration waitDuration() default Duration.ofMillis(100);Class<? extends Throwable>[] retryOnException() default {};
}

然后在需要重试的方法上添加 @Retryable 注解:

@Retryable(maxAttempts = 3, waitDuration = Duration.ofMillis(100))
public Mono<String> myMethod() {// ...
}

组合使用
Resilience4j 支持将多个组件组合在一起使用,例如可以将 CircuitBreaker 和 Retry 组合起来,以实现更强大的容错能力。以下是一个简单的示例:

CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("myCircuitBreaker");
Retry retry = Retry.ofDefaults("myRetry");Mono<String> result = Mono.defer(() -> {if (circuitBreaker.isCallPermitted("myCircuitBreaker") && retry.isRetry()) {return Mono.just("Hello, World!");} else {return Mono.error(new RuntimeException("Operation failed"));}
}).retryWhen(retry);

4、总结

Resilience4j 是一个功能强大且易于使用的容错库,可以帮助我们更好地应对分布式系统中的故障和延迟。通过本文的介绍,相信大家已经对 Resilience4j 的核心组件、使用方法和高级特性有了一定的了解。在实际项目中,可以根据需要选择合适的组件和配置,以提高系统的可靠性和稳定性。
以上就是全部内容,如果你有任何问题、意见或建议,都欢迎在评论中分享。让我们继续分享知识,共同成长,一起走向更加美好的未来。感谢你们的阅读,祝愿你们在未来的道路上一帆风顺!

这篇关于Resilience4j 知识总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/645508

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

sqlite3 相关知识

WAL 模式 VS 回滚模式 特性WAL 模式回滚模式(Rollback Journal)定义使用写前日志来记录变更。使用回滚日志来记录事务的所有修改。特点更高的并发性和性能;支持多读者和单写者。支持安全的事务回滚,但并发性较低。性能写入性能更好,尤其是读多写少的场景。写操作会造成较大的性能开销,尤其是在事务开始时。写入流程数据首先写入 WAL 文件,然后才从 WAL 刷新到主数据库。数据在开始

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

二分最大匹配总结

HDU 2444  黑白染色 ,二分图判定 const int maxn = 208 ;vector<int> g[maxn] ;int n ;bool vis[maxn] ;int match[maxn] ;;int color[maxn] ;int setcolor(int u , int c){color[u] = c ;for(vector<int>::iter

整数Hash散列总结

方法:    step1  :线性探测  step2 散列   当 h(k)位置已经存储有元素的时候,依次探查(h(k)+i) mod S, i=1,2,3…,直到找到空的存储单元为止。其中,S为 数组长度。 HDU 1496   a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 。 x在 [-100,100] 解的个数  const int MaxN = 3000

状态dp总结

zoj 3631  N 个数中选若干数和(只能选一次)<=M 的最大值 const int Max_N = 38 ;int a[1<<16] , b[1<<16] , x[Max_N] , e[Max_N] ;void GetNum(int g[] , int n , int s[] , int &m){ int i , j , t ;m = 0 ;for(i = 0 ;

go基础知识归纳总结

无缓冲的 channel 和有缓冲的 channel 的区别? 在 Go 语言中,channel 是用来在 goroutines 之间传递数据的主要机制。它们有两种类型:无缓冲的 channel 和有缓冲的 channel。 无缓冲的 channel 行为:无缓冲的 channel 是一种同步的通信方式,发送和接收必须同时发生。如果一个 goroutine 试图通过无缓冲 channel