先来看两个本次我们项目当中出现的异常(出异常时系统未配置hystrix参数)
Caused by: java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@28ee4bd7 rejected from java.util.concurrent.ThreadPoolExecutor@58ab318d[Running, pool size = 10, active threads = 10, queued tasks = 0, completed tasks = 143639]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
at com.netflix.hystrix.strategy.concurrency.HystrixContextScheduler$ThreadPoolWorker.schedule(HystrixContextScheduler.java:172)
at com.netflix.hystrix.strategy.concurrency.HystrixContextScheduler$HystrixContextSchedulerWorker.schedule(HystrixContextScheduler.java:106)
at rx.internal.operators.OperatorSubscribeOn.call(OperatorSubscribeOn.java:50)
at rx.internal.operators.OperatorSubscribeOn.call(OperatorSubscribeOn.java:30)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
... 161 common frames omitted
Exception in thread "Thread-23" com.netflix.hystrix.exception.HystrixRuntimeException: OrderQueryClient#orderDetail(String) fallback execution rejected.
异常原因
解释下这两个异常出现的原因
RejectedExecutionException
hystrix 默认的策略模式为 THREAD,并且默认核心线程为10,其队列默认使用 SynchronousQueue,也就是最大并发只能到10,超过则直接拒绝,然后走降级逻辑
HystrixRuntimeException:fallback execution rejected.
这个异常表明 降级逻辑执行被拒绝,hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests 默认值为10,表明降级执行超过10并发,则会抛出此异常
修改参数配置
# 参考配置如下
hystrix:
# === === === == 默认Command === === === ==
command:
default:
# 降级信号量控制
fallback:
enable: true
isolation:
semaphore:
maxConcurrentRequests: 200
execution:
isolation:
# 调用隔离方式, 默认: 采用线程隔离, ExecutionIsolationStrategy:THREAD
strategy: THREAD
# 调用超时时间, 默认: 5 秒
thread:
timeoutInMilliseconds: 30000
# === === === == 熔断器 === === === ==
circuitBreaker:
# 熔断器在整个统计时间内是否开启的阀值, 默认20个请求
requestVolumeThreshold: 1000
# 熔断器默认工作时间, 默认: 5 秒
sleepWindowInMilliseconds: 5
# 默认: 50%, 当出错率超过50% 后熔断器启动
errorThresholdPercentage: 50
# 是否强制开启熔断器阻断所有请求, 默认: false, 不开启
forceOpen: false
# 是否允许熔断器忽略错误, 默认false, 不开启
forceClosed: false
threadpool:
default:
# 并发执行的最大线程数,默认10
coreSize: 400
# SynchronousQueue
maxQueueSize: -1
# 线程生存时间, 默认1分钟
keepAliveTimeMinutes: 2
后记思考
hystrix 的 Isolation 策略默认是服务间隔离,隔离方式有两种:线程池、信号量
默认是采用线程池隔离,从而某个服务出现问题时,不会影响其他服务(底层执行只会命中对应的池然后池溢出降级)
但是此时我们项目的场景比较单一,它仅仅是两个单体项目之间的调用:A->B,其中涉及非常多的接口,而我们微观来看,实际上也不想让某些“非核心”接口,影响了其他核心接口的调用,这其实就需要hystrix提供更细粒度的断路器配置