ribbon及feign(nacos-1.4.1)源码流程图
2022-09-01 20:55:51 0 举报
ribbonjifeign源码流程图
作者其他创作
大纲/内容
FeignAutoConfiguration
RibbonAutoConfiguration
2. 将服务实例列表分区
LoadBalancerRequestFactory#createRequest
static final class Default implements InvocationHandlerFactory创建InvocationHandler
InterceptingHttpAccessor
FeignContext
3. 拿到服务实例后去替换掉url中的服务名
LoadBalancerAutoConfiguration
hostReactor.getServiceInfo
requestFactory属性
2. 赋值configurations用于createContext不同服务不同配置
JDK动态代理返回接口的代理对象
@Bean
对目标对象进行去进行代理操作
SimpleClientHttpRequestFactory
extends
从容器中根据类型获取Bean
拼接http://service-name/path
1. 虽然写在定时任务的后面但是先执行,因为定时任务不是立即执行,第一次是延迟1s执行
2. 否则没有设置
AbstractBufferingClientHttpRequest
创建定时任务
参数
FeignClientProperties
DefaultFeignLoadBalancedConfiguration
用RestTemplateCustomizer定制所有有@LoadBalanced注解的RestTemplate
FeignClientConfigurer
LoadBalancerInterceptor
2. lamda表达式过来,如果拦截器都执行完了那么执行else
setServerListForZones(serversInZones)
父容器getBean
InterceptingClientHttpRequest
builder
updateAction.doUpdate()
根据配置去构建feign
InterceptingClientHttpRequest#executeInternal
容器中找Client类型的BeanLoadBalancerFeignClient
1. 拦截器还没有处理完则继续执行拦截器
执行父类BaseContractd的方法里面会穿插执行子类SpringMvcContract的方法
LoadBalancerInterceptor#intercept
context
initialize(request)
restOfInit(clientConfig)
容器中找Targeter类型的bean
这里涉及了局部和全局配置的判断
feign源码入口
注册beanFeignClientSpecificationconfiguration属性全局配置
updateListOfServers()
new RibbonLoadBalancerClient(springClientFactory())
源码入口
ServerList
2. 延迟的定时任务去更新服务列表(第一次延迟1s,后面的30s)
run方法中执行lamda表达式
2. 让负载均衡器去选取服务实例
feign(context)
给每个RestTemplate都添加一个LoadBalancerInterceptor
applicationContext.getBean(FeignContext.class)
NamedContextFactory<FeignClientSpecification>
@EnableConfigurationProperties
getServers
createContext创建子容器的时候去register配置类
initWithConfig
2. 更新
FeignClientFactoryBean.getObject()
AbstractBufferingClientHttpRequest#executeInternal
HttpAccessor
定位到@LoadBalanced注解所在包找AutoConfiguration或者Configuration
使用configuration
RestTemplateCustomizer
ReflectiveFeign.newInstance(Target<T> target)
AbstractClientHttpRequest
1. 获取ClientHttpRequestFactory
getTarget()
子容器中注册,每个服务一个子容器
serverListImpl.getUpdatedListOfServers()
enableAndInitLearnNewServersFeature()
LoadBalancerRequestFactory
创建jdk动态代理
1. 将服务实例列表赋值给父类BaseLoadBalancer 的属性allServerList
LoadBalancerFeignClient#execute
@LoadBalanced@Autowired(required = false)private List<RestTemplate> restTemplates
lamda表达式定制RestTemplate
@Bean@ConditionalOnProperty(\"ribbon.eager-load.enabled\")RibbonApplicationContextInitializer
BaseLoadBalancer
HttpClientFeignLoadBalancedConfiguration
FeignRibbonClientAutoConfiguration
设置Server的定时Ping任务
super初始化父类
loadBalancer.chooseServer(hint != null ? hint : \"default\")
走ribbon替换uri中的service name
AbstractClientHttpRequestFactoryWrapper
configureUsingConfiguration
InterceptingClientHttpRequestFactory
AbstractClientHttpRequestFactoryWrapper-> InterceptingClientHttpRequestFactory
FeignHttpClientProperties
context.setConfigurations(this.configurations)
IRule
@AutoConfigureBefore
@LoadBalanced@BeanRestTemplate
AbstractBufferingClientHttpRequest#executeInternal(HttpHeaders)
OkHttpFeignLoadBalancedConfiguration
RibbonClientConfiguration
1. this.requestFactory.createRequest
SpingMvcContract
RibbonLoadBalancerClient#execute
轮询算法,从0开始计数,每次+1然后对实例列表取模得到实例的数组的下标值
ribbonServerList()
request.apply(serviceInstance)
PollingServerListUpdater
@EnableFeignClients
IPing
1. super初始化父类
子容器getBean
1. 从容器中取负载均衡器ILoadBalancer的bean
NacosRibbonClientConfiguration
PollingServerListUpdater#start
@Autowired(required = false)private List<FeignClientSpecification> configurations
rule.choose(key)
去整合ribbon
AbstractClientHttpRequest#execute
LoadBalancerClient
@import
serverListUpdater.start(updateAction)
configureUsingProperties
onApplicationEvent(ApplicationReadyEvent event)
@Bean@ConditionalOnMissingBeanpublic ServerList<Server> ribbonServerList(IClientConfig config)
每个服务创建一个spring容器配置里可以配置哪几个服务是要启动加载
@AutowiredStockservice
targetToHandlersByName.apply(target)
1. 如果RestTemplate中设置了拦截器
PredicateBasedRule#choose
@ConditionalOnMissingBean会找去父容器找有没有该类型的bean,所以这个bean不会加载
子流程
注册FeignClientSpecification自定义扫描器注册FactoryBeanFeignClientFactoryBeangetObjectType是@FeignClient注解的类型
super.getRequestFactory()
SynchronousMethodHandler
去执行lamda表达式
NacosNamingService#selectInstances
request.execute()
SimpleBufferingClientHttpRequest
配置文件>java配置
ClientHttpResponse
Ribbon对外提供的一个扩展口用于更新服务实力列表,NacosServerList实现了该接口从而让ribbon能获取nacos的服务实例列表
BaseContract#parseAndValidateMetadata
type是@FeignClient注解的接口类型
默认ZoneAvoidanceRule
父容器已有
怎么找RibbonAutoConfiguration?- 1.LoadBalancerAutoConfiguration有个@ConditionalOnBean(LoadBalancerClient.class)- 2. LoadBalancerClient接口就一个实现类RibbonLoadBalancerClient- 3. 看实现类在哪个AutoConfiguration或者Configuration中用到了(根据接口去找也行就是范围大点)
targetRequest(template)
super.chooseServer(key)-> BaseLoadBalancer#chooseServer
eligible.get(incrementAndGetModulo(eligible.size()))
spring容器初始化完成后发布事件去更新服务列表
将RequestTemplate适配成Request这里会去执行拦截器interceptor.apply(template)
DefaultTargeter
requestFactory
this.springClientFactory.getContext(clientName)
SynchronousMethodHandler#invoke
取client的本地缓存,没有则去server拉取服务实例列表
new FeignLoadBalancer.RibbonRequest
contract.parseAndValidateMetadata(target.type())
request.getURI()替换服务名为服务实例ip
用到了父子容器,SpringClientFactory有个ApplicationContextAware回调塞入parent,手动创建的容器会设置该parent为父容器
2. 创建定时任务更新服务列表
setServersList(ls)
2. 从factory中创建request
updateAllServerList(servers)
super.setServersList(lsrv)
this.clientFactory.getLoadBalancer(serviceId)
ServiceRequestWrapper#getURI
DynamicServerListLoadBalancer
NacosServerList
dispatch.get(method).invoke(args)
new InterceptingRequestExecution()
lamda表达式创建LoadBalancerRequest匿名类对象
SpringClientFactory
@Bean用来去对target进行动态代理
2. this.loadBalancer.execute
使用配置文件
@BeanribbonLoadBalancer()
1. 走父类
InterceptingHttpAccessor.getRequestFactory()
替换
inheritParentConfiguration
3. 一个扩展点,可以去处理header
OrderService接口执行方法进入代理逻辑执行invoke方法
response使用decoder类型转换成方法的返回类型
getLoadBalancer(serviceId)
ribbon.eager-load.enabled默认是false,就是服务在第一次使用的时候去拉取(这个配置类应用启动不会去加载,用到的时候去手动拆创建容器,每个服务都会创建自己的一个spring容器)
SmartInitializingSingleton
setPingInterval(pingIntervalTime)
RibbonNacosAutoConfiguration
FeignClientsConfiguration
1. 从nacos客户端本地缓存没有去拉取nacos server服务实例列表
for (final Method method : targetType.getMethods()) {遍历接口的所有方法,static方法continue解析类、方法、方法参数上的mvc注解,封装到MethodMetadata中最后返回MethodMetadata的list集合MethodMetadata:实际就是方法元数据,会将Class的uri和method的拼接,将HttpMethod、Header、Consumer、Producer等封装进来}
restTemplate.getForObject(\"http://stock-service/test/ribbon\
exececute -> doExecute
0 条评论
下一页