rabbitmq -- networking

时间:2021-04-07 13:36:34

RabbitMQ大名鼎鼎, 其networking 部分经常被众多Erlang 程序员, 爱好者分析. 小的时候就见到很多人写过这方面的blog, 比如:

1, http://www.blogjava.net/killme2008/archive/2009/11/29/304079.html

2, http://jzhihui.iteye.com/blog/1544779

基本上就是很简单明了的结构。

RabbitMQ networking 监控树结构

使用observer 来查看RabbitMQ networking 的监控树结构, 大致是这样的:

rabbitmq -- networking

其中:

1, rabbit_net_sup 是整个RabbitMQ的 主supervisor 进程

2, 进程<0.47.0> 是一个实例的tcp_listener_sup, 因为RabbitMQ 的networking 允许可以同时listen 多个端口, 所以此处的tcp_listener_sup 是匿名进程

3, 进程<0.49.0> 是一个实例的listen 进程, 负责监听端口,并在tcp_acceptor_sup 监控进程下start_child 执行数量的acceptor 进程

4, tcp_acceptor_sup_:::19000 是所有acceptor 进程的监控进程

5, 进程<0.50.0> 是实例的acceptor 进程, 负责异步接收新建立的socket 并执行 OnConnect 函数, 在rabbit_tcp_client_sup 监控进程下创建client 进程

6, <0.267.0>, <0.268.0>, <0.270.0> 是client 进程, 每个client 进程对应一个socket

在实际的RabbitMQ 中, client 进程是一个supervisor 进程, 其中包包括一个rabbit_reader 进程和一个 helper 进程

RabbitMQ networking 代码结构

为了比较清晰的学习下这部分的代码姿势, 我做了一个简单的代码抽离, 将RabbitMQ 的networking 的代码单独出来一个application. 代码module 大致是这个样子的:

rabbitmq -- networking

(哈哈, sublime 要比emacs 轻一些, 不用emacs 后, 我的电脑轻了不少)

这其中:

1, file_handle_cache, gen_server2 是辅助性的module

2, rabbit_net_app 是application的 start, 并boot net

boot net 的流程主要分为三个部分:

2.1 将epmd 分配给本node 的端口, 写入mnesia

2.2 启动rabbit_tcp_client_sup 并声明其工作子进程

2.3 启动tcp_listener_sup, tcp_listener_sup 会先后start tcp_acceptor_sup_:::19000 进程和listen 进程, tcp_acceptor_sup_:::19000 进程会声明自己的子工作进程(也就是acceptor 进程), listen 进程会监听端口, 并在tcp_acceptor_sup_:::19000 进程下start_child 指定数量的acceptor 进程

社区相关

在社区,有不少人用RabbitMQ的networking 做了一些事情,比如最近和小伙伴讨论比较多的esockd , 大致看来, 作者是以RabbitMQ 的networking 作为蓝本, 在此基础上做了一些代码结构的调整.

总结

epmd 可扩展性阅读: http://blog.yufeng.info/archives/539