这篇紧接着第7篇,有些执行socket细节过程需要细细研究(也就 标记为A、B、C、D),就如下图
1、doFinalShutdown() 做最后关闭 (A)
-
如下图示
-
总结
- 关闭socket
- interrupt mainloop (也就监听主线程)
- 通知所有关闭监听器(shutdownCompleted方法)
- 哪些监听器需要重新恢复监听
2、FrameHandler#readFrame (读取socket)
- com.rabbitmq.client.impl.Frame#readFrom (核心方法),把socket数据变成Frame对象
- 如下图
- 总结
- 数据协议:类型+通道+数据大小+数据+结束符
- 总结
2.1、Frame类
2.1.1、成员变量
- type 类型( FRAME_HEARTBEAT :心跳, FRAME_METHOD: 方法, FRAME_HEADER : 头部信息, FRAME_BODY 内容主题)
- channel 通道 (0-65535)
- payload 消息内容字节 (读取数据)
- accumulator (写出数据)
- NON_BODY_SIZE = 1+2+4+1 (没有内容最小大小, 1type+2channel+4payloadSize + 1end character)
2.1.2、核心方法
- com.rabbitmq.client.impl.Frame#readFrom 读取数据
- com.rabbitmq.client.impl.Frame#writeTo 写socket数据
3、AMQConnection#readFrame (C)
-
先已经从socket读取数据转成Frame, frame需要继续加工处理
-
总结
- Frame 转成Method 区分不同Frame请求指令 com.rabbitmq.client.impl.AMQImpl
- AMQConnection#processControlCommand异常信息提示
- 唤醒下一次rpc,channel一次只能一个线程使用
- 最后将结果设置到BlockingCell上, 在BlockingCell有wait 和notifyAll机制
4、AMQConnection#handleFailure (D)
-
处理读取数据时候发生异常,主要释放资源
-
总结
- 关闭心跳检测
- 将关闭信息通知rpc和blockingCell,上层服务可以知道
- 关闭对应通道和复用通道数字
- 消费者接受关闭时需要处理逻辑
- 通知关闭监听器
- 利用CountLatch等待所有子通道完成之后释放工作池线程
5、总结
- 里面还有很多线程之间调度 wait() notifyAll()
- CountDownLatch使用
- 同步锁使用,多线程感觉很复杂, 确实学习好素材
结尾
- 感谢大家的耐心阅读,如有建议请私信或评论留言。
- 如有收获,劳烦支持,关注、点赞、评论、收藏均可,博主会经常更新,与大家共同进步
- 下一篇研究一下 rabbitmq WorkPool ( 接收数据工作池)