hystrix核心流程图-基于feign
2021-12-22 13:43:44 0 举报
hystrix核心流程图
作者其他创作
大纲/内容
异常降级
初始化
HystrixObservableTimeoutOperator
LoadBalancerFeignClient
获取HystrixCommand.Setter
http请求
Future
schedule
构建一个LoadBalancerCommand该类中构建了重试处理器RequestSpecificRetryHandler
build
获取最大重试数量、最大重试下一次数量
构建
applyHystrixSemantics
正常
从缓存中获取
支撑
创建一个适合ribbon请求的对象
command执行超时检测
ServiceA的invoke方法
terminateCommandCleanup
ReflectiveFeign.newInstance
setRequestContext
Each
targetWithFallback从FeignContext中获取实现了ServiceA的fallback的实例
线程池一个Feign客户端才会创建一个线程池,线程池名称默认就是groupName,serviceA
拿到一个future
订阅OnSubscribe
使用该feign的类中
先校验Feign.Builder的类型是否为HystrixFeign.Builder,不是则走feign默认逻辑,强转Builder类型,并且获取名称(ServiceA),获取SetterFactory这一步都是基于feign.hystrix.enabled=true实现
Observable包含一个command
terminate
将fallback的实例构建成FallbackFactory.Default实例
参数
FeignLoadBalancerIClientConfigILoadBalancerServerIntrospector
singleSemaphoreRelease
接口
信号量的方式这里害的关注信号量释放的回调方法
在client.execute执行完成之后处理返回结果
configureFeign根据是否取默认的配置还是每个feign客户端专用的配置去给builder设置。如果有自己专有的就用自己的覆盖默认的,如果用默认的就用默认的覆盖自己专有的
这里要判断队列默认大小是0,也就是-1,则直接往线程池中调度;如果队列大于0,则线程池的前置队列大小必须小于queueSizeRejectionThreshold阈值
从请求url中剔除ServiceA
构建一个HystrixInvocationHandler的回调,供InvocationHandlerFactory.create使用传入HardCodedTarget、nameToHandler、setterFactory、FallbackFactory 构建。基于Feign解析Spring Mvc的contract构造解析Hystrix的contract
前置等待队列满了
默认值创建线程池1、coreSize = 102、keepAliveTime = 13、queue = new SynchronousQueue<Runnable>
execution的Observable
配置feign
Func0#call()
targetWithFallbackFactory从FeignContext中获取实现了ServiceA的FallbackFactory的实例
执行run的核心逻辑
hystrixObservable(applyHystrixSemantics)
Terminate
handleFallback
Next
工程启动初始化
超时定时器超时校验 默认是1s钟执行一次
不开启
该接口使用该feign
executeWithLoadBalancer
FeignClientFactoryBean
FeignContext每个服务都对应着一个独立的spring容器,核心是一个map的结构
是否执行完毕
wrapWithAllOnNextHooks
loadBalance
构建Feign.Builder
注入
GET http:///user/sayHello/1?name=张三age=20 HTTP/1.1
判断超时状态是否为NOT_EXECUTED,并将其设置为TIMED_OUT
执行时command的状态为OBSERVABLE_CHAIN_CREATED,如果状态为USER_CODE_EXECUTED,则抛出异常
Targeter接入配置Hystrix(feign.hystrix.enabled=true),则使用HystrixTargeter
submit
创建一个FeignLoadBalancer放入缓存,key为ServiceA这里会根据服务名称创建IClientConfig、ILoadBalancer、ServerIntrospector,并放入到FeignLoadBalancer
threadPool.getScheduler
getFallback回调方法
获取command执行结果
构建一个Observable对像
queue().get()
执行时command的状态为OBSERVABLE_CHAIN_CREATED,如果状态为UNSUBSCRIBED,则释放掉observable
使用JDK动态代理创建feign的动态代理对象
选择server
断路器判断circuitBreaker.allowRequest()
返回
ServiceA的动态代理
Spring容器
HystrixCommand执行
线程池动态扩容,根据配置来判断
判断是否设置超时组件
unsubscribe
setterMethodMap
touchConfig
LoadBalancerContext.getServerFromLoadBalancer传入uri和key
Feign.Builder#target实现类HystrixFeign.Builder
FeignClientsConfiguration初始化一系列的组件
队列默认大小是0new SynchronousQueue<Runnable>
HystrixInvocationHandler.invoke
fallbackFactory
线程池的方式
通常来说我们不会为每个feign客户端配置固定的url
executeCommandAndObserve执行command
这个就是feign客户端接口的动态代理实现机制,传入:FeignClientFactoryBeanFeign.BuilderFeignContextHardCodedTarget
如果没有设置降级策略fallbackFactory,则直接抛出异常
未实现降级机制
调度器工作者调度线程ThreadPoolWorker#schedule
unsubscribeCommandCleanup
Completed
从spring容器中取出Feign上下文
执行任务
调用HystrixCommand的run方法
.subscribeOn(threadPool.getScheduler(new Func0<Boolean>() { @Override public Boolean call() { return properties.executionIsolationThreadInterruptOnTimeout().get() && _cmd.isCommandTimedOut.get() == TimedOutStatus.TIMED_OUT; } })
getUserExecutionObservableuserObservable
线程池拒绝
获取ILoadBalancer,并选择serverZoneAwareLoadBalancer实现类选择server的逻辑见ribbon
断路器关闭
create
判断
开启
调用父类(AbstractCommand)构造方法构造
command状态校验
fallback
创建Service客户端的配置
IClientConfig
execute
根据execution.timeout.enabled的配置判断是否需要设置超时组件,默认开启
fireOnCompletedHook
构建HystrixCommand对象HystrixCommand包含run、getFallback两个回调方法
创建线程池
HystrixContextScheduler调度器调度线程
如果command超时状态为TIMED_OUT,则抛出异常
HystrixInvocationHandler#hystrixCommand#run()
构建FeignLoadBalancer
断路器打开:1、circuitBreakerForceOpen = true2、circuitBreakerForceClosed = true,还要根据metrics的总请求数 < circuitBreakerRequestVolumeThreshold3、circuitBreakerForceClosed = true,getErrorPercentage错误百分比小于circuitBreakerErrorThresholdPercentage断路器关闭:1、circuitBreakerForceClosed = true,metrics的总请求数 >= circuitBreakerRequestVolumeThreshold,getErrorPercentage错误百分比 >= circuitBreakerErrorThresholdPercentage
1、构建了一个SynchronousMethodHandler.Factory,2、基于同步方法处理器工厂构建了一个ParseHandlersByName,3、基于InvocationHandlerFactory、QueryMapEncoder、ParseHandlersByName构建了一个ReflectiveFeign
f.isDone()
error
markExceptionThrown
执行时command的状态为NOT_STARTED,并将其设置为OBSERVABLE_CHAIN_CREATED
feign.hystrix.enabled=false
FeignClient的动态代理创建
返回结果
调用feign接口
client.execute
Unsubscribe
根据配置判断资源隔离是用信号量的方式还是用默认的线程池方式。我们使用默认的使用线程池的方式
实际只使用了Feign.Builder、HardCodedTarget
构建worker
1、设置commandGroup(ServiceA)2、设置commandKey(com.demo.ServiceA#sayHello(String)),校验3、设置threadPoolKey,未设置则取commandGroup(ServiceA)4、设置断路器5、设置线程池,名称为threadPoolKey,线程池大小默认为10,等待队列为-16、设置请求缓存,名称为commandKey7、设置请求日志......
ErrorResumeNext
getExecutionObservableOnSubscribe
target
执行时thread的状态为NOT_USING_THREAD,如果不是这个状态则抛出异常,如果是,则将状态更改为STARTED
维护(优先从这里取)
放入缓存
新的
构建HystrixCommand
requestLog启用但不处理
feign构建一个Feign.Builder将FeignContext中的编解码器和Contract封装到Builder中feign.hystrix.enabled=true则默认实现类使用HystrixFeign.Builder
通过当前执行方法获取到HystrixCommand.Setter
executeCommandWithSpecifiedIsolation默认走线程池隔离逻辑
FeignAutoConfiguration初始化一系列的组件
DeprecatedOnRunHookApplication
ReflectiveFeign.newInstance这里创建的不是实现类是HystrixInvocationHandler的FeignInvocationHandler
初始化Feign.Builder组件
ExecutionHookApplication
fallbackMethodMap
getObject()->getTarget()
HystrixContextSchedulerWorker
markEmits
markOnCompleted
断路器打开
feign客户端动态代理实现类
线程状态校验
scheduler.createWorker();
执行报错
动态代理的核心逻辑判断feign客户端(ServiceA)是否实现了降级机制,降级机制有两种实现,如果两种都没有,则走feign默认逻辑,后续逻辑见feign核心分析
RibbonRequest
Feign.Builder
调用ServiceA
缓存不存在
队列满了,或者执行超时了,或者报错了
ILoadBalancer实现类 ZoneAwareLoadBalancer与eureka整合见Ribbon核心流程图分析
直接扔到线程池中
run回调方法
将TimerListener设置到监听HystrixCommand的超时定时器中HystrixTimer,可以看看HystrixTimer的源码
调用者
从FeignContext中获取一个Targeter
requestCache默认不启用
toObservable().toBlocking().toFuture()
0 条评论
下一页