`
herman_liu76
  • 浏览: 99632 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

抗战时期延安与上海地下党的远程通信

 
阅读更多
    当ZHUXI(敏感词)在延安领导全国抗战的时候,如果在上海的周恩来去延安开会,那么ZHUXI有事情可以直接联系周恩来办。可是当周恩来回到上海后,ZHUXI找恩来有事,那应该如何远程调用呢?

    最初我们接触java语句的时候,在介绍类,对象时,总会拿现实中的东西作为例子,比如水果是类,苹果、香蕉是对象。而<thinking in java>多线程通讯举例的时候21.5.3,会拿一个厨师与服务员以及膳食的生产与消费来举例。那么如今看到复杂的系统的时候,我还会想象出生活中的场景,来比对系统的各种功能与调用关系,不知道有没有与我一样的呢?

    就拿前一阵分析的dubbo系统来说(原码分析),它是阿里巴巴公司实现SOA治理的工具,它的核心功能是实现了一个远程方法调用。主要涉及的对象有invorker,proxy,headExchangeClient,headExchangeServer,headExchangeChanel,headExchangeHandler,nettyClent,nettyServer,nettychannel,nettyhandle,netty本身的类等等。对于这个复杂的系统,我设想了一个场景:比如headExchange是个核心交换层,就设想一边是延安的联络处,一边是上海地下党的悦来客栈。而传输工具就是民国邮政、民间镖局之类的,主要实现的功能是ZHUXI调用远在上海的恩来同志。那么详细的过程如下所述:

   前面说过,如果是本地调用,那ZHUXI直接联系恩来同志就可以了。现在要远程调用,我们给ZHUXI安排一个高级秘书,如果找恩来办的事,就直接找这个秘书(proxy)来办,秘书实现了恩来的所有作用。比如现在发出一个命令字条,“组织抗日政策宣传(参数:77事变)”。秘书拿到命令后,需要把这个命令传了去,秘书感觉总不给我自己跑到上海吧,我需要利用民国的传输企业或者镖局来传,不过如此复杂而含有不同类型的工作太多,还是需要分工协作的,那干脆成立一个中央联络处吧,统一利用各种民国的现成交通资源,让上海那边成立一个相应的部门,不过名称改改,还要伪装一下,就叫“悦来客栈”吧,联络处(headExchangeClient)与悦来客栈(headExchangeServer)就此诞生,两个部门成立了,那要与可以传输东西的邮局或镖局打交道,那两个部门下再成产专门的小组吧,一个小组叫邮政小组 (nettyClient),一个小组叫镖局小组(minaClient),明确分工。那个客栈下面也成立了两个小组,分别是粮油组(nettyServer),饭局组(minaClient)。联络处内部还有一个岗位,就是高级通信员(HeaderExchangeChannel),他与后面介绍的内部通信员不同,高级通信员(HeaderExchangeChannel)是受联络处长指挥,并安排两个小组长的办事的。现在秘书(proxy)需要发信息出去的时候,联络处长(headExchangeClient)收到命令后就让高级通信员处理,自己就在一边喝茶等消息,这可是同步调用,必须等结果。接下来高级通信员先给信息包装成内部标准快件(response,request),再安排邮政组长或者镖局组长发送。

    以邮政这边为例(netty传输),不过这个邮政与现在的邮政不同,首先他会收寄的两边派出一个邮政快递员(jboss.channel)供客户使用,他会让客户安排两个人(decoder,encoder)专门做包装与拆包装的工作以满足快递的要求,因为任何快件发送时都要拆成小块,而收到的时候要从小块中恢复成快件,很神奇吧。怎么拆,怎么组装这就是协议,http就是协议。这里我们叫dubbo协议,拆成小块时会在一些小块上做上标记,比如前两块写上magic码,还有写是寄件还是返回件等等,实际上就是拆分与组装邮政收发件(内部快件response,request与邮政收寄件的转换)的工作。另外客户还可以安排一个守门人(nettyHandle)来监控快递的收发工作,或者是签收,或者是回寄件等。前面两个人派到邮局就不用管了,只需要关注你的守门人的消息。

    邮政组与粮油组是要建立一种可靠的连接的,所以都安排了专人,都叫内部通信员(nettyChannel),内部通信员受小组长指挥,一般待命,有事情了专门负责对接邮局派出的邮政快递员(jboss.channel)的。前面提到高级通信员(HeaderExchangeChannel)要找组长发送快件了,假设找的邮政组长,邮政组长就叫醒内部通信员,内部通信员再找快递员把东西发出去。到此,发送的工作算是做完了!

​   至于接收,邮政组与粮油组都有安排了一个守门人(nettyHandle)专门守在门口看看有没有邮递过来。比如发现来了快件,就通知让平时休息的内部通信员干活了,让内部通信员记着这个快递员的名字,并拿着快件,然后去找粮油组长(nettyClient)来处理。邮政组长安排本组的手下的MultiMessageHandler 还有 HeartbeatHandler(如果是心跳请求或者响应,它直接处理掉)处理,他们处理完了,如果还有进一步的处理,就再交给客栈拆信员(DecodeHandler,这个拆信与前面派到邮局的拆信员不一样,把调用相关的信息都拆分好了,将信息包装成Invocation了)处理,处理好了再交给悦来客栈的机要员(HeaderExchangeHandler),于是拆信员把信拆开后,把信与内部通信员的名字都给了机要员。客栈拆信员与客栈的机要员都是客栈安排给组长使用的,并非组长手下,因为也可以安排给其它组长使用。

    机要员(HeaderExchangeHandler)可是一个重要角色,因为他掌握着核心的dubbo通讯规则,他看了信后,会判断来信的类型,如果是命令(request),如果这个命令是只读事件(Request.READONLY_EVENT)、他就仅仅给高级通信员作标识,如果是要求回复的快件,则会找来相关处理人(requestHandle)来处理,处理人会根据命令中的serviceKey找一个秘书(invoker)告诉恩来同志的,恩来同志会真正处理的,处理结果马上返回给机要人员。机要人员马上写一封回信(返回值),由于拆信员把内部通信员的名字给了机要员,机要员就安排这个通信员送回去,通信员当然也知道邮递员的名字,就交给刚才的邮递员送回去。

    ​延安的联络处的守门人(nettyHandle)也在监控着快递的到来,发现有快件来了,也是叫醒内部通信员,拿着来信去找邮政组组长(nettyClient),组长分别让本组的MultiMessageHandler 还有 HeartbeatHandler处理,等他们处理完了,如果要继续处理,那他们再直接给联络处安排给他的DecodeHandler 和 HeaderExchangeHandler来处理。对于刚才的情况,HeaderExchangeHandler发现是之前请求结果的返回件,就会通知之前等待的秘书,告诉他可以带结果回去交差了。

---------------------------------BEGIN-----------------------------------------

      最后再简单总结一下完整的过程:​ZHUXI的调用交给恩来代理秘书(proxy),秘书去联络处长(headExchangeClient)那边提交任务给处长并等待服务员(DefaultFuture)通知结果。处长把任务交给高级通信员(HeaderExchangeChannel),后者包装成内部标准快件后,安排邮政组长发送(nettyClient),邮政组长又把任务交给内部通信员(nettyChannel),内部通信员最后联系邮局快递员(jboss.channel)办理。邮局会把快件拆成一个个小方块后发到上海,到了上海会重新组装成原来的快件。上海那边的客栈的粮油组安排专门的守门人(nettyHandle)监控,当快递员(jboss.channel)送货后,守门人(nettyHandle)把快件与以及内部通信员(先让他记住此快递员名字)交给粮油组长处理。组长会让手下的处理人(MultiMessageHandler 与 HeartbeatHandler)和客栈安排的处理人(DecodeHandler与客栈的机要员(HeaderExchangeHandler))依次处理信息,处理时会把内部通信员依次告诉各位。如果最终到了机要员这里(内部通信员要先找到自己对应的高级通信员,向上调用用高级的,向下调用用内部的),他再找到相关处理人(requestHandle)处理(高级通信员也一并交给他)并马上等结果,后者再找到一个秘书(invoker)专门通知恩来(enlai_Impl)处理。处理结果由机要员掌握。机要员拿到结果并包装成内部快件后,让内部通信员(对下的操作,而非高级通信员)发出去。内部通信员(nettyChannel)则找前面记住的快递员(jboss.channel)真正返回结果。

        邮局把快件拆小块发出后,在延安又组成原始快件不细表,后由那边的快递员(jboss.channel)送出。那边的邮政组因为安排了守门人,会叫醒内部通信员并让他记住快递员名字后,把内部通信员与快件交给邮政组长,组长安排手下的处理人(MultiMessageHandler 与 HeartbeatHandler)和联络处安排的处理人(DecodeHandler与联络处的机要员(HeaderExchangeHandler))依次处理信息,处理时把内部通信员依次告诉各位。如果到了机要员这里,内部通信员是要先找到高级通信员的(对上用高级的,对下用小组内部的),发现是内部标准返回件(response),就叫服务员(DefaultFuture)叫醒发出指令后等待的代理秘书(proxy),秘书最后返回结果给ZHUXI。

----------------------------------END-------------------------------------------
    ​机要员(HeaderExchangeHandler)与高级通信员(HeaderExchangeChannel)是两个重要的角色!承上启下的发挥着关键作用。

    描述了这么多,并不仅是讨论dubbo,而是把面向对象的复杂系统类比出现实场景来。通过把dubbo中的调用类比设计出的延安与上海的调用,​感叹系统的层次设计合理,人员调用科学。这样的类比也更方便我宏观上把握此设计的精髓,你会不会经常用类比现实场景的方式理解其它系统呢?
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics