ZeroMQ 4.2.2 源代码分析(四)- Malamute

The ZeroMQ Enterprise Messaging Broker
https://github.com/zeromq/malamute

1. zactor_t

ZeroMQ 4.2.2 源代码分析(四)- Malamute_第1张图片

zactor_t是CZMQ提供的接口。CZMQ是对ZeroMQ的C接口包装。

zactor_t与shim_t总是成对出现。Zactor_t面向客户,shim_t在后台处理。创建zactor_t时,会同时创建shim_t和一个新的线程,shim_t在这个新线程中运行。aactor_t还会创建一对pair_t的socket,分别绑定到shim_t和它自己,以便两者通信。

客户可以通过zactor_new()指定shim_t运行的函数zactor_fn,从而处理真正的业务。

typedef void (zactor_fn) (zsock_t* pipe, void* args);

第一个参数是shim_t的pair_t socket,用它可以接收来自客户的配置命令。第二个参数是客户通过zactor_new()指定的额外参数,这个参数一般被用来指定另外一个zsock_t。这样,zactor_t就有了两个zsock_t,一个用作配置命令,一个用作消息交互。

2. mlm_server (第一个zactor_fn)

ZeroMQ 4.2.2 源代码分析(四)- Malamute_第2张图片

Malamute的server端的一个zactor_t以mlm_server作为zactor_fn。在mlm_server中,做如下事情:

  • 创建一个新的router_t类型的zsock_t,以便接收client的消息再转发至若干个client。
  • 创建一个zloop_t,以便监听来自前台zactor_t的配置消息,和来自router_t的client消息。 除了zactor_t,s_server_t的配置也可以从配置文件读取,所以zloop_t也监听一个1秒的定时器消息,以便监听配置文件的变化。
  • zloop_t内部用poll机制实现监听。

3. zauth (Malamute的第二个zactor_fn)

ZeroMQ 4.2.2 源代码分析(四)- Malamute_第3张图片

Malamute的server端如果需要校验client的身份,它还会创建一个zactor_t,将zauth作为zactor_fn。在zauth中,做如下事情:

  • 创建一个rep_t类型的zsock_t,以便接收client的认证消息,并回复认证结果。
  • 创建一个zloop_t,以便监听来自zactor_t的配置消息,和来自rep_t的client认证消息。
  • zloop_t使用zpoller_t,但实际上内部还是使用poll机制。

4. mlm_client (第三个zactor_fn)

ZeroMQ 4.2.2 源代码分析(四)- Malamute_第4张图片

Malamute的client端的对外接口是mlm_client_t,它是zactor_t的包装。它以mlm_client作为zactor_fun。在mlm_client,做如下事情:

  • 创建一对pair_t类型的zsock_t,分别绑定在mlm_client_t和s_client_t上,用于消息交互。
  • 创建一个dealer_t类型的zsock_t,与pair_t类型的zsock_t以接力的方式,完成消息收发。
  • zactor_t创建的一对pair_t类型的zsock_t用户配置命令。

5. mlm_stream_simple (第四个zactor_fn)

ZeroMQ 4.2.2 源代码分析(四)- Malamute_第5张图片

Malamute的server端为每条数据流创建一个stream_t。zactor_t以mlm_stream_simple为zactor_fun。在mlm_stream_simple中,做如下事情:

  • 创建stream_engine_t
  • 创建zpoller_t,以便监听来自zactor的配置命令和来自stream_t的消息。
  • 当客户注册过滤条件是,stream_engine_t负责保存;当客户发送消息时,stream_engine_t负责根据过滤条件找到目标客户。

6. server端和client端的数据交互

  • client端创建mlm_client_t,并设置mechanism。如果是plain mechanism,则需要设置用户名和密码。它们会写入zsock_t的选项。
  • 连接server端。如果plain mechanism,则自动发送用户密码完成认证。
    • 在server端,zauth函数从rep_t读取认证消息,在本地用户列表中查询,如果用户密码匹配,则认证成功。zauth的用户密码信息是从本地配置文件读取的。
  • 连接成功后, client端发送注册请求MLM_PROTO_CONNECTION_OPEN(message type=0x01)。注意reader是用户的名字。注意这里的“用户”跟zauth的“用户”不同。连接和认证是互相独立的。每个连接有自己的用户名,但多个连接可以使用同一个zauth的用户名进行认证。
0xAAA8 0x01 0x08 + MALAMUTE 0x01 0x06 + reader
2 oct 1 1 + 8 1 1 + 6
signature message id/type protocol name protocol version client name
  • 在server端,mlm_server函数从router_t读取注册消息。因为router_t的消息组总是以identity消息开头,所以mlm_server可以根据identity查询本地用户列表。如果查询不到,则增加新条目。
  • 然后mlm_server发送注册请求的结果MLM_PROTO_OK(message type=0x0f)。0xc8(200)代表成功。
0xAAA8 0x0F 0x00C8 0x00
2 oct 1 2 1
signature message id/type status code status reason(length + value)
  • 如果注册成功,client端继续发送自己的过滤条件消息MLM_PROTO_STREAM_READ(message type=0x06)。stream是流名字,pattern是client要求的消息格式。
0xAAA8 0x06 0x07 + weather 0x06 + Temp.*
2 oct 1 1 + 8 1 + 6
signature message id/type stream name pattern
  • 在server端,mlm_server函数从router_t读取过滤条件消息。mlm_server根据stream名字查找本地stream列表。如果查询不到,则增加新条目,并创建一个mlm_stream_simple线程处理该stream的过滤业务。
  • 上表是subscriber客户的注册消息。下表是publisher客户的注册消息MLM_PROTO_STREAM_WRITE(message type=0x05):
0xAAA8 0x05 0x07 + weather
2 oct 1 1 + 8
signature message id/type stream name

相关链接

ZeroMQ 4.2.2 源代码分析(一)
ZeroMQ 4.2.2 源代码分析(二)
ZeroMQ 4.2.2 源代码分析(三)
ZeroMQ 4.2.2 源代码(四)- Malamute

你可能感兴趣的:(ZeroMQ 4.2.2 源代码分析(四)- Malamute)