熔断器 Hystrix 源码解析 —— 请求执行(四)之失败回退逻辑

5分钟搞懂SCMA:稀疏码多址接入的核心原理与实战应用 本文深入浅出地解析了SCMA(稀疏码多址接入)的核心原理与实战应用。通过对比传统正交多址技术,阐释了SCMA如何通过非正交叠加和稀疏码本设计,实现远超资源单元数的用户接入,从而有效应对5G海量机器通信(mMTC)的挑战。文章还探讨了其在上行海量连接、免授权接入等场景的应用潜力及工程实现中的关键考量。 阅读详情

摘要: 原创出处 http://www.iocoder.cn/Hystrix/command-execute-fourth-fallback/ 「芋道源码」欢迎转载,保留摘要,谢谢!

本文主要基于 Hystrix 1.5.X 版本


������关注微信公众号:【芋道源码】有福利:
1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
3. 您对于源码的疑问每条留言都将得到认真回复。甚至不知道如何读源码也可以请教噢。
4. 新的源码解析文章实时收到通知。每周更新一篇左右。
5. 认真的源码交流微信群。


1. 概述

本文主要分享 Hystrix 命令执行(四)之失败回退逻辑。

建议 :对 RxJava 已经有一定的了解的基础上阅读本文。

Hystrix 执行命令整体流程如下图:

FROM 《【翻译】Hystrix文档-实现原理》「流程图」

另外,#handleXXXX() 方法,整体代码比较类似,最终都是调用 #getFallbackOrThrowException() 方法,获得【回退逻辑 Observable】或者【异常 Observable】,在 「8. #getFallbackOrThrowException(…)」 详细解析。


推荐 Spring Cloud 书籍:

2. handleFallback

在 《Hystrix 源码解析 —— 命令执行(一)之正常执行逻辑》「4. #executeCommandAndObserve(…)」 中,#executeCommandAndObserve(...) 的第 82 行 onErrorResumeNext(handleFallback) 代码,通过调用 Observable#onErrorResumeNext(...) 方法,实现【执行命令 Observable】执行异常时,返回【回退逻辑 Observable】,执行失败回退逻辑。

FROM 《ReactiveX文档中文翻译》「onErrorResumeNext」
onErrorResumeNext 方法返回一个镜像原有 Observable 行为的新 Observable ,后者会忽略前者的 onError 调用,不会将错误传递给观察者,作为替代,它会开始镜像另一个,备用的 Observable 。

handleFallback 变量,代码如下 :

  1: final Func1<Throwable, Observable<R>> handleFallback = new Func1<Throwable, Observable<R>>() {
  2:     @Override
  3:     public Observable<R> call(Throwable t) {
  4:         // 标记尝试成功
  5:         circuitBreaker.markNonSuccess();
  6:         // 标记 executionResult 执行异常
  7:         Exception e = getExceptionFromThrowable(t);
  8:         executionResult = executionResult.setExecutionException(e);
  9:         // 返回 【回退逻辑 Observable】
 10:         if (e instanceof RejectedExecutionException) { // 线程池提交任务拒绝异常
 11:             return handleThreadPoolRejectionViaFallback(e);
 12:         } else if (t instanceof HystrixTimeoutException) { // 执行命令超时异常
 13:             return handleTimeoutViaFallback();
 14:         } else if (t instanceof HystrixBadRequestException) { // TODO 【2014】【HystrixBadRequestException】
 15:             return handleBadRequestByEmittingError(e);
 16:         } else {
 17:             /*
 18:              * Treat HystrixBadRequestException from ExecutionHook like a plain HystrixBadRequestException.
 19:              */
 20:             if (e instanceof HystrixBadRequestException) { // TODO 【2014】【HystrixBadRequestException】
 21:                 eventNotifier.markEvent(HystrixEventType.BAD_REQUEST, commandKey);
 22:                 return Observable.error(e);
 23:             }
 24: 
 25:             return handleFailureViaFallback(e);
 26:         }
 27:     }
 28: };

3. #handleShortCircuitViaFallback()

#handleShortCircuitViaFallback() 方法,short-circuit ,处理链路处于熔断的回退逻辑,在 此处 被调用,代码如下 :

  1: private Observable<R> handleShortCircuitViaFallback() {
  2:     // TODO 【2011】【Hystrix 事件机制】
  3:     // record that we are returning a short-circuited fallback
  4:     eventNotifier.markEvent(HystrixEventType.SHORT_CIRCUITED, commandKey);
  5:     // 标记 executionResult 执行异常
  6:     // short-circuit and go directly to fallback (or throw an exception if no fallback implemented)
  7:     Exception shortCircuitException = new RuntimeException("Hystrix circuit short-circuited and is OPEN");
  8:     executionResult = executionResult.setExecutionException(shortCircuitException);
  9:     try {
 10:         // 获得 【回退逻辑 Observable】 或者 【异常 Observable】
 11:         return getFallbackOrThrowException(this, HystrixEventType.SHORT_CIRCUITED, FailureType.SHORTCIRCUIT,
 12:                 "short-circuited", shortCircuitException);
 13:     } catch (Exception e) {
 14:         return Observable.error(e);
 15:     }
 16: }
  • 第 4 行 :TODO 【2011】【Hystrix 事件机制】
  • 第 7 至 8 行 :标记 executionResult 执行异常。
  • 第 11 至 12 行 :调用 #getFallbackOrThrowException() 方法,获得【回退逻辑 Observable】或者【异常 Observable】,在 「8. #getFallbackOrThrowException(…)」 详细解析。
  • 第 14 行 :返回【异常 Observable】。

4. #handleSemaphoreRejectionViaFallback()

#handleSemaphoreRejectionViaFallback() 方法,semaphore-rejection ,处理信号量获得失败的回退逻辑,在 此处 被调用,代码如下 :

  1: private Observable<R> handleSemaphoreRejectionViaFallback() {
  2:     // 标记 executionResult 执行异常
  3:     Exception semaphoreRejectionException = new RuntimeException("could not acquire a semaphore for execution");
  4:     executionResult = executionResult.setExecutionException(semaphoreRejectionException);
  5:     // TODO 【2011】【Hystrix 事件机制】
  6:     eventNotifier.markEvent(HystrixEventType.SEMAPHORE_REJECTED, commandKey);
  7:     logger.debug("HystrixCommand Execution Rejection by Semaphore."); // debug only since we're throwing the exception and someone higher will do something with it
  8:     // retrieve a fallback or throw an exception if no fallback available
  9:     // 获得 【回退逻辑 Observable】 或者 【异常 Observable】
 10:     return getFallbackOrThrowException(this, HystrixEventType.SEMAPHORE_REJECTED, FailureType.REJECTED_SEMAPHORE_EXECUTION,
 11:             "could not acquire a semaphore for execution", semaphoreRejectionException);
 12: }
  • 第 3 至 4 行 :标记 executionResult 执行异常。
  • 第 6 至 7 行 :TODO 【2011】【Hystrix 事件机制】
  • 第 10 至 11 行 :调用 #getFallbackOrThrowException() 方法,获得【回退逻辑 Observable】或者【异常 Observable】,在 「8. #getFallbackOrThrowException(…)」 详细解析。

5. #handleThreadPoolRejectionViaFallback()

#handleThreadPoolRejectionViaFallback() 方法,thread-pool-rejection ,处理线程池提交任务拒绝的回退逻辑,在 此处 被调用,代码如下:

  1: private Observable<R> handleThreadPoolRejectionViaFallback(Exception underlying) {
  2:     // TODO 【2011】【Hystrix 事件机制】
  3:     eventNotifier.markEvent(HystrixEventType.THREAD_POOL_REJECTED, commandKey);
  4:     // TODO 【2002】【metrics】
  5:     threadPool.markThreadRejection();
  6:     // 获得 【回退逻辑 Observable】 或者 【异常 Observable】
  7:     // use a fallback instead (or throw exception if not implemented)
  8:     return getFallbackOrThrowException(this, HystrixEventType.THREAD_POOL_REJECTED, FailureType.REJECTED_THREAD_EXECUTION,
  9:             "could not be queued for execution", underlying);
 10: }
  • 第 3 行 :TODO 【2011】【Hystrix 事件机制】
  • 第 5 行 :TODO 【2002】【metrics】
  • 第 8 至 9 行 :调用 #getFallbackOrThrowException() 方法,获得【回退逻辑 Observable】或者【异常 Observable】,在 「8. #getFallbackOrThrowException(…)」 详细解析。

6. #handleTimeoutViaFallback()

#handleTimeoutViaFallback() 方法,execution-timeout ,处理命令执行超时的回退逻辑,在 此处 被调用,代码如下:

  1: private Observable<R> handleTimeoutViaFallback() {
  2:     // 获得 【回退逻辑 Observable】 或者 【异常 Observable】
  3:     return getFallbackOrThrowException(this, HystrixEventType.TIMEOUT, FailureType.TIMEOUT,
  4:             "timed-out", new TimeoutException());
  5: }

7. #handleFailureViaFallback()

#handleFailureViaFallback() 方法,execution-failure ,处理命令执行异常的回退逻辑,在 此处 被调用,代码如下:

  1: private Observable<R> handleFailureViaFallback(Exception underlying) {
  2:     // TODO 【2011】【Hystrix 事件机制】
  3:     /**
  4:      * All other error handling
  5:      */
  6:     logger.debug("Error executing HystrixCommand.run(). Proceeding to fallback logic ...", underlying);
  7: 
  8:     // report failure
  9:     eventNotifier.markEvent(HystrixEventType.FAILURE, commandKey);
 10: 
 11:     // 标记 executionResult 异常 TODO 【2007】【executionResult】用途 为啥不是执行异常
 12:     // record the exception
 13:     executionResult = executionResult.setException(underlying);
 14:     // 获得 【回退逻辑 Observable】 或者 【异常 Observable】
 15:     return getFallbackOrThrowException(this, HystrixEventType.FAILURE, FailureType.COMMAND_EXCEPTION, "failed", underlying);
 16: }
  • 第 2 至 9 行 :TODO 【2011】【Hystrix 事件机制】
  • 第 13 行 :标记 executionResult 异常。
  • 第 15 行 :调用 #getFallbackOrThrowException() 方法,获得【回退逻辑 Observable】或者【异常 Observable】,在 「8. #getFallbackOrThrowException(…)」 详细解析。

8. #getFallbackOrThrowException(…)

#getFallbackOrThrowException() 方法,获得【回退逻辑 Observable】或者【异常 Observable】,代码如下 :

  1: private Observable<R> getFallbackOrThrowException(final AbstractCommand<R> _cmd, final HystrixEventType eventType, final FailureType failureType, final String message, final Exception originalException) {
  2:     // 记录 HystrixRequestContext
  3:     final HystrixRequestContext requestContext = HystrixRequestContext.getContextForCurrentThread();
  4:     // 标记 executionResult 添加( 记录 )事件
  5:     long latency = System.currentTimeMillis() - executionResult.getStartTimestamp();
  6:     // record the executionResult
  7:     // do this before executing fallback so it can be queried from within getFallback (see See https://github.com/Netflix/Hystrix/pull/144)
  8:     executionResult = executionResult.addEvent((int) latency, eventType);
  9: 
 10:     if (isUnrecoverable(originalException)) { // 无法恢复的异常
 11:         logger.error("Unrecoverable Error for HystrixCommand so will throw HystrixRuntimeException and not apply fallback. ", originalException);
 12: 
 13:         // TODO 【2003】【HOOK】
 14:         /* executionHook for all errors */
 15:         Exception e = wrapWithOnErrorHook(failureType, originalException);
 16:         // 返回 【异常 Observable】
 17:         return Observable.error(new HystrixRuntimeException(failureType, this.getClass(), getLogMessagePrefix() + " " + message + " and encountered unrecoverable error.", e, null));
 18:     } else {
 19:         if (isRecoverableError(originalException)) { // 可恢复的异常
 20:             logger.warn("Recovered from java.lang.Error by serving Hystrix fallback", originalException);
 21:         }
 22: 
 23:         if (properties.fallbackEnabled().get()) {
 24:             /* fallback behavior is permitted so attempt */
 25: 
 26:             // 设置 HystrixRequestContext 的 Action
 27:             final Action1<Notification<? super R>> setRequestContext = new Action1<Notification<? super R>>() {
 28:                 @Override
 29:                 public void call(Notification<? super R> rNotification) {
 30:                     setRequestContextIfNeeded(requestContext);
 31:                 }
 32:             };
 33: 
 34:             // TODO 【2007】【executionResult】用途
 35:             final Action1<R> markFallbackEmit = new Action1<R>() {
 36:                 @Override
 37:                 public void call(R r) {
 38:                     if (shouldOutputOnNextEvents()) {
 39:                         executionResult = executionResult.addEvent(HystrixEventType.FALLBACK_EMIT);
 40:                         eventNotifier.markEvent(HystrixEventType.FALLBACK_EMIT, commandKey);
 41:                     }
 42:                 }
 43:             };
 44: 
 45:             // TODO 【2007】【executionResult】用途
 46:             final Action0 markFallbackCompleted = new Action0() {
 47:                 @Override
 48:                 public void call() {
 49:                     long latency = System.currentTimeMillis() - executionResult.getStartTimestamp();
 50:                     eventNotifier.markEvent(HystrixEventType.FALLBACK_SUCCESS, commandKey);
 51:                     executionResult = executionResult.addEvent((int) latency, HystrixEventType.FALLBACK_SUCCESS);
 52:                 }
 53:             };
 54: 
 55:             // 处理异常 的 Func
 56:             final Func1<Throwable, Observable<R>> handleFallbackError = new Func1<Throwable, Observable<R>>() {
 57:                 @Override
 58:                 public Observable<R> call(Throwable t) {
 59:                     // TODO 【2003】【HOOK】
 60:                     /* executionHook for all errors */
 61:                     Exception e = wrapWithOnErrorHook(failureType, originalException);
 62:                     // 获得 Exception
 63:                     Exception fe = getExceptionFromThrowable(t);
 64: 
 65:                     long latency = System.currentTimeMillis() - executionResult.getStartTimestamp();
 66:                     Exception toEmit;
 67: 
 68:                     if (fe instanceof UnsupportedOperationException) {
 69:                         // TODO 【2011】【Hystrix 事件机制】
 70:                         logger.debug("No fallback for HystrixCommand. ", fe); // debug only since we're throwing the exception and someone higher will do something with it
 71:                         eventNotifier.markEvent(HystrixEventType.FALLBACK_MISSING, commandKey);
 72:                         // 标记 executionResult 添加( 记录 )事件 HystrixEventType.FALLBACK_MISSING
 73:                         executionResult = executionResult.addEvent((int) latency, HystrixEventType.FALLBACK_MISSING);
 74: 
 75:                         // 创建 HystrixRuntimeException
 76:                         toEmit = new HystrixRuntimeException(failureType, _cmd.getClass(), getLogMessagePrefix() + " " + message + " and no fallback available.", e, fe);
 77:                     } else {
 78:                         // TODO 【2011】【Hystrix 事件机制】
 79:                         logger.debug("HystrixCommand execution " + failureType.name() + " and fallback failed.", fe);
 80:                         eventNotifier.markEvent(HystrixEventType.FALLBACK_FAILURE, commandKey);
 81:                         // 标记 executionResult 添加( 记录 )事件 HystrixEventType.FALLBACK_FAILURE
 82:                         executionResult = executionResult.addEvent((int) latency, HystrixEventType.FALLBACK_FAILURE);
 83: 
 84:                         // 创建 HystrixRuntimeException
 85:                         toEmit = new HystrixRuntimeException(failureType, _cmd.getClass(), getLogMessagePrefix() + " " + message + " and fallback failed.", e, fe);
 86:                     }
 87: 
 88:                     // NOTE: we're suppressing fallback exception here
 89:                     if (shouldNotBeWrapped(originalException)) {
 90:                         return Observable.error(e);
 91:                     }
 92: 
 93:                     return Observable.error(toEmit);
 94:                 }
 95:             };
 96: 
 97:             // 获得 TryableSemaphore
 98:             final TryableSemaphore fallbackSemaphore = getFallbackSemaphore();
 99: 
100:             // 信号量释放Action
101:             final AtomicBoolean semaphoreHasBeenReleased = new AtomicBoolean(false);
102:             final Action0 singleSemaphoreRelease = new Action0() {
103:                 @Override
104:                 public void call() {
105:                     if (semaphoreHasBeenReleased.compareAndSet(false, true)) {
106:                         fallbackSemaphore.release();
107:                     }
108:                 }
109:             };
110: 
111:             Observable<R> fallbackExecutionChain;
112: 
113:             // acquire a permit
114:             if (fallbackSemaphore.tryAcquire()) {
115:                 try {
116:                     if (isFallbackUserDefined()) {
117:                         executionHook.onFallbackStart(this);
118:                         fallbackExecutionChain = getFallbackObservable();
119:                     } else {
120:                         //same logic as above without the hook invocation
121:                         fallbackExecutionChain = getFallbackObservable();
122:                     }
123:                 } catch (Throwable ex) {
124:                     //If hook or user-fallback throws, then use that as the result of the fallback lookup
125:                     fallbackExecutionChain = Observable.error(ex);
126:                 }
127: 
128:                 // 获得 【回退逻辑 Observable】
129:                 return fallbackExecutionChain
130:                         .doOnEach(setRequestContext)
131:                         .lift(new FallbackHookApplication(_cmd)) // TODO 【2003】【HOOK】
132:                         .lift(new DeprecatedOnFallbackHookApplication(_cmd))
133:                         .doOnNext(markFallbackEmit)
134:                         .doOnCompleted(markFallbackCompleted)
135:                         .onErrorResumeNext(handleFallbackError) //
136:                         .doOnTerminate(singleSemaphoreRelease)
137:                         .doOnUnsubscribe(singleSemaphoreRelease);
138:             } else {
139:                return handleFallbackRejectionByEmittingError();
140:             }
141:         } else {
142:             return handleFallbackDisabledByEmittingError(originalException, failureType, message);
143:         }
144:     }
145: }
  • 耐心,这个方法看起来灰常长,也仅限于长,理解成难度很小。
  • 第 3 行 :记录 HystrixRequestContext 。
  • 第 5 至 8 行 :标记 executionResult 添加( 记录 )事件。
  • 第 10 至 17 行 :调用 #isUnrecoverable(Exception) 方法,若异常不可恢复,直接返回【异常 Observable】。点击 链接 查看该方法。
  • 第 19 至 21 行 :调用 #isRecoverableError(Exception) 方法,若异常可恢复,打印 WARN 日志。点击 链接 查看该方法。主要针对 java.lang.Error 情况,打印 #isUnrecoverable(Exception) 排除掉的 Error。
  • 【反向】第 141 至 143 行 :当配置 HystrixCommandProperties.fallbackEnabled = false ( 默认值 :true ) ,即失败回退功能关闭,调用 #handleFallbackDisabledByEmittingError() ,返回【异常 Observable】。点击 链接 查看该方法。
  • 【反向】第 138 至 140 行 :失败回退信号量( TryableSemaphore )【注意,不是正常执行信号量】使用失败,调用 #handleFallbackRejectionByEmittingError() ,返回【异常 Observable】。点击 链接 查看该方法。
  • 第 23 行 :当配置 HystrixCommandProperties.fallbackEnabled = true ( 默认值 :true ) ,即失败回退功能开启。
  • 第 27 至 32 行 :设置 HystrixRequestContext 的 Action ,使用第 3 行记录的 HystrixRequestContext 。
  • 第 35 至 43 行 :TODO 【2007】【executionResult】用途
  • 第 46 至 53 行 :TODO 【2007】【executionResult】用途
  • 第 56 至 95 行 :处理回退逻辑执行发生异常的 Func1 ,返回【异常 Observable】。

    • 第 61 行 :TODO 【2003】【HOOK】
    • 第 63 行 :调用 #getExceptionFromThrowable(Throwable) 方法,获得 Exception 。若 t 的类型为 Throwable 时,包装成 Exception 。点击 链接 查看该方法代码。
    • 第 68 至 76 行 :当 fe 的类型为 UnsupportedOperationException 时,使用 e + fe 创建 HystrixRuntimeException 。该异常发生于 HystrixCommand#getFallback() 抽象方法未被覆写。
    • 第 77 至 86 行 :当 fe 的类型为其他异常时,使用 e + fe 创建 HystrixRuntimeException 。该异常发生于 HystrixCommand#getFallback() 执行发生异常。
    • 第 89 至 91 行 :调用 #shouldNotBeWrapped() 方法,判断 originalException 是 ExceptionNotWrappedByHystrix 的实现时,即要求返回的【异常 Observable】不使用 HystrixRuntimeException 包装。点击 链接 查看该方法代码。
    • 第 93 行 :返回【异常 Observable】,使用 toEmit ( HystrixRuntimeException ) 为异常。
  • 第 98 行 :调用 #getFallbackSemaphore() 方法,获得失败回退信号量( TryableSemaphore )对象,点击 链接 查看该方法代码。TryableSemaphore 在 《Hystrix 源码解析 —— 命令执行(一)之正常执行逻辑》「3. TryableSemaphore」 有详细解析。

  • 第 100 至 109 行 :信号量释放的 Action。
  • 第 114 至 137 行 :失败回退信号量( TryableSemaphore )使用成功,返回【回退逻辑 Observable】。
    • 【重要】第 116 至 122 行 :调用 #getFallbackObservable() 方法,创建【回退逻辑 Observable】。将子类对 HystrixCommand#getFallback() 抽象方法的执行结果,使用 Observable#just(...) 包装返回。点击 链接 查看该方法的代码。
      • 第 116 行 :调用 #isFallbackUserDefined() 方法,返回命令子类是否实现 HystrixCommand#getFallback() 抽象方法。只有已实现( true ) 的情况下,调用 HOOK TODO 【2003】【HOOK】。
    • 第 129 至 137 行 :获得 【回退逻辑 Observable】。
      • 第 131 行 :// TODO 【2003】【HOOK】
      • 第 135 行 :调用 Observable#onErrorResumeNext(...) 方法,实现【失败回退 Observable】执行异常时,返回【异常 Observable】。

有两个注意点:

  • 当命令执行超时时,失败回退逻辑使用的是 HystrixTimer 的线程池。
  • 失败回退逻辑,无超时时间,使用要小心。

666. 彩蛋

比想象中“臭长”的逻辑。

总的来说,逻辑和 《Hystrix 源码解析 —— 命令执行(一)之正常执行逻辑》 是很类似的。

胖友,分享一波朋友圈可好!

别再手动找触点了!EPLAN线圈触点映像的3种显示方式与F键/Ctrl+B快捷键实战 本文详细解析EPLAN线圈触点映像的3种显示方式与F键/Ctrl+B快捷键实战技巧,帮助电气设计工程师提升图纸操作效率。通过精简编号、路径栏显示和元件旁可视化三种模式的应用场景对比,结合快捷键肌肉记忆训练法,实现触点快速定位与管理,大幅减少手动查找时间。 阅读详情

相关推荐

不止是打字机效果:手把手教你用SpannableStringBuilder打造Android富文本AI对话界面

本文详细介绍了如何使用SpannableStringBuilder在Android平台上构建专业级AI对话界面,涵盖流式文本处理、富文本解析、交互优化等核心技术。通过实战代码示例,帮助开发者实现类似DeepSeek的AI产品交互效果,提升用户体验和应用专业度。

weixin_28358083的博客 197

Spring Cloud消费者集成报错,因为我用的springboot 2.X

折腾两天了,各种奇奇怪怪的问题,因为网上大多数版本都是1.X的都是比较早期的版本的,官方最新的是2.X版本的的,所以我决定整2.x版本的,如果遇到了以下问题,基本上都是feign的版本选择的问题,因为官方文档也没有说名集成的时候用那几个版本的jar,可以尝试下用以下代码: <dependency> <groupId>org.sp...

记录下日常遇到的问题或者一些思考,不喜勿喷 3392

阿里平头哥与华为芯片的比较

阿里平头哥与华为芯片代表了中国AI芯片领域的两种典型发展路径:平头哥通过兼容CUDA生态快速切入市场,以较低成本提供接近国际水平的AI算力;华为则坚持全栈自研路线,构建从芯片到框架的完整技术体系,更注重供应链安全和自主可控。从短期来看,平头哥PPU在单卡性能参数上全面超越昇腾910B,接近英伟达H20水平,且成本优势明显,有望在云服务和互联网应用领域取得更大市场份额。而华为昇腾则凭借全栈自研和端边云协同优势,在政企市场和科研领域更具竞争力。

shao.bing的专栏 3966

Hystrix 源码解析 —— 请求执行(四)之失败回退逻辑

摘要: 原创出处 http://www.iocoder.cn/Hystrix/command-execute-fourth-fallback/ 「芋道源码」欢迎转载,保留摘要,谢谢!本文主要基于 Hystrix 1.5.X 版本 1. 概述 2. handleFallback 3. #handleShortCircuitViaFallback() 4. #handleSemaphoreRejec

天黑了 7155

RabbitMq安装

本文详细介绍了在CentOS7系统上离线部署RabbitMQ4.3.2的完整流程。主要内容包括:1)准备RabbitMQ安装包、Erlang依赖和socat网络工具;2)安装系统编译依赖并编译安装Erlang;3)部署RabbitMQ服务,配置环境变量和socat依赖;4)启用Web管理插件并创建管理员账号;5)配置防火墙放行端口;6)设置Systemd开机自启服务;7)提供常用运维命令。文档特别强调离线部署注意事项,包括socat依赖、版本兼容性、账号安全及主机名配置等问题,为生产环境部署提供完整解决方案

sinat_25821779的博客 321

一步一步搭建S32K14x的AutoSar项目----S32DS 代码工程的搭建

一步一步搭建S32K14X的AutoSar项目----S32DS代码工程的搭建

wo580231的博客 3487

java.lang.OutOfMemoryError处理错误

java.lang.OutOfMemoryError异常解决方法   原因: 常见的有以下几种: 1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据; 2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收; 3.代码中存在死循环或循环产生过多重复的对象实体; 4.使用的第三方软件中的BUG; 5.启动参数内存值设定的过小; 常见错误提示: 1.tomcat:jav...

weixin_33816821的博客 538

YOLOv8+BiFPN双向特征金字塔:多尺度目标检测精度提升28%的实战教程

双向特征金字塔网络(BiFPN)是一种强化多尺度特征融合支持“自顶向下+自底向上”的双向特征流动,同时保留不同尺度的细节信息;引入加权融合机制,自动学习不同特征的重要性权重;裁剪冗余节点,在轻量化的同时提升融合效率。

m0_64661770的博客 492

Flinksql关于日期截取字段报错SQL parse failed. Encountered “, DAY“

Flinksql关于日期截取字段报错SQL parse failed. Encountered ", DAY"

远方的博客 2539

Chamfer Loss

ChamferLoss是一种常用于3D点云(pointcloud)处理的损失函数,特别是在点云生成和对齐任务中。它的目的是度量两个点集之间的相似度,特别是在点云重建、配准或生成等任务中,常用于优化模型使得生成的点云更接近真实的点云。

夜空中明亮的星的专栏 454

信号的反射(振铃、台阶、回勾、尖峰毛刺)

反射是怎么形成的 假设信号传输过程中,经过两个阻抗不同的区域,如下图所示。区域1阻抗为Z1,区域2阻抗为Z2。 在分界面处,电压必须是连续的,否则,在分界面处会产生无穷大的电场,这在真实世界中是不可能的。 同样,分界面两侧的电流必须是连续的,否则分界面处会产生无穷大的磁场。 因此: 根据欧姆定律,必然有: 显然如果Z1≠Z2的情况下,上面式子不可能同时成立。如何理解这一困境? 应该从 ...

sinat_15677011的博客 1万+

Hystrix失败处理逻辑解析

熔断器打开线程池/信号量跑满调用超时调用失败本篇文章则介绍一下在发生降级时Hystrix的处理细节,下面的方法异常的处理逻辑:final Func1<Throwab...

javaxuexilu的博客 571

OpenClaw 在 Docker 容器中的部署实战——零配置启动

本文介绍了OpenClaw在Docker容器中的快速部署方法,对比了本地部署与容器化部署的优势。通过官方镜像和Docker Compose两种方式,5分钟即可完成部署,并详细讲解了配置管理方案(挂载配置文件和环境变量)。文章还提供了飞书集成配置方法,以及生产环境下的日志管理、资源限制、健康检查等优化建议。最后包含常见问题排查指南,帮助开发者快速实现OpenClaw的容器化部署。

刘一说的IT专栏 902

SpringCloud系列之Hystrix熔断器【待完善】

目录1. 简介2. 实例2.1 在RestTemplate和Ribbon上使用熔断器2.2 在Feign上使用熔断器2.3 使用Hystrix Dashboard 监控熔断器状态2.4 使用Turbine 聚合监控3. 源码解析 1. 简介 Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时,异常等,Hystrix能保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。 “断路器” 本身是一种开关设置,当某个

陆林烽的博客 721

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Hystrix 配置参数全解析

Hystrix 配置参数全解析 前言 不久前在部门周会上分享了 Hystrix 源码解析之后,就无奈地背上了专家包袱,同事们都认为我对 Hystrix 很熟,我们接触 Hystrix 更多的还是工作中的使用和配置,所以很多人一遇到 Hystrix 的配置问题就会过来问我。为了不让他们失望,我把 Hystrix 的配置文档仔细看了一遍,将有疑问的点通过翻源码、查官方 issue、自己实验的方式整理了一遍,这才对 Hystrix 的配置有了一定的了解。 在了解这些配置项的过程中,我也发现了很多坑,平常我们

483

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Hystrix工作流程解析

方法中,首先会判断是否开启熔断器,如果开启则直接进入失败处理的逻辑。否则会尝试获取信号量(如果使用的是线程池的模式则默认获取成功),获取成功进入。7.计算熔断器状态,所有的运行状态(成功, 失败, 拒绝,超时)上报给熔断器,用于统计从而判断熔断器状态。在上面这个方法中会有一个缓存的判断,如果存在缓存的话直接返回结果,否则进入方法。//如果开启请求缓存则查询缓存是否存在。4.判断线程池/信号量是否跑满,如果跑满进入步骤8,否则进入步骤5。6.判断是否调用成功,返回成功调用结果,如果失败进入步骤8。...

lt_xiaodou的博客 354

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

熔断器 Hystrix 源码解析 —— 命令执行(一)之正常执行逻辑

title: Hystrix 源码解析 —— 命令执行(一)之正常执行逻辑 date: 2018-10-22 tags: categories: Hystrix permalink: Hystrix/command-execute-first-run摘要: 原创出处 http://www.iocoder.cn/Hystrix/command-execute-first-run/ 「芋道源码」

芋艿V 888

soul网关源码学习17-hystrix插件解析(下)

soul网关源码学习17-hystrix插件解析(下) 目标: 了解hystrix的底层实现 实现步骤 使用命令模式将所有对外部服务(或依赖关系)的调用包装在HystrixCommand或HystrixObservableCommand对象中,并将该对象放在单独的线程中执行; 每个依赖都维护着一个线程池(或信号量),线程池被耗尽则拒绝请求(而不是让请求排队)。 记录请求成功,失败,超时和线程拒绝。 服务错误百分比超过了阈值,熔断器开关自动打开,一段时间内停止对该服务的所有请求。 请求失败,被拒绝,超时

m0_54065725的博客 380

SpringCloud容错处理:Hystrix源码分析

容错处理 容错处理是指软件运行时,能对由非正常因素引起的运行错误给出适当的处理或信息提示,使软件运行正常结束 从解释中可以看出,简单理解,所谓的容错处理其实就是捕获异常了,不让异常影响系统的正常运行,正如java中的try catch一样。 而在SpringCloud微服务调用中,自身异常可自行处理外,对于依赖的服务若发生错误,或者调用异常,或者调用时间过长等原因时,避免长时间等待,造成...

琦彦 2215

SpringCloud微服务架构实战:Feign+Hystrix实现RPC调用保护

学习技术一定要制定一个明确的学习路线,这样才能高效的学习,不必要做无效功,既浪费时间又得不到什么效率,大家不妨按照我这份路线来学习。大家不妨直接在牛客和力扣上多刷题,同时,我也拿了一些面试题跟大家分享,也是从一些大佬那里获得的,大家不妨多刷刷题,为金九银十冲一波!《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!学习总结学习技术一定要制定一个明确的学习路线,这样才能高效的学习,不必要做无效功,既浪费时间又得不到什么效率,大家不妨按照我这份路线来学习。

2401_84091321的博客 788

Hystrix 源码解析 —— 命令执行(一)之正常执行逻辑

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34414650的博客 179

最新SpringCloud微服务架构实战:Feign+Hystrix实现RPC调用保护,mysql语句优化面试题

谈到面试,其实说白了就是刷题刷题刷题,天天作死的刷。。。。。为了准备这个“金三银四”的春招,狂刷一个月的题,狂补超多的漏洞知识,像这次美团面试问的算法、数据库、Redis、设计模式等这些题目都是我刷到过的并且我也将自己刷的题全部整理成了PDF或者Word文档(含详细答案解析)66个Java面试知识点架构专题(MySQL,Java,Redis,线程,并发,设计模式,Nginx,Linux,框架,微服务等)+大厂面试题详解(百度,阿里,腾讯,华为,迅雷,网易,中兴,北京中软等)算法刷题(PDF)本文已被。

2401_84584583的博客 535
上一篇: Spring干货汇总(含Spring Boot与Spring Cloud)
下一篇: 源码阅读技巧篇
公众号-芋道源码
博客等级 码龄10年 1625粉丝 377原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值