分类: 云计算
2017-03-24 13:46:25
在博文Ceph源码分析之Async模块:1、异步通信核心模块EventCenter+Epoll 里面介绍了Async实现异步通信的底层核心模块。这次打算从上层应用来看ceph的通信模型模型。
ceph通信模块的源代码定义在msg目录下,消息类型定义在message目录下面。
ceph各个组件直接的通信以及和客户端直接的通信都依赖与ceph的通信模块,捋清楚通信模块对阅读源代码会有帮助。
先看一张简单的交互图
ceph通信模块的角色主要分为Messenger和Dispatcher两大角色
Messenger
消息管理器,对上负责将消息转给Dispatcher和提供发送消息的接口:send_message,对下负责将应用发送的消息转发给Connection(封装的socket连接实例)
Dispatcher
消息分法器,根据消息类型将消息分发给应用层的具体操作接口
其它涉及到的两个重要的角色
Message
消息格式基类,可以根据需求派生出不同类型的消息,不同的消息类型定义在message目录下面,最大的不同就是msg_type(消息类型)
Connection
连接实例,负责维护同客户端建立的socket连接以及ceph的协议栈操作接口(在Async中间层协议栈的时候会深入介绍),向上提供发送消息接口及转发底层消息给DispathcQueue或者消息管理器,向下发送和介绍消息。
使用ceph通信模块来收发消息
* 发送消息
发消息比较简单,应用只需将消息内容按照需要的消息类型(定义在messaging/*或自定义)进行封装后调用Messenger的send_message即可。
Messenger是如何将消息转给应用的或者说是如何管理?Messenger设计了两个分发器管理成员:dispatchers和fast_dispatchers,用来处理不同类型的请求处理。应用层则按需求将不同的分发器注册给Messenger,进而Messenger接收到底层来的消息时,会将消息分发给已经注册的两个dispatchers。
设计fast_dispatchers的目的就是为了让有些消息能够省去底层的一层流程(比如跳过入队列),直接到达应用。Dispatcher类是一个基类,里面设计封装了应用同Messenger交互的接口(每个具体的Dispatcher派生类自行去实现更具体的消息处理,一般都是再根据消息类型来分开处理消息)。Dispatcher并不是所有的接口封装都是为了转发消息,它更深层次的含义是提供一个应用层和底层的通信接口,而这个接口的桥梁是Messenger消息管理器。
当底层有消息到来时,Messenger会将消息转给dispatcher对于的ms_*系列的接口,最常用的是ms_dispatch接口,因此你可以看到像monitor,osd这些应用的核心消息处理都在ms_dispatch接口里面实现。
最简单的方式就是应用本身作为Dispatcher的派生类,如此,Messenger便是直接通过应用关联,比如Monitor、osd、mgr都是应用组件本身作为Dispatcher的派生类。
申请一个Dispatcher的派生类实例,做为应用的模块注册给Messenger,比如RadosClient里面会注册各个Client给Messenger,而这些Client都是Dispatcher的派生类。
ceph的消息基类是:Message,Message里面设计了一个type成员,用来区分不同的消息类型,不同的消息模块可以通过type来构造,而这些type定义在Message.h中
技巧:比如你想要看某个消息是谁发的,那么你只需要去查看这个消息类型对应的消息模块有哪些,然后再查到谁在使用这个消息模块来封装消息,进而就可以找到发送这个消息的地方。
以ceph-mon为例子,Monitor类继承自Dispatcher
class Monitor : public Dispatcher,
实现它的ms_dispatcher方法,这个方法里面实现了mon的消息处理
注册给Messenger,add_dispatcher_tail方法就是将当前应用添加到dispatcher列表中
Messenger收到消息转给dipatcher
ceph monitor处理消息