ceph 网络模块 源码分析 二
上一篇简单介绍了网络模块中传递的消息类型,本篇主要介绍消息发送和接收的相关模块:
- Messenger 发送和接收消息的类
- Dispatcher: 分发消息的类
- Connection: 定义连接的类
网络模块的设计模式:
ceph的网络模块采用了观察者模式的设计模式:
- Messenger是消息的发布者
- Dispatcher是消息的订阅者
Messenger的订阅者列表dispatchers中保存了所有订阅此消息的Dispatcher对象,每当Messenger对象收来消息时,它调用ms_delivery_dispatch()来将消息分发给所有dispatcher进行处理,所有的Dispatcher对象都实现了ms_dispatch()接口用于具体的消息处理.
Dispatcher中记录了它所订阅的Messenger,所以当新建一个Dispatcher对象是,它会调用Messenger的add_dispatcher_tail()把它注册到Messenger的订阅者列表中.当Dispatcher想发送消息的时候,它调用Messenger对象的send_message()来发送消息.另外,add_dispatcher_tail()还会进行另外一个重要的工作,即启动Messenger的accepter线程和dispatch_thread线程,前者用于监听客户端的连接请求,后者用于处理缓存接收到的消息.
Messenger
/src/msg/Messenger.h
/src/msg/Messenger.cc
作为消息的发布者,Messenger主要三类接口:
- 注册订阅者disspatcher,例如add_dispatcher_tail()
- 发布收到的消息,例如ms_delivery_dispatch()
- 发送消息, 例如send_message()
class Messenger {
private:
// 保存所有订阅者
list<Dispatcher *> dispatchers;
list<Dispatcher *> fast_dispatchers;
protected:
entity_inst_t my_inst;
int default_send_policy;
bool started;
uint32_t magic;
int socket_priority
public:
// 分发收到的消息
void ms_delivery_dispatch(Message *m);
void ms_fast_dispatch(Message *m);
// 注册订阅者
void add_dispatcher_tail(Dispatcher *d);
void add_dispatcher_head(Dispatcher *d);
// 发送消息
virtual int send_message(Message *m, const entity_inst_t& dest) = 0;;
}
Dispatcher
/src/msg/Dispatcher
作为消息的订阅者,Dispatcher主要用于具体的信息处理,它定义了两个处理信息的接口:ms_dispatch()和ms_fast_dispatch().
所有的消息处理应用类都继承自Dispatcher接口,并实现了各自的消息处理接口,例如Monitor,OSD,MDSDaemon等.
class Dispatcher {
public:
// 消息是否可以快速分发
virtual bool ms_can_fast_dispatch(Message *m) const { return false;}
// 快速分发之前的预处理
virtual void ms_fast_preprocess(Message *m) {}
// fast_dispatch和dispatch的唯一的区别是:消息是否要额外处理,
// 如果消息不需要额外处理,可以直接分发,即fast_dispatch
// 否则必须等处理完之后再进行分发.
virutal int ms_fast_dispatch(Message *m) = 0;
virtual bool ms_dispatch(Message *m) = 0;
// 处理连接状态
virtual void ms_handle_connect(Connection *con) {}
virtual void ms_handle_fast_connect(Connection *con) {}
// 回调表示新连接的到来
virtual void ms_handle_accept(Connection *con) {}
virtual void ms_handle_fast_accept(Connection *con) {}
}
Connection
/src/msg/Connection
Conncetion是端到端的socket连接的封装,它最重要的接口是发送消息.
struct Connection {
Messenger *msgr;
int peer_type; // 连接的对端的类型
entity_addr_t peer_addr; // 连接的对端的地址
utime_t last_keepalive; // 最后一次发送keepalive的时间
utime_t last_keepalive_ack; // 最后一次接收keepalive ack的时间
uint64 features;
bool failed;
int rx_buffers_version; // 缓冲区的版本
// 缓冲区: ceph_tid_t -> (buffer, rx_buffers_version)
map<ceph_tid_t,pair<bufferlist,int> > rx_buffers;
//发送消息之前判断连接状态
virtual bool is_connected() = 0;
// 发送消息
virtual int send_message(Message *m) = 0;
// 发送ping,确认连接状态
virtual void send_keepalive() = 0;
}