Netty自娱自乐之类Dubbo RPC 框架设计构想 【上篇】

  之前在前一篇的《Netty自娱自乐之协议栈设计》,菜鸟我已经自娱自乐了设计协议栈,gitHub地址为https://github.com/vOoT/ncustomer-protocal。先这一篇中,准备接着自娱去实现一个RPC框架,现在公司共的是Dubbo,那么先不看其代码,先自行实现一下吧。

  dubbo 包括 注册和服务调用,细节我们先不管,然后,我先先实现一个如下的简单模型

     

   哈哈哈,第一个版本就是这么简单,粗暴。说到自定义配置,首先想到的是Spring 自定义标签,利用标签进行配置服务。而我设计的标签页非常的简单,使用如下:

    <rpc:provider id="helloServiceImpl" class="com.qee.rpc.HelloServiceImpl"/>

    <rpc:cumsumer id="helloService" interface="com.qee.rpc.HelloService"/>

看到了没,非常像dubbo,那么如何实现一个自定义标签呢,从网上可以了解搜索的到,现在我就简单说明一下,如何编写和测试自己自定义的Spring 标签。

  一、 定义xsd 文件,该文件是xml文件的 schema 定义。从上面的例子中,我们知道xsd文件里面应该有2个节点,1个provider节点和1个cumsumer节点定义。然后制定provider节点有id 和classs属性,而cumsumer节点有 id和 interface属性。定义文件如下(该文件名为light-weight-rpc.xsd):

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.qee.com/schema/rpc"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:beans="http://www.springframework.org/schema/beans"
            targetNamespace="http://www.qee.com/schema/rpc"
            elementFormDefault="qualified"
            attributeFormDefault="unqualified">

    <xsd:import namespace="http://www.springframework.org/schema/beans"/>

    <xsd:element name="provider" type="rpc-provider-type"></xsd:element>

    <xsd:element name="cumsumer" type="rpc-cumsumer-type"></xsd:element>

    <xsd:complexType name="rpc-provider-type">
        <xsd:attribute name="id" type="xsd:string" use="required"></xsd:attribute>
        <xsd:attribute name="class" type="xsd:string" use="required"></xsd:attribute>
    </xsd:complexType>

    <xsd:complexType name="rpc-cumsumer-type">
        <xsd:attribute name="id" type="xsd:string" use="required"></xsd:attribute>
        <xsd:attribute name="interface" type="xsd:string" use="required"></xsd:attribute>
    </xsd:complexType>

</xsd:schema>

  上面,画上红线的地方需要注意和主要的关注点,首先需要说明这个文件的name space 为 xmlns="http://www.qee.com/schema/rpc 。其他的具体如何写可以到网上搜索。有了这个文件,我们需要在xml的文件引入他,比如如下test.xml文件如何引用该文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:rpc
="http://www.qee.com/schema/rpc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.qee.com/schema/rpc http://www.qee.com/schema/rpc/light-weight-rpc.xsd"> <rpc:provider id="helloServiceImpl" class="com.qee.rpc.HelloServiceImpl"/> <rpc:cumsumer id="helloService" interface="com.qee.rpc.HelloService"/> </beans>

  上面就是一个spring xml 文件,主要关注的是花黄线的部分,这样就可以使用<rpc:provider> 和<rpc:cumsumer>。

  二、组织文件,即要把文件放到合适的地方,让Spring能够识别。第一步,需要把light-weight-rpc.xsd文件放到META-INF的文件夹下,然后在META-INF文件创建2个新的文件,名字固定。

文件1:spring.schemes ,该文件里面直有一行数据,如下

       http\://www.qee.com/schema/rpc/light-weight-rpc.xsd=META-INF/light-weight-rpc.xsd

  该行告诉Spring容器,http://www.qee.com/schema/rpc/light-weight-rpc.xsd ,之前定义命名空间的light-weight-rpc.xsd文件是META-INF下的light-weight-rpc.xsd

文件2:spring.handlers,该文件里面也只有一行数据,如下

       http\://www.qee.com/schema/rpc=com.qee.rpc.config.support.LightWeightRpcNamespaceHandlerSupport

  该行告诉Spring容器,命名空间http://www.qee.com/schema/rpc的解析处理器是 com.qee.rpc.config.support.LightWeightRpcNamespaceHandlerSupport。这个例子的目录如下

  

 

好了到现在我们基本把文件的位置放置正确了。之后就是需要编写com.qee.rpc.config.support.LightWeightRpcNamespaceHandlerSupport。

  三、编写com.qee.rpc.config.support.LightWeightRpcNamespaceHandlerSupport,该类需要继承NamespaceHandlerSupport,重写init()方法。主要的目的就是注册,节点解析处理器。

代码如下:

public class LightWeightRpcNamespaceHandlerSupport extends NamespaceHandlerSupport {

    @Override
    public void init() {
        //注册用于解析<rpc>的解析器
        registerBeanDefinitionParser("provider", new LightWeightRpcBeanDefinitionParser());
        registerBeanDefinitionParser("cumsumer", new LightWeightRpcBeanDefinitionParser());
    }
}

  从代码上我们只要,就是把解析xml文件provider和cumsumer节点进行BeanDefinition转化解析。

  因为这2个节点非常的类型。所以我就只想用痛一个解析处理器,LightWeightRpcBeanDefinitionParser,该转化器继承org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser。具体代码如下:

public class LightWeightRpcBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {


    protected Class getBeanClass(Element element) {
        return LightWeightRPCElement.class;
    }

    protected void doParse(Element element, BeanDefinitionBuilder bean) {
        String interfaces = element.getAttribute("interface");
        String clazz = element.getAttribute("(使s s0">);Lig6ng clazz =ue00000"> L,s0">);Lig6ng clazz classprot(clazz UtilsghtsT00f(id)n>=ue00000"> LsumeerSu使s s0">);Lig6ng,classprot(clazz UtilsghtsT00f(n>= e)n>=ue00000"> Ln>= e使s s0">);Lig6ng,= e)clazz classprot(clazz UtilsghtsT00f(r: #000000)n>=ue00000"> Lr: #000000使s s0">);Lig6ng,void<最终生nbsp对象行告诉Class(Element elementice"/itiochema/rpc 28-2org.s象就是.beans.factory.xml.AbstractSingleBeanDefinitionParser。6ng@Data
@Toclazz 
s NamespaceHandlerSupport {

    @Override
="color: #0000ff">return LightWeignClass(Element element {= e <rpc:provate clazz return LightWeigw
<00ff">return LightWeignnt Test> NamespaceHandlerSupport {

    @Override
&nbsmespaceHandlerSupport {

    @Override
    p(clazz [] argsn>s0">);Lig6ng clazz = elem(Class(Element element)ctx.n>);Lig6ng clazz = elem(Class(Element element)ctx.n>);Lig6ng clazz  Ligh 定义xsd 文产析pror 象/rpc p672564加载器lond: ,lt;/ror接口bsp字ider/: #000000,lt;/ror

 柄/:vtp://ww  ">

 柄/想Invtp://ww NamespaceHandlerSupport { @Override ="color: #00 I: #00000spaxy ="com.qee.rpc.HelloServiterfment>

<00ff">return LightWeignInvtp://ww extendsextendsreturn LightWeignIn #00000spaxy protectedthi>
<.exc" return LightWeignexc" extends NamespaceHanObj>throw>
<00ff">return LightWeignThrow/scrcolor: #####Messesp allma/r callma/r an>= ele00ff">return LightWeignExc"Manespr./:vtke(exc" blogs.结果栈,ght-w解决就pre><00ff">return LightWeigfazz lemow Li 定义xsd 文/继t-rp逻辑iti/:vtkecNamespac个斆fig.nbsp;<过bbo Exc"Manespro

逻辑所Exc"Manespr/span>="com.封装648Exec"oryle="bag 臺程池i>

<  allBackExc" ="com.qee.rpc.HelloServiterfment>
<  all/scrMessesp allma/rstyle0ff">return LightWeignff">extendsextendsreturn LightWeignremoteAddresses;f">extendsextendsreturn LightWeign allBackExc" protectedthi>
<.sumeerSu =00ff">return LightWeignsumeerSu"azz lemtends NamespaceHan allBackExc" return LightWeignremoteAddressesf">protectedthi>
<.sumeerSu =00ff">return LightWeignsumeerSu"azz ctedthi>
<.remoteAddresses =00ff">return LightWeignremoteAddresses;fazz lemtends NamespaceHan allBackExc" return LightWeignremoteAddresses, LondBalle="dclaategyblondBalle="dclaategyf">protectedthi>
<.sumeerSu =00ff">return LightWeignsumeerSu"azz ctedthi>
<.remoteAddresses =00ff">return LightWeignremoteAddresses;fazz ctedthi>
<.londBalle="dclaategy =00ff">return LightWeignlondBalle="dclaategy;fazz lemtends NamespaceHa00ff">return LightWeign allBackExc" fazz c* 程执fazz c*fazz c* sfazz c* sreturn Lig8tWeignExcep//ww
 cted inhtWeigfazz 0000ff">extends NamespaceHanMessesp allma/r call(n>throw>
<00ff">return LightWeignExcep//ww">protectedifpan>prot(Coll>

return LightWeignyle="baRemoteUrl导xt.n>ifpan>prot(Coll>throw如下:

s0">);Lig6ng clazz inormDefaulsizu =00ff">return LightWeignremoteAddresses.sizu()eImpl" ctedinormDefaulidx =00ff">return LightWeignlondBalle="dclaategy.slaategy(sizu);f">exteeeeeInetSocketAddress inetSocketAddress an>= ele00ff">return LightWeignremoteAddresses.n><(idx clazz Lblogs.;rpc:" +ninetSocketAddress + " lidx=" +pudx clor: #####Messesp allma/r messesp allma/r an>= elempcBeanDefinitionParser()); regipMessesp allma/r()eImpl" cted Class getBea>pmessesp allma/r00ff">new
<00ff">return LightWeignyle="baRemoteUrl导xtcolor: #ndsreturn LightWeignremoteUrls">extendsreturn LightWeignyle="baRemoteUrl导xtcc导xt;f">extends NamespaceHandlerSupport {

    @Override
&nbsmespaceHa00ff">return LightWeignyle="baRemoteUrl导xtcn>protectedifpan>return LightWeign>synchronizuan style=(yle="baRemoteUrl导xt.:

<00ff">return LightWeign>ifpan>return LightWeign>= elempcBeanDefinitionParser());
        regipyle="baRemoteUrl导xt();span styl= elempcBeanDefinitionParser());
        regi HashMap/style0ff">return LightWeig();span styl Class getBea>pc导xt;fr: #lemmtendsfazz c* 添加bbo 远程之卹/从sle="ba-url.an sties 获fazz c*fazz c* sreturn Lig8tWeignsumeerSufazz c* sreturn Lig8tWeignsle="baAddressCort.Lfazz c* s NamespaceHandlerSupport {

    @Override
boolume getBea>paddyle="baAddress(clazz protectedifpan>return LightWeign> Class getBeanvascrspaceHa00ff">return LightWeigclazz classprot(remoteUrlsf>ifpan><(sumeerSuf"=empcBeanDefinitionParser());
   ullspaceHa00ff">return LightWeign>

return LightWeig();span stylescrspaceHa00ff">return LightWeig>

return LightWeignremoteUrls.n><(sumeerSuf;span stylifpan>prot(sle="baAddressCort.Ls.ttps:ins(sle="baAddressCort.L)n> Class getBeanvascrspaceHa00ff">return LightWeigclazz Class getBeantrurspaceHa00ff">return LightWeigclazz Class getBeanvascrspaceHa00ff">return LightWeigclazz lemtendsfazz c* 获bbo 匪定乐.程之 sumeerSuplike "c.config.support.Li搜sumer id="helfazz c*fazz c* sreturn Lig8tWeignsumeerSufazz c* s NamespaceHan">protn>protected Class getBea>premoteUrls.n><(sumeerSuf;span lemowpLondBalle="dclaategybolor: #ndsfazz c* 从 0 -sizu-1 获bbo 值fazz c*fazz c* sreturn Lig8tWeignsizufazz c* spsizu);fw

ame spa成amenbsp; prorg.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser。具体代码如下:

< RollPolzz claategybement name="p"color: #000000"iterfment>
<00ff">return LightWeignLondBalle="dclaategybolor: #nds=ue em000ff">return LightWeigclor: #ndspc>= eemtends NamespaceHanRollPolzz claategy( pc>= ef">protectedthi>
<.n>= el=00ff">return LightWeignc>= eeazz lemtend0000ff">extends NamespaceHandlerSupport {

    @Override
inormDefaulslaategy(ement name="p"color: #000000"inormDefau>psizu)">protectedsynchronizuan stylean style="color: #0000ff">prot(c>= ef">protectedctedinormDefaulnexyn>=ue em(/jqueryn>=ue + 1) %>psizuclazz =ue an>= ele00ff">return LightWeignnexyn>=ue;span stylifpan>=ue le=">psizu)">protectedddddddddnexyn>=ue an>= elem000ff">return LightWeigclcteddddddddd}span styl Class getBea>pcjqueryn>=ueclazz 
<:

pExc"Manesprbolor: #ndsfazz c* 默认是200ㇺ程 cted"vateactSing dlerSupport { @Override &nbsmespaceHandlerSupport { @Override finalspaceHandlerSupport { @Override inormDefaulDEFAULT_THRED_NUM em20000ff">return LightWeigclor: #ndsfazz c* 超时时间为1秒 cted"vateactSing dlerSupport { @Override &nbsmespaceHandlerSupport { @Override finalspaceHandlerSupport { @Override inormDefaulDEFAULT_TIME_OUT_TIME em100000ff">return LightWeigclor: #nds"vateactSing dlerSupport { @Override &nbsmespaceHanExec"oryle="ba exec"oryle="ba e00ff">return LightWeignExec"ors.newFixedThreadPool(DEFAULT_THRED_NUM)emtends NamespaceHandlerSupport { @Override &nbsmespaceHanMessesp allma/r /:vtke( all/scrMessesp allma/rstyle0ff">return LightWeigncall)">protectedFulaseactSingMessesp allma/rstyl submit =00ff">return LightWeignexec"oryle="ba.submit(call);fazz ctedtryspaceHa00ff">return LightWeig> Class getBea>psubmit.n><(DEFAULT_TIME_OUT_TIME, TimeUnit.MILLISECONDS)clazz catchn stylean style="color: #0000ff">prot(In #0ruptedExcep//ww"u)">protectedddddsubmit.cle="l(trurspaceHa00ff">return LightWeigf;span stylthrow如下:

s0">);Lig6ng,catchn stylean style="color: #0000ff">prot(Exec"/wwExcep//ww"u)">protectedddddsubmit.cle="l(trurspaceHa00ff">return LightWeigf;span stylthrow如下:

s0">);Lig6ng,catchn stylean style="color: #0000ff">prot(TimeoutExcep//ww"u)">protectedddddSyn>newtrurspaceHa00ff">return LightWeigf;span stylthrow如下:

s0">);Lig6ng, NamespaceHandlerSupport { @Override &nbsmespaceHandlerSupport { @Override pshutdown()">protectedexec"oryle="ba.shutdown();fazz lemtends NamespaceHandlerSupport { @Override &nbsmespaceHandlerSupport { @Override pshutdownNow()">protectedexec"oryle="ba.shutdownNow();fazz lemw NamespaceHandlerSupport { @Override ="color: #00 Rspan>
<00ff">return LightWeignspan id=Processore="colFLightAwarenff">extendsextends NamespaceHanObj>throw>
<00ff">return LightWeign"colsExcep//ww">protected Class getBea>psumeeazz lemtend0000ff">extends NamespaceHanObj>throw>
<00ff">return LightWeign"colsExcep//ww">pprotectedObj>= ele00ff">return LightWeignsumeeazz tendsprotClass(Element element)">protected//spr果itiClass(Element elementice则强转文仦则不

span stylass(Element element rpcelement an>= ele00ff">return LightWeign(Class(Element element)nsumeeazz tendddddeazz tendddd// WtHub0912175   XML bsp后制值fazz ccccccccC"color: #00如le="an>= elempcBeanDefinitionParser()); ullspaceHa00ff">return LightWeig;span stylifpan>return LightWeigclazz UtilsgisEmpty(rpcelement.n>tryspaceHa00ff">return LightWeig>= element.ge00ff">return LightWeig>C"col.forerSu#rpcelement.n>catchn stylean style="color: #0000ff">prot(C"colNotF/ligExcep//ww"u)">protectedddddthrow如下:

s0">);Lig6ng clazz

return LightWeignyle="baRemoteUrl导xt.n>

<00ff">return LightWeignclazz = elem:

return LightWeignRollPolzz claategy(n>= e)neImpl" ctedddddI: #00000spaxy = elem:

return LightWeignIn #00000spaxy

ame sp优化渺各种方式产生动pror-weighcglib等lazz = ele spaxy. spaxyIstyle="(sumecpan style)cpan stylLond: #0,m:

return LightWeign styl[]{n>= e},ifpan>protrmDefau">

protecteddddd

= ele00ff">return LightWeign(rmDefau">

Class getBea>p"extends NamespaceHandlerSupport { @Override s>throw>

<00ff">return LightWeign"colsExcep//ww">protectedthi>
<.sumeFLightreturn LightWeignsumeFLight;mrote}
 cted

 NamespaceHandlerSupport {

    @Override
="color: #00 yle="baRemoteUrlsI#00="com.qee.rpc.HelloServiterfment>
<00ff">return LightWeignIn000aliz fazz c* .程定bsp;/路径默认
 ctedreturn LightWeigor: #0n>=ue00000"> L${remote-urls-path:="colpath:sle="ba-urls.an sties}使s s0">);Lig6ng >extendsextends NamespaceHandlerSupport {

    @Override
     af>throw>
<00ff">return LightWeignExcep//ww">protectedPan sties pps an>= elempcBeanDefinitionParser());
        regi00ff">return LightWeignPan sties();fazz ctedifpan>s0">);Lig6ng f">protectedctedthrow如下:

s0">);Lig6ng clazz = elemremoteUrlsspan stPath.s0">);Lig6ng clazz classs0">);Lig6ng ">protectedctedthrow如下:

s0">);Lig6ng clazz = elem:

);Lig6ng] clazz = elempcBeanDefinitionParser()); regi00ff">return LightWeignBufferedInputclaeam(resourhe.n>= ele00ff">return LightWeignpps.an styerSup()eImpl" ctedwhileactSing00ff">return LightWeign(enghtsMoreelement0#00">protectedddddSlazz = ele00ff">return LightWeign(Slazz )"un.nexyelement();span styl= ele00ff">return LightWeignpps.n>= elemstrRemoteUrls.s0">);Lig6ng clazz classreturn LightWeign>baeakspaceHa00ff">return LightWeig;span stylforactSing00ff">return LightWeign(clazz = elemremoteUrl.s0">);Lig6ng clazz classs0">);Lig6ng ">protectedctedclass
s0">);Lig6ng clazz = elempcBeanDefinitionParser()); regipyle="baAddressCort.L();span stylreturn LightWeig]f;span styl=ueOf#hid=P/sp[ regi1s s0">);Lig6ng] f;span styl= elem:

return LightWeignInetSocketAddress(sle="baAddressCort.L.n> NamespaceHandlerSupport { @Override ="color: #0000ff">return LightWeignInvtkercolor: #0Autowired>extends= ele pan style="ba使s s0">);Lig6ng >extends NamespaceHandlerSupport { @Override pt()">protectedan style="ba.an st00000"> L123使s s0">);Lig6ng clazz L122344使s s0">);Lig6ng clmpl" news0">);Lig6ng >@En/scrAutoCort.Luda//ww s NamespaceHandlerSupport { @Override ="color: #0000ff">return LightWeignAppbolor: #ndsreturn LightWeignExec"ors.newCachedThreadPool();f">extendss0">);Lig6ng);f">extendsp(clazz [] argsn>tryspaceHa00ff">return LightWeig>c"color: #0000ff">return LightWeig, argsn;span styl Lthe m Thread :" +pThread.cjqueryThread().n>newfinalspaceHanInvtkercinvtkerc=t(Invtker)lAxml" rel="导xtUtilsgn>s0">);Lig6ng clazz class ">protectedcted regi00ff">return LightWeignRunn/scr( ">protectedctedextenddddddddddddddddds NamespaceHandlerSupport { @Override prun( ">protectedctedtryspaceHa00ff">return LightWeig>catchn style00ff">return LightWeign(In #0ruptedExcep//ww"u)">protecteddddddddddddddddddddde.tStackTrace();span styl1ghtWes s0">);Lig6ng clmpl" catchn style00ff">return LightWeign(In #0ruptedExcep//ww"u)">protecteddddde.tStackTrace();span styllmfinallyspaceHa00ff">return LightWeig>/:vtkecNames/渺schema底层> r: #00#00#00cyn> Li 妁诸ghtRs://githubportvOoT/lleme-wEleme-.sut.LightWeightRpcNamespaceHandlerSupport。这个例子的目录如下

3202508703-1048274411http://images2017.cnbhema/r所样72564-on>="iti/initi/me sp过yc.con注解告诉0Autowired,#0Resourhe oo,邅动〯象2017.cnblogs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/logs.com/blog/hema/rmework

 <rlt;rlt;rlt;rlt;rlt;rlt;rlt;rlt;rlt;rlt;rlt;rlt;rlt;rlt;rlt;rlt;rlt;rlt;rlee.com/sclogs.com/btyle="k.beaid="MySignalase"btyle=" rk.beans.factolear"btyle=" rk.beaid="_pid=_info_ck"" rk.beaid="B id=Category"btyle=" rk.beaid="EntryTag"btyle=" rk.beaid="_pid=_info"" rkyle=" rk.beans.factolear"btyle=" rk.beaid="pid=_nexy_e.cv"btyle=" rkyle=" r r r kyle=" r k.beans.fa = "pid=Desu>pid=ed@ndlerSuid="pid=-date">下<-09-13 20:29spaceHanda hrefe'ghtRpcNwwwndlerSupportliferecord/'>vOoT...
) 评论(dlerSuid="pid=_ortment_count">...) nda href eightRs://indlerSupportEdit id=s.aspx?pid=id=7511617" rel="nofollow">编辑收藏k.beaid="-ortments-pl000holder"btyle="kscript typrn rk.beaid='.beCrtmentShow'btyle=" rk.beaid='ortment_nav'>dlerSuid='lerS_refresh_tips'btyspan>
刷新评论tya>ka hrefe'#' oncamek=' Class RefreshPesp()c'>刷新页面tya>ka hrefe'#top'>blogs.顶部mincrementViewCount(cb_entryId); }, 50)c r公告 r k.beaid="-news"btyle="kscript typrnreturn