Dubbo接口测试调试工具(三) -- 项目设计

 

聊的不止技术。跟着小帅写代码,还原和技术大牛一对一真实对话,剖析真实项目筑成的一砖一瓦,了解最新最及时的资讯信息,还可以学到日常撩妹小技巧哦,让我们开始探索主人公小帅的职场生涯吧!

 

(PS:本系列文章以幽默风趣风格为主,较真侠和学习怪请绕道~)

 

 

江华:“哟,小帅,又在写bug啊?”

小帅:“滚......”

老胡:“小帅,让你写的工具进度怎样啦?”

小帅:“正是愁着这个呢!老胡,我感觉无从下手呀,你说这个项目应该怎样开展的呢?”

老胡:“原来你几天茶饭不思,连小檬都不撩了就是为了这个啊!”

小帅:“对啊,老胡,快教教我。”

老胡:“看在你这么努力(考顺)的样子,我就勉为其难指点你一下啦。”

江华:“......老胡你吃着小帅买的士力架说这话良心不痛吗?”

老胡:“咳咳咳,啊哈哈,我们看下怎样开始这个项目吧!”

 

老胡:“小帅,你可以先把学校里那套自上往下、自下往上的软件设计理论先放一边,嗯对,因为我也记不住。其实这个项目没那么复杂。”

 

老胡:“你以前不是学过画画么,我来问你,如果让你画一只猫,你会这样做?”

 

小帅:“en...首先确定这只猫长什么样,然后确定它在纸张摆放比例,然后做辅助线把猫分成头、身、腿、尾巴等几部分,然后根据五官比例作辅助线把头部又分成眼、耳、口、鼻、嘴等几个小部分,然后就可以开始画啦,等等,你想说的是,这个跟写代码是一样的?”

 

老胡:“对的,思路是一样的,下面我们一起分解说明一下。”

 

 

1、首先确定项目的总体功能。我们要的功能很简单,输入 --》转发 --》展示。

       图1 总体设计

 

2、接着,我们拆分输入部分。

 

老胡:“说这个之前,小帅,我来问你,假如让你来设计一个RPC框架,你会怎样设计呢?”

 

小帅:“en...我想想哈(不好意思表情)。”

江华:“老胡,你太看得起他了。”

老胡:“或者这样问,你觉得都应该包含哪些东西?结合你平时使用Dubbo的场景想一想。”

小帅:“en...之前使用Dubbo的场景啊,哦对了,先定义一个接口,然后在生产者写实现,再然后注册到Zookeeper,然后消费者也注册到Zookeeper,然后就跟使用本地接口方法那样了,那是不是一个RPC框架就应该包含接口定义、生产者、消费者、注册中心?”

老胡:“你这样回答也不能说错。RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。既然是远程调用,那么必定存在一个服务端,也就是你提到的生产者。知道有服务端还不够,我们得知道服务端的IP和端口,因为计算机网络都是通过Socket(套接字)来进行通讯的。那么我们是怎样知道服务端的IP和端口的呢?”

 

小帅:“我知道,Dubbo是通过Zookeeper暴露的服务的。它好像会把IP、端口、接口、方法这些拼接成Url,然后写到Zookeeper的/dubbo/xxx/providers 节点上。”

老胡:“纠正一下,虽然Dubbo推荐使用Zookeeper作为注册中心,但注册中心并不一定只能用Zookeeper哦。”

江华:“Dubbo目前支持4种注册中心,(multicast,zookeeper,redis,simple)”

老胡:“对的,当然,RPC框架不一定需要使用注册中心,但有了它可以做很多东西。好了,服务端的IP和端口都知道了,我们还需要一种协议,你可以理解为一种服务端和客户端都能听到的语言,也就是小帅你所说的接口。而接口会包含接口名称、方法名称还有参数这些东西。”

 

再回想一下Dubbo Consumer的使用方法。

1、配置zookeeper地址。

2、引用API的jar包

3、输入接口、方法、参数等。

 

老胡:“输入部分跟Dubbo保持一致,这样一来,我们的工具就可以不改变用户习惯的前提下充当一个泛化Dubbo客户端了。”

 

 

     图2 分解输入

 

3、接着,我们拆分转发部分。

 

1、获取Provider的IP和Port。

 

老胡:“前面已经提到,我们可以通过注册中心拿到服务器的IP和地址,也就是所谓的服务发现。Provider会把自身的一系列参数拼接成url,然后存放到zookeeper的provider节点上。所以我们只需要从Zookeeper获取Provider的所有节点,稍作解析就能得到Provider列表,从而得到IP和Port。”

 

2、连接Provider。

 

老胡:“获取到服务器地址以后,下一步当然是连接Provider了。还记得Consumer和Provider默认用什么通信框架的吗?”

小帅:(挠头表情)

江华:“默认是Netty吧,Provider暴露服务的时候会启动一个Netty Server。”

老胡:“是的,Provider在初始化interface的时候,除了会向zookeeper注册,还会通过export方法在本地启动Netty服务器,监听暴露的端口,等待客人送上门。咳咳,等待连接建立。而Consumer则会启动一个Netty客户端和Provider建立单一长连接来收发数据。”

小帅:“所以我们可以写一个Netty Client,然后连接上Provider的Netty Server?”

老胡:“没错。”

 

小帅:“哦哦,这个我懂,我可以写一个ClientBootStrap,嘿嘿。”

江华:“这就那么开心,小萌新真容易满足。”

小帅:“......”

 

 

图2 连接服务器

 

3、收发数据

 

老胡:“连接上Provider后,下一步就可以收发数据了。小帅,书刚看完,这块你还记得吧?”

江华:“怎么可能记得,他估计都要找当当退货去了。”

老胡:“......”

小帅:“......”

 

小帅:“我记得Netty连接建立后会返回一个Channel,这就是数据传输的管道。调用write方法就可以写入数据,推送到服务器了。”

小帅:“等等,老胡,我记得我之前看Demo的时候,除了自己ChannelHandler,好像还需要向Pipeline添加一个encode和decode的ChannelHandler。”

老胡:“是的,数据包在网络传输是二进制字节流,只有1和0我们工具和Provider都识别不了,所以这里还涉及到序列化和反序列化过程。这块先不急,后面我会教你,通过薅Dubbo的羊毛来实现。”

小帅:“哦哦,这样啊。那这个数据包就是我们前面输入部分提到接口、方法、参数这些吗?”

老胡:“是的,我们把这些信息封装成规定格式的数据包,然后编码,经过网络传输,然后服务端解码,然后分离出接口类、方法、参数,服务端就可以通过反射执行对应的方法了。”

小帅:“哇塞,原来是这样的啊!”

江华:“你好像好惊讶的样子...”

小帅:“...你就喜欢装什么都懂。”

 

4、响应。

 

老胡:“请求包发送出去了,我们得拿到响应,不然后面的展示模块就没发玩了。怎样知道响应报文对应哪个发送报文呢?”

小帅:“江华,你懂你说啊。”

江华:“切,我当然知道,Dubbo在Request包中封装了一个mId的流水号,通过它就可以跟踪发送的包了。”

老胡:“是的,流水号在分布式系统幂等去重、顺序重整、异步调用跟踪等起着重要的作用。在封装数据包的时候,我们可以把流水号记录下来。然后可以阻塞等待这个流水号数据包的响应。小帅,还记得Netty的事件机制吧?”

小帅:“记得记得。”

老胡:“刚才提到可以往Pipeline里添加一个自定义ChannelHandler,用来监听数据接收事件。当服务端执行完方法调用,把数据包返还回来。编码、网络传输、到客户端解码,我们就可以拿到这个流水号了,然后修改这个流水号的等待状态,结束阻塞,这样就可以把数据返回前端页面展示了。”

 

 

最后,分解展示部分

 

老胡:“展示部分比较简单,直接把RpcResult对象转换一下就可以输出到页面了。”

小帅:“哦哦,感谢老胡,我知道怎样做啦。我这就去写代码嘿嘿,告辞!”

老胡:“这孩子,年轻真好。”

江华:“呵呵,老胡,你等着,等下他肯定会回来。”

                                                                        

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值