关系经济人类预测化学自然
中准网
自然科学
知识物理
化学生物
地理解释
预测理解
本质社会
人类现象
行为研究
经济政治
心理结构
关系指导
人文遗产

JSF源码分析

11月15日 海岸线投稿
  作者:京东零售李孟东架构设计
  1。7。4HOTFIXT4版本包布局及简要含义
  看过了全包的简要,那么其核心的功能模块,就从常用的项目xml配置出发,便于我们的理解。如下:jsfprovider。xml配置
  以我们地址服务的jsfprovider。xml文件为例,即:
  可以看到,在JSF的配置文件中,我们并没有看到任何关于注册中心的内容。说到底,作为(集团自主研发的高效)RPC调用框架,其高可用的注册中心重中之重,所以带着这份疑惑,继续往下探究,没有注册中心地址,这些标签是怎么完成服务的注册,订阅的。配置解析
  在Spring的体系中,Spring提供了可扩展Schema的支持,即自定义的标签解析。
  1、首先我们发现配置文件中自定义的xsd文件,在标签名称上找到NamespaceUri链接http:jsf。jd。comschemajsfjsf。xsd
  2、然后根据SPI加载,在METAINF中找到定义好Spring。handlers文件和Spring。schemas文件,一个是具体的解析器的配置,一个是jsf。xsd的具体路径Spring。handlers文件内容:http:jsf。jd。comschemajsfcom。jd。jsf。gd。config。spring。JSFNamespaceHandlerSpring。schemas文件内容:http:jsf。jd。comschemajsfjsf。xsdMETAINFjsf。xsd
  3、由此我们进一步查询继承NameSpaceHanderSupport或者实现NameSpaceHandler对应的接口类,在我们的jsf框架中JSFNamespaceHandler是采用继承前者(NameSpaceHanderSupport)去实现的,即:com。jd。jsf。gd。config。spring。JSFNamespaceHandler
  【补充】NamespaceHandler的功能就是解析我们自定义的JSF命名空间的,为了方便起见,我们实现NamespaceHandlerSupport,其内部通过BeanDefinitionParser对具体的标签进行处理,即对我们定义的标签进行具体处理。com。jd。jsf。gd。config。spring。JSFBeanDefinitionParserparse
  4、最终这些配置(也就是我们在xml中配置的标签值)会解析成为ServerConfig和ProviderConfig,并且会依据所配置的属性,对相应的类进行属性的赋值。com。jd。jsf。gd。config。ServerConfig
  com。jd。jsf。gd。config。ProviderConfig
  初始化
  OK,我们回到JSFNamespaceHandler看一下服务是如何暴露的。众所周知,在Spring容器中的bean一定会经历一个初始化的过程。所以通过com。jd。jsf。gd。config。spring。JSFBeanDefinitionParser实现org。springframework。beans。factory。xml。BeanDefinitionParser来进行xml的解析,另外通过ParserContext中封装了BeanDefinitionRegistry对象,用于BeanDefinition的注册,用来初始化各个bean,即(com。jd。jsf。gd。config。spring。JSFBeanDefinitionParserparse)。
  如下:bean类ProviderBean会监听上下文事件,并且当整个容器初始化完毕之后会调用export()方法进行服务的暴露。com。jd。jsf。gd。config。spring。ProviderBean
  服务暴露
  我们回到源码中,发现其核心代码逻辑如下图:com。jd。jsf。gd。config。ProviderConfigdoExport
  com。jd。jsf。gd。config。ProviderConfigdoExport该方法的整体逻辑如下:
  1、首先进行各种基本的校验和拦截,如:〔JSF21200〕provider的alias不能为空;〔JSF21202〕providerconfig的server为空;〔JSF21203〕同一接口alias的provider配置了多个;。。。
  2、其次获取所有的RegistryConfig,如果获取不到注册的地址,那么就会走默认的注册中心地址:i。jsf。jd。com。
  com。jd。jsf。gd。config。RegistryConfig
  3、然后获取provider中配置的server,如果provider中存在server相关的配置,即是com。jd。jsf。gd。config。ServerConfig,此时会启动server(serverConfig。start()),并且采用默认对应的序列化方式(serverConfig。getSerialization(),默认msgpack)进行注册服务编码。com。jd。jsf。gd。config。ServerConfigstart(服务启动)
  4、start方法中会调用ServerFactory中的方法产生相对应的对象,然后会调用Server中的方法去启动Server,而在这个过程中,最终会对应到ServerTransportFactory产生相应的传输层,即是定位到JSFServerTransport的start()方法,在这里我们可以看到,该部分实现了netty框架的transport层,在进入这个方法的时候,会根据是否配置使用epoll模型来选择所生成的对象是EpollServerSocketChannel或者NioServerSocketChannel,然后在ServerBootStrap中初始化相关的参数,直到最后绑定好端口号。com。jd。jsf。gd。server。ServerFactoryinitServer
  com。jd。jsf。gd。transport。JSFServerTransportstart
  5、最后通过(this。register();)服务注册并且暴露出去,其中JsfRegistry这个类的对象,在该类的构造函数中会连接jsf的注册中心,如果注册中心不可用的话,会生成并使用本地的文件并且开始守护线程,并使用两个线程池去发送心跳检测以及重试机制,另外一个线程池去检测连接是否成功(com。jd。jsf。gd。registry。JSFRegistryaddRegistryStatListeners)。com。jd。jsf。gd。registry。JSFRegistry
  6、服务注册(com。jd。jsf。gd。registry。JSFRegistryregister)的过程会将对应的ProviderConfig转换为JsfUrl类,这里JsfUrl是整个框架的核心,他保存了一系列的配置,并且和其同样重要的还有订阅Url类SubscribeUrl,这里JsfUrl属于服务Url,服务Url中保存了协议,端口号,ip地址等相关重要的信息,并且回到上层JsfContext会将配置信息维护起来(JSFContext。cacheProviderConfig(this);)。到这里(this。)provider的服务从配置装配到服务暴露就完成了。com。jd。jsf。gd。registry。JSFRegistryregister
  com。jd。jsf。vo。JsfUrl
  jsfconsumer。xml配置
  以上是完成了provider服务的暴露,那么我们回到consumer中,看一下,如下:
  我们在上方的配置文件中发现到了注册中心地址i。jsf。jd。com,也就是说服务注册相关的配置没有写到jsfprovider。xml端,只是配置到了jsfconsumer。xml中而已。配置解析初始化
  配置解析过程是同上,就不多做赘述了,最终这些配置会解析成为ConsumerConfig和RegistryConfig,并且会依据所配置的属性,对相应的类进行属性的赋值。com。jd。jsf。gd。config。ConsumerConfigAbstractConsumerConfig
  最终初始化映射到ConsumerBean类。com。jd。jsf。gd。config。spring。ConsumerBean
  服务订阅
  不过我们发现其实现了FactoryBean,如我们所了解的,如果一个bean实现了该接口(FactoryBean),它被用作一个对象的工厂来暴露,而不是直接作为一个将自己暴露的bean实例。这也就意味着需要调用getObject()来获取真正的实例化对象(可能是共享的或独立的)。之所以这样使用的原因在于我们的Consumer端只能调用接口,接口是无法直接使用的,它需要被动态代理封装,产生代理对象,再把它放入Spring容器中。因此使用FactoryBean其实只是为了方便创建代理对象而已。
  在getObject()方法中ConsumerBean会调用子类consumerConfig的refer()方法,从而开始了客户端的初始化的过程。在refer()过程中,consumer会去订阅相关的provider的服务。核心代码如下:
  com。jd。jsf。gd。config。ConsumerConfigrefer
  该方法的整体逻辑为,如下:
  1、首先进行各种基本的校验和拦截,如:consumer的alias不能为空,请检查配置同一个接口aliasprotocol本地配置的超过三次,抛出启动异常。。。
  2、一些不同配置的逻辑,如是否泛化调用,是否走injvm调用等
  3、通过工厂模式生成一个Client的实例,由于上面ConsumerConfigAbstractConsumerConfig默认的集群策略failover,所以在没有配置的情况下会生成FailoverClient,然后进行相关的Invoke操作(this。proxyInvokernewClientProxyInvoker(this);)。com。jd。jsf。gd。client。ClientFactorygetClient
  【补充】目前JSF支持的集群策略有,failover:失败重试(默认);failfast:失败忽略;pinpoint:定点调用;
  4、在client中,先定义其负载均衡,然后判断是否需延迟建立长链接。否的话,会直接进行初始化连接。其次如果未定义路由规则,或者不存在连接时,Client会先初始化相关的路由以及初始化连接,如下:
  5、在初始化连接(initConnections)中会进行调用ConsumerConfig中的subscribe()进行服务的订阅,并且在初始化的过程中,consumer会连接相应的Providers。com。jd。jsf。gd。client。ClientinitConnections
  6、我们看到在获取连接过程(connectToProviders())中,如果连接池中已经存在则直接返回,不存在则需要重新建立连接。如下:会初始化一个名为JSFCLICONNinterfaceId的线程池,在线程池中会执行对应任务,即获取到一个ClientTransport对象。com。jd。jsf。gd。client。ClientconnectToProviders
  如果连接(com。jd。jsf。gd。transport。ClientTransportFactoryinitTransport),则:1)首先判断相关协议;com。jd。jsf。gd。transport。ClientTransportFactoryinitTransport
  2)然后BuildChannel建立连接(com。jd。jsf。gd。transport。ClientTransportFactoryBuildChannel),在这里会对应到Server端启动代码的相关参数,即是该处会监听服务器端的端口号,绑定到相应的ip,并根据对应的通道做数据传输。com。jd。jsf。gd。transport。ClientTransportFactoryBuildChannel
  3)并且,对于transport层,我们应该关注他注入了哪些pipeline:可以看到JSFEncoderJSFDecoder用来解码,编码具体的协议。handler则是具体的channel处理器,用于处理心跳包,客户端请求,和消息路由。最后回到最上层(com。jd。jsf。gd。config。ConsumerConfigrefer)将配置文件维护起来(JSFContext。cacheConsumerConfig(this);)。com。jd。jsf。gd。transport。ClientChannelInitializerinitChannel
  综上简单的过了一遍各自功能的初始化加载方式等简单阐述了一下,不过阅读起来肯定是偏零散的,需要我们根据以上步骤和源码包进行进一步探索。另外我们也可以用服务器启动日志上,看到JSF核心流程的日志记录,部分截图如下(感兴趣可以在预发机器的启动日志中翻阅):服务器启动日志(JSF)
  总的来说,其提供者Provider,消费者Consumer,注册Registry等关系应该如下图所示:Architecture
  第一部分:Provider端启动服务向注册中心Session注册自己的服务,注册服务的形式如:〔jsf:192。168。124。73:22000?safVersion210jsfVersion1691interfacecom。jd。wxt。material。service。DspTaskQueueServicealiaschengzhi3642459〕此时在注册服务,暴露服务的过程中,此时JsfRegistry会进行初始化连接。在此过程中,如果有配置对应的Server端,那么还会对Server进行初始化。
  第二部分:Consumer在第一次获取实体信息时,由于其是FactoryBean,故必须调用getObject()方法去获取实体,在此过程会调ConsumerConfig的refer()方法,即可将Client端注册到jsf注册中心并订阅对应alias下Provider的变化。在这个过程中会初始化Consumer以及Provider端的监听器,对相关的Consumer和Provider做事件监听。此过程会产生Client对象,并且在初始化该对象时,会默认的去使用随机的负载均衡策略,并且会初始化路由,初始化路由后,会调用ConsumerConfig的subscribe方法,然后会初始化客户端对之前启动的Server进行连接。
  第三部分:注册中心会异步通知Consumer是否需要重新订阅Provider。
  第四部分:就是直接调用方法invoke。
  第五部分:Monitor对服务进行监控,治理或者降级容灾。流程图
  最终调用,如下:
  com。jd。jsf。gd。filter。FilterChaininvokeResponseMessageresponsethis。filterChain。invoke(requestMessage);
  参考资料
  SPI:http:jnews。jd。comcircleinfodetail?postId215333
  NamespaceHandler:https:www。yisu。comzixun447867。html
  jsf:https:cf。jd。compagesviewpage。action?pageId132108361
  netty:https:www。cnblogs。comjing99p12515149。html
投诉 评论 转载

婴儿出生后,第一个抱他的不要是6种人,有科学依据不知道你们那,有没有婴儿第一抱这么一说呢?我看到有网友说,他们那的说法是,婴儿的第一抱很重要,因为谁第一个抱,孩子以后的性格就像谁。婴儿的第一抱确实很重要。但谁抱他……我为冬奥搬箱子在海拔2000米的云海里工作,累并幸福着《中国经济周刊》记者孙冰北京报道北京冬奥会的精彩绝伦,不仅来自于赛场上冲击更高、更快、更强、更团结的运动健儿,更多默默付出的赛事保障人员、志愿者们也是不应被忽略的幕后英雄……蚝油不是万能提鲜油,切记5不能,做错了坏得快,做菜也难吃各位读者朋友们大家好,感谢阅读我分享的美食文章,经验和大家一起共享,今天我要和大家分享的内容是:蚝油不是万能提鲜油,切记5不能,做错了坏得快,做菜也难吃!蚝油是一种广东传……马斯克入选2021年美国国家工程院院士名单2月10日消息,日前,美国工程院发布2021年度国家工程院增补院士名单,此次共有111名院士及22名外籍院士入选。其中储能领域包括特斯拉创始人埃隆马斯克、LG能源解决方案密歇根……经常手脚冰凉的人有救了!四个保暖药膳,辨证使用效果好不少人一到秋冬就手脚发凉,穿厚衣服、盖厚被子也不易缓解。对于没有基础疾病,但天气稍冷就出现手脚发凉者,采用中医药调理可收到较好的效果。取暖之前先辨证下面列举手……元宇宙资讯宵夜联想将与百度合作推出元宇宙网际展示空间想世界,动态联想将与百度合作推出元宇宙网际展示空间想世界11月9日消息,2022年联想创新科技大会于今日举办。在本次大会上,联想集团董事长兼CEO杨元庆表示,联想正将虚拟现……JSF源码分析作者:京东零售李孟东架构设计1。7。4HOTFIXT4版本包布局及简要含义看过了全包的简要,那么其核心的功能模块,就从常用的项目xml配置出发,便于我们的理解。如下……文创和产业聚合是以口夸村振兴不二出路(通讯员李银娟郎开喜)3月17日,一个集合了楚雄州文旅局、楚雄州州民宗委、楚雄彝族文化研究院、楚雄州广播电视台、楚雄文学院、子午镇、以口村委会和两家文创设计单位的领导、专家和设……经典反特连环画天竺之谜上册(湖美版)。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。……白露到,再忙也要喝碗汤,5道汤任选,滋补防秋燥,全家安度秋莫愁厨路无知己,谁人不识小面姨。大家好,我是小面姨。今天小面姨给大家分享5道汤寀的做法。就在大家陶醉在过中秋节之际,有一个节气又与我们不期而遇。这个节日就是白露。可能大家都没有……北京环球度假区环球中国年主题活动今日开启,生肖角色人气高新京报贝壳财经讯(记者曲筱艺)在北京环球影城,处处可见喜庆的新春气氛。好莱坞大道挂满了象征吉祥如意的传统灯笼;好莱坞大道的尽头,矗立着一棵巨大的环球新春许愿树,满树桃花盛开,成……重磅消息!广药明年或入主广州队,彭伟国成主教练能比郑智靠谱?自从广州队在第18轮联赛以0比0逼平三外援的上海海港之后,坊间对于郑智的执教能力是有所肯定的。为何有此说法?第一、郑智从卡纳瓦罗手里接下这个问题多多的广州队,在几大外援都提前解……
2023年全球设备出货预测出炉,市场形势仍将严峻带鱼里淋2个鸡蛋,学会这样做,5斤都不够吃,出锅连汤汁都不剩详解川式冒烤鸭卤汤底料制作及技术关键原神水神行秋简单培养攻略,毕业参考面板河北平山县,走出了一家世界500强钢铁企业2022年世界50大女足球星排名110,超新星成为巴萨新图腾iQOO11手机开始降价,骁龙8Gen22k屏幕,12GB2Python函数与装饰器Decorator的原理国家能源局发布双碳重大计划末日博士警告如果出现真正硬着陆,美股可能重挫40励志语录坚持不仅仅是一种品质也是一种信念现役四大球星都有哪些优缺点?
英语月日年怎么读英语月日年的读音是什么儿童内衣裤用什么洗涤用品好我这个人五年级学生作文500字观赏鱼怎么养新手养观赏鱼知识金猫榜今晚开播!40集历史大剧来袭,六位国家一级演员加盟,该 理科男的浪漫情书看不懂交通伤残鉴定出院后多久进行鉴定?看见与理解,是亲子沟通的基石为了健康少吃外卖判断婴儿过敏体质的几个标准感动不已婆婆巧手建和谐精选小学作文500字4篇

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找菏泽德阳山西湖州宝鸡上海茂名内江三亚信阳长春北海西安安徽黄石烟台沧州湛江肇庆鹤壁六安韶关成都钦州