欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

RabbitMQ源码分析 - 启动

程序员文章站 2022-07-13 15:10:58
...

RabbitMQ是一个消息队列的实现,基于AMQPAdvanced Message Queuing Protocol)。最近因为工作需要,打算深入了解RabbitMQ的架构以实现,后续会出一系列文章记录分析过程。这篇总结RabbitMQ的启动过程。

(注:分析代码基于RabbitMQ 2.8.2

 

         RabbitMQ的启动入口在[$RABBIT_SRC/src/rabbit.erl --> start/2]。主要代码如下:

start(normal, []) ->
    case erts_version_check() of
        ok ->
            {ok, SupPid} = rabbit_sup:start_link(),
            true = register(rabbit, self()),
            [ok = run_boot_step(Step) || Step <- boot_steps()],
            io:format("~nbroker running~n"),
            {ok, SupPid};
        Error ->
            Error
end.
其中rabbit_sup:start_link/0启动rabbit的监控树。最重要是这个调用[ok = run_boot_step(Step) || Step <- boot_steps()]

boot_steps会从已加载的模块中提取自定义属性rabbit_boot_step的值(大部分定义在[$RABBIT_SRC/src/rabbit.erl]文件中),该结构定义了rabbit在启动过程中的一个启动步骤,其中包含:启动该步骤的启动入口,该步骤所依赖的步骤以及依赖于该步骤的步骤。其结构如下:

-rabbit_boot_step({rabbit_registry,
                   [{description, "plugin registry"},
                    {mfa,         {rabbit_sup, start_child,
                                   [rabbit_registry]}},
                    {requires,    external_infrastructure},
                    {enables,     kernel_ready}]}).
 其中rabbit_registry定义步骤名称,mfa定义启动入口,requires定义该步骤所依赖的步骤(组名),enables说明依赖于该步骤成功执行的步骤。

         启动步骤可以分组。一组步骤的启动会依赖于另一组步骤的成功执行。像上面的rabbit_registry就依赖于external_infrastructure(包含多个启动步骤)的成功执行,而rabbit_registry的成功启动则会使kernel_ready进入准备状态。实际上,会有多个启动步骤会使kernel_ready进入准备状态,只有所有这些启动步骤都成功启动后,依赖于kernel_ready的步骤才能启动(像rabbit_log, rabbit_event都会使kernel_ready进入准备状态)。

         RabbitMQ就根据这些启动步骤之间的依赖关系,构造一个有向无环图(这跟我在ganger里对进程依赖关系的组织类似),并拓扑排序所有步骤(参见[$RABBIT_SRC/src/rabbit.erl --> sort_boot_steps/2]),生成唯一的启动顺序,然后按照该启动顺序调用相应启动步骤的MFA启动相应功能(参见[$RABBIT_SRC/src/rabbit.erl --> run_boot_steps/2])。

(具体有哪些启动步骤,以及每个步骤的具体功能参见这篇文章:RabbitMQ Boot Process

相关标签: erlang rabbitmq