19. Dubbo原理解析-通信层之暴露服务
来源:互联网 发布:用苹果手机拍淘宝图片 编辑:程序博客网 时间:2024/05/18 17:40
Dubbo的整个远程通信层由exchange,transport, serialize
exchange,信息交换层,封装请求响应模式,同步转异步,以Request, Response为中心,扩展接口为Exchanger, ExchangeChannel, HeaderExchangeHandler,ExchangeClient, ExchangeServer
transport,网络传输层,抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel, Transporter, Client, Server,Codec
serialize,数据序列化层,可复用的一些工具,扩展接口为Serialization, ObjectInput, ObjectOutput,ThreadPool
一:提供方暴露服务
1. 服务提供方在DubboProtocol暴露服务export的过程
DubboProtocol构建requestHandler实现了reply方法,用来响应服务调用方的请求,调用具体的服务,并将请求结果封装为RpcResult返回给调用方
requestHandler在创建服务createteServer的 Exchanger bind的时候传入,
Exchangers.bind(url, requestHandler) //传入url, 处理器,这个处理器会被层层装饰
根据spi策略HeaderExchanger.bind(url,requestHandler)
构建HeaderExchangeServer对象,new HeaderExchangeServer(Transporters.bind(url,new DecodeHandler(new HeaderExchangeHandler(handler))))
装饰requestHandler对象
根据spi策略NettyTransporter.bind(url, channelHandler), 构建NettyServer对象,绑定netty服务启动服务监听
2. NettyServer初始化过程,它是dubbo默认的通讯框架
构造器入参URL统一数据模型包含服务器端地址,超时时间等参数
构造器中装饰传入的ChannelHandler,ChannelHandler其实是一个处理器链,transporter层做了装饰,这里NettyServer构造其中通过ChannelHandlers.wrap方法再次进行装饰
RequestHandleràDecodeHandlerà HeaderExchangeHandlerà MultiMessageHandlerà
HeartbeatHandlerà AllChannelHandler
NettyServer的构造其中会调doOpen方法启动netty。 Netty是基于pipeline管道机制的,我们可以添加阀(org.jboss.netty.channel.ChannelHandler)来实现自己的需求
Decoder: InternalDecoder继承netty对象SimpleChannelUpstreamHandler
Dubbo自定义了一套buffer用来适配底层的nio, 自定的channelBuffer读取netty传递过的字节然后调用dubbo的编码解码器codec.decode解码成Request/Response对象返回
触发netty的messageReceived事件
Encoder:InternalEncoder继承于netty的OneToOneEncoder, 将传入的Request/Response/String等对象类型转换成字节流
注:为什么Decoder对象没有直接继承于netty的OneToOneDecoder对象能,因为decoder
时候要把字节流读入到dubbo自定义的buffer中,然后再调codec,这样codec的接口就不直接依赖于nio的api,便于codec的扩展及替换
3. NetttyHandler:继承于netty对象SimpleChannelHandler触发netty事件来处理dubbo需求,它会触发一系列的dubbo的ChannelHandler。它是一个处理链AllChannelHandlerà MultiMessageHandlerà HeartbeatHandleràDecodeHandler HeaderExchangeHandler à RequestHandler
AllChannelHandler: 默认分发请求实现对于netty事件中除了writeRequested的其他请求chanenlConnected, channelDisconnected,messageReceived, exceptionCaught这四种事件通过构建ChannelEventRunnable任务放入线程池分发
MultiMessageHandler:对于消息的received事件,如果消息是批量传输的decode后会由MultiMessage承载,如果是MultiMessage遍历其中的消息分别交由下一个handler处理
4. HeartbeatHandler:处理心跳
Connected事件设置读写时间戳为当前时间
Disconnected事件清空读写时间戳
Sent事件发送请求设置写时间戳为当前时间
Received事件接收请求设置读时间戳为当前时间
1) 判断消息是心跳请求,当Request对象的mEvent属性为true且mData为null时为心跳事件。
如果此心跳事件需要响应即Request.isTwoway(), 构建心跳响应对象Response,设置响应对象的mEvent=true && mData=null
下面channel处理,最终会通过netty响应客户端。
2) 判断消息是心跳响应,Response的mEvent=true && mData=null, 记录日志直接返回,不在做后续的channel处理了。
3) 如果不是心跳处理,交由下一个处理器处理。
5. DecodeHandler:对于读取的消息或者消息的数据实现了Decodeable接口的decode
6. HeaderExchangeHandler:这里已经到了交换层的handler了,对于这个handler我们主要关心sent事件: 设置channel的写时间戳, 交由后面hanler来发送消息,如果消息是request,根据request获取DefaultFuture设置它的发送时间为当前时间,用来判断是否超时。received事件:接收读取数据
1) 给channel设置读取时间戳
2) 如果是msg是请求类型的Reqeust,
根据request的id构建response对象
调DubboProtocol中构建的requestHandler的replay方法,返回调用结果
跟response对象设置返回结果
Channel.send(response) 向客户端发送响应
3) 如果读取的数据是Response响应并且不是心跳
根据response透传的id获取defaultFuture, 设置defaultFulture的response的值,唤醒线程,defaultFulture的get方法返回调用值
4) 如果是string类型, 处理telnet命令
5) 其他的交由下一个handler处理 //什么场景??
下面给出服务提供方服务绑定的活动图
- 19. Dubbo原理解析-通信层之暴露服务
- 20. Dubbo原理解析-通信层之引用服务
- dubbo组成原理-service服务暴露
- Dubbo中暴露服务的过程解析
- 21. Dubbo原理解析-通信层之请求响应活动图
- dubbo暴露服务过程
- Dubbo服务再暴露
- Dubbo源码分析之三:服务的暴露
- dubbo服务原始暴露流程
- Dubbo服务暴露的流程
- 15. Dubbo原理解析-集群&容错之目录服务Directory
- 16. Dubbo原理解析-集群&容错之router路由服务
- dubbo注解暴露服务与接收服务
- 8. Dubbo原理解析-服务发布
- 9. Dubbo原理解析-服务引用
- 18. Dubbo原理解析-服务调用
- 分布式服务框架dubbo原理解析(顶)
- 分布式服务框架dubbo原理解析
- uml总结之状态图、活动图
- 卷积神经滤波CNN(一)
- Web页面跳转的3种路径
- 最长回文字符串
- java web 监听器详解
- 19. Dubbo原理解析-通信层之暴露服务
- 字母易位词
- Java - 批量插入用法(jdbcTemplate)
- FZU 2150 Fire Game
- 如何提高一项能力
- Jquery如何解析JSON数据
- jvm参数设置
- Linux下软件安装方法汇总
- oVirt problem with duplicate UUIDs