04_Ribbon Feign Hystrix Zuul流程
2024-05-23 21:49:30 2 举报
Ribbon Feign Hystrix Zuul源码剖析
作者其他创作
大纲/内容
拉取 server list
是否抛异常
LoadBalancerRequestFactory创建的一个LoadBalancerRequest的匿名实现类
invocationHandlerFactory 的HystrixInvocationHandler
FeignLoadBalancer
queue()返回一个Future
Future创建可以interruption的Future,这个Future是前一个的Wrap类。
ILoadBalancer负载均衡器
Eureka Server
UpdateAction.doUpdate()持续更新 其实还是调用拉取所有server list的方法
缓冲队列是否有可用空间threadPool.isQueueSpaceAvailable()
父类 BaseLoadBalancer chooseServer()
threadPool
FilterProcessorrunFilters()
注入
markOnCompleted
restOfInit()方法
HystrixThreadPoolDefault
ServerListUpdaterstart()
updateListOfServers()拉取所有server list
getURI()根据筛选出的server 返回最终物理请求地址
返回
postRoute
不开启
动态代理 T Proxy
默认没配置maxQueueSize
AbstractServerPredicatechooseRoundRobinAfterFiltering()
1、Hystrix会给每个HystrixCommand设置一个超时器2、超时器本身是一个ScheduledThreadPoolExecutor(定时调度线程池),他会在你设定的executionTimeoutInMilliseconds超时时间之后开始执行,如果在超时时间command没有执行,就修改状态为timeout,并抛出HystrixTimeoutException触发超时流程。3、当command执行完后如果没有超时,会通过isNotTimedOut()将TimedOutStatus状态改为COMPLETED,这样timerListener在判断超时的时候,就不会触发超时了。4、command执行完会将timer清理掉。
ZuulRunner此类将servlet请求和响应初始化为RequestContext,并将FilterProcessor调用包装到preRoute(),route(),postRoute()和error()方法
调用RibbonLoadBalancerClient的reconstructURI 完成 URI 的拼接
返回 ObservableuserObservable
Action0terminateCommandCleanup
父类:AbstractLoadBalancerAwareClientexecuteWithLoadBalancer()
setupPingTask()开启 Timer 定时任务来检测server list中的server 是否可用
Action0unsubscribeCommandCleanup
handleFallback
MethodHandler
LoadBalancerInterceptor
Func0ObservableapplyHystrixSemantics
route
spring的HttpRequest 对象 ServiceRequestWrapper
EurekaRibbonClientConfiguration配置组件
超时HystrixObservableTimeoutOperator
true
如果启用feign.hystrix
Feign.Builderbuild()
Observable afterCache = hystrixObservable
lift超时设置
网络请求LoadBalancerRequestapply()
zuulServletservice()
从配置上下文中获取类型为ILoadBalancer 的对象
执行我们自己构建的HystrixCommand的run()方法HystrixInvocationHandler的invoke中创建的hystrixCommand
initWithConfig()
hystrix 流程
调用父类Feign.Builderbuild()
getCacheKey()是否为null
get()
100 SimpleHostRoutingFilter简单配置的方式走这个filter,就是直接配置host地址,不需要ribbon的。直接通过httpclient请求然后返回CloseableHttpResponse
回调
markEmits
Zuul 流程
返回threadPool
feign 结合ribbon + hystrix流程
preRoute
构建ThreadPoolExecutor
Feign
-1 FormBodyWrapperFilterMediaType为APPLICATION_FORM_URLENCODED和MULTIPART_FORM_DATA才会执行(默认不执行)
Observable 包含5个回调对象
servicehystrix动态代理service
schedule()
false
构造一个 HystrixThreadPoolDefault的默认线程池
feign 结合ribbon流程
动态代理对象 T Proxy
返回 Observable
maxQueueSize=0
doOnSubscribe
调用 ReflectiveFeign.newInstance() 方法,创建绑定对象 Feign创建动态代理对象的核心方法
配置了maxQueueSize
error
Eureka Client
是否有缓存
Futuredelegate创建不能interruption的Future
-2 Servlet30WrapperFilterRequestContext中设置request为Servlet30RequestWrapper,其中包装了原生的HttpServletRequest
LoadBalancerAutoConfiguration 配置组件
先执行请求,随后放入缓存
拿到ServiceName对应的所有server list放到 BaseLoadBalancer的 allServerList
Func0.call()
ZoneAwareLoadBalancer
Spring的基础网络组件ClientHttpRequestExecution请求最终的物理地址
RibbonLoadBalancerClient 轮询负载均衡客户端execute()
1000 SendResponseFilter将响应结果返回给浏览器
ServerList
开启
不为空
先尝试从 HystrixRequestCache中获取
preRoute(sType)
LinkedBlockingQueue(maxQueueSize)
动态代理关键对象 FeignInvocationHandler
打印日志
900 LocationRewriteFilter如果是30x转发,就执行这个过滤器,默认不执行
放入线程池提交ThreadPoolExecutor.submit()
获取
RibbonAutoConfiguration配置组件LoadBalancerClient = RibbonLoadBalancerClient
-3 ServletDetectionFilterRequestContext中设置isDispatcherServletRequest = true
LoadBalancerFeignClientexecute()
调用 Feign.target() 方法1、构建 ReflectiveFeign2、返回 代理对象
semaphore还是threadPoolexecutionSemaphore.tryAcquire()
InvocationHandlerFactory控制反射方法调度
applyHystrixSemantics的call() 方法返回 Observablereturn applyHystrixSemantics(_cmd)( _cmd 代表的this,也就是hystrixCommannd本身)
执行command逻辑executeCommandAndObserve(_cmd)
getExecutionObservable()
setRequestContext
LoadBalancerInterceptor拦截器
之后就和上面Feign创建出最终的 T proxy 动态代理对象一致了。关键是这个T proxy中的invocation handler是 HystrixInvocationHandler
HystrixTimer.getInstance()创建调度线程池,默认size=4ScheduledThreadPoolExecutor
SynchronousQueue
返回真实的server 地址
获取fallback或者fallbackFactory
SynchronousMethodHandlerinvoke()接口方法的具体实现
ThreadPoolWorker.schedule()
通过父类AbstractCommand初始化HystrixRequestCache
hystrixCommand.execute()
toObservable().toBlocking().toFuture();
返回Response
BlockingQueue workQueue = getBlockingQueue(maxQueueSize)
10 RibbonRoutingFilter1、构建 RibbonCommandContext,包含request Header,request Params,request Body,uri 等请求服务所需要的一切。2、构建 RibbonCommand ,并执行RibbonCommand的execute()方法。RibbonCommand的实现类是HttpClientRibbonCommand父类是HystrixCommand,所以这里说明是直接执行hystrix的execute()方法。
subscribeOn
找出最终的目标server
RestTemplate所有标记 @LoadBalanced 的 RestTemplate 的bean 集合
返回 ObservableObservable afterCache = HystrixCachedObservable
构建HystrixRequestCache
DomainExtractingServerListgetUpdatedListOfServers()
setPing()
到头来还是通过ZoneAwareLoadBalancerchooseServer()
通过父类AbstractCommand初始化threadPoolinitThreadPool()threadPoolKey = 我们定义的@FeignClient中的name。
给每个 RestTemplate 注入拦截器
super.invocationHandlerFactory给父类的 invocationHandlerFactory 赋值,这个factory返回 HystrixInvocationHandler
RibbonClientConfiguration配置组件ILoadBalancer = ZoneAwareLoadBalancerServerListUpdater = PollingServerListUpdaterIRule = ZoneAvoidanceRule
FilterProcessor按类型运行自定义过滤器
Command状态改变 :commandStateNOT_STARTED -- OBSERVABLE_CHAIN_CREATED
controller
Y
HystrixTargeter
回调ServerOperation.call(Server)
DiscoveryEnabledNIWSServerListgetUpdatedListOfServers()
构建HystrixContextScheduler
构建出 ReflectiveFeign
RestTemplateCustomizer
Command状态改变 :commandStateOBSERVABLE_CHAIN_CREATED -- USER_CODE_EXECUTED
如果大于了rejection的数量,直接抛异常RejectedExecutionException
FilterLoadergetFiltersByType()
HystrixConcurrencyStrategy
500 SendForwardFilter转发给自己的controller
构建HystrixCommand重写 run() 和 getFallback()
getUserExecutionObservable(_cmd)
executeCommandWithSpecifiedIsolation(_cmd)
构建RequestCacheKey由 type、key和从currencyStrategy构成type的作用是区分collapser和commandkey 就是 HystrixCommandKey.name()比如:CompanyService#hello(String)
IRuleZoneAvoidanceRule父类 PredicateBasedRulechoose()
HystrixObservableTimeoutOperator.call()
请求
feign流程
空
初始化默认配置touchConfig()
返回,并放入缓存
1、target.type().getClassLoader() HardCodedTarget的type就是那个@FeignClient接口的Class2、new Class<?>[]{target.type()} @FeignClient接口3、上面的 FeignInvocationHandler 最终构建出 JDK动态代理对象Proxy
无
HystrixContextScheduler.createWorker()构建HystrixContextSchedulerWorker
转换为HystrixFeign.Builder
获取最终请求的serverselectServer
默认threadPool的queue长度是-1,所以这里直接返回true
HystrixInvocationHandler#invoke()
有
加载默认配置关键在于根据我们配置的queue的大小(maxQueueSize)来改变线程池的排队行为
标记了@FeignClient的接口
是否开启缓存requestCacheEnabled
父类DynamicServerListLoadBalancer初始化
ribbon流程
IPing
处理并返回handleRequestCacheHitAndEmitValues()
断路器circuitBreaker
父类BaseLoadBalancer
Request
订阅的时候,保存执行这个command的thread,方便我们执行interrupt。
toObservable()
发送请求
ZuulRunnerpreRoute()
订阅这个Observable的时候触发threadPool.getScheduler()
ThreadState状态改变 :threadStateNOT_USING_THREAD -- STARTED
ZoneAvoidanceRule进行server list过滤,选出同机房的server
super.contract()设置注解解析器HystrixDelegatingContract
ZuulFilterrunFilter()
Observable afterCache包含5个回调对象
执行请求LoadBalancerCommand.submit(ServerOperation)
解码ResponseEntityDecoderdecode()根据 metadata.returnType 返回实体对象,这个returnType就是实体对象那个类类型
restTemplate发送请求
构建TimerListener重写tick()方法,设置超时状态并抛异常
执行
Action0 fireOnCompletedHook
1 DebugFilterzuul.debug.parameter=true才会执行,才会打印日志(默认不执行)
Default implements InvocationHandlerFactorycreate() 创建 InvocationHandler 对象
enableAndInitLearnNewServersFeature()定时获取最新的server list
HystrixFeign.Builderbuild()
1、如果TimedOutStatus是NOT_EXECUTED状态,就将TimedOutStatus变为TIMED_OUT2、抛出HystrixTimeoutException
invocationHandlerFactory
如果queue的size小于配置的queueSizeRejectionThreshold返回 true , 否则false
构造:LoadBalancerCommand
0 条评论
下一页