[Erlang 0096] RabbitMQ Boot Step

来源:互联网 发布:周杰被黑真相知乎 编辑:程序博客网 时间:2024/06/06 14:08

   之前提到[链接]RabbitMQ会把启动过程分成若干阶段,按照依赖关系进行启动.rabbit_boot_step里面的requires 和 enables配置节是描述这种依赖关系的关键.require约定了该项目启动所依赖的前置条件,enables 表示当前项目启动之后可以启动什么;如果有多个项目enable一个项目(比如:external_infrastructure),要等这些项目都启动了external_infrastructure 才可以启动. 
 
   为什么要搞得那么复杂?一股脑调用启动不就行了?RabbitMQ启动过程中复杂的依赖关系,以及灵活扩展的要求,不可能随机顺序启动或者硬编码启动顺序.官方在GitHub上面举了一个例子:
 
   Boot steps can be separated into groups. A group of boot steps will enabled certain other group. For example routing_ready is actually enabled by many others boot steps, not just recovery. One of such steps is the empty_db_check that ensures that the Mnesia, Erlang's built-in distributed database, has the default data, like the default guest user for example. Also we can see that the recovery boot step also depends on empty_db_check so this logic takes care of running them in the right order that will satisfy the interdependencies they have.
 
 看一下上面所说的图形效果,这只是RabbitMQ整个启动过程的片段,[ 完整高清大图请点击这里 ]:
 

 
  整个启动过程,会被构造成一个有向无循环图,这里可以参考rabbit.erl的sort_boot_step方法
 
复制代码
sort_boot_steps(UnsortedSteps) ->    case rabbit_misc:build_acyclic_graph(fun vertices/2, fun edges/2,                                         UnsortedSteps) of        {ok, G} ->            %% Use topological sort to find a consistent ordering (if            %% there is one, otherwise fail).            SortedSteps = lists:reverse(                            [begin                                 {StepName, Step} = digraph:vertex(G,                                                                   StepName),                                 Step                             end || StepName <- digraph_utils:topsort(G)]),            digraph:delete(G),            %% Check that all mentioned {M,F,A} triples are exported.            case [{StepName, {M,F,A}} ||                     {StepName, Attributes} <- SortedSteps,                     {mfa, {M,F,A}}         <- Attributes,                     not erlang:function_exported(M, F, length(A))] of                []               -> SortedSteps;                MissingFunctions -> basic_boot_error(                                      {missing_functions, MissingFunctions},                                      "Boot step functions not exported: ~p~n",                                      [MissingFunctions])            end;        {error, {vertex, duplicate, StepName}} ->            basic_boot_error({duplicate_boot_step, StepName},                             "Duplicate boot step name: ~w~n", [StepName]);        {error, {edge, Reason, From, To}} ->            basic_boot_error(              {invalid_boot_step_dependency, From, To},              "Could not add boot step dependency of ~w on ~w:~n~s",              [To, From,               case Reason of                   {bad_vertex, V} ->                       io_lib:format("Boot step not registered: ~w~n", [V]);                   {bad_edge, [First | Rest]} ->                       [io_lib:format("Cyclic dependency: ~w", [First]),                        [io_lib:format(" depends on ~w", [Next]) ||                            Next <- Rest],                        io_lib:format(" depends on ~w~n", [First])]               end])    end.
复制代码

DEMO


 看一个具体例子,RabbitMQ in Action 一书中rabbit_exchange_type_recent_history扩展.代码url: https://github.com/rabbitinaction/sourcecode 看看它的启动规格说明:

复制代码
-rabbit_boot_step({?MODULE,[{description, "exchange type x-recent-history"},{mfa, {rabbit_registry, register,[exchange, <<"x-recent-history">>, ?MODULE]}},{requires, rabbit_registry},{enables, kernel_ready}]}).-rabbit_boot_step({rabbit_exchange_type_recent_history_mnesia,[{description, "recent history exchange type: mnesia"},{mfa, {?MODULE, setup_schema, []}},{requires, database},{enables, external_infrastructure}]}).
复制代码
  参照上面的高清大图,可以看一下它会在什么位置完成上面两步操作.下面我们重新编译启动Rabbit,看下启动过程的输出,注意新增的部分:
 
复制代码
Eshell V5.9  (abort with ^G)(rabbit@nimbus)1>+---+   +---+|   |   |   ||   |   |   ||   |   |   ||   +---+   +-------+|                   || RabbitMQ  +---+   ||           |   |   ||   v3.0.0  +---+   ||                   |+-------------------+AMQP 0-9-1 / 0-9 / 0-8Copyright (C) 2007-2012 VMware, Inc.Licensed under the MPL.  See http://www.rabbitmq.com/node           : rabbit@nimbusapp descriptor : /data/rabbitmq-server-3.0.0/scripts/../ebin/rabbit.apphome dir       : /rootconfig file(s) : (none)cookie hash    : qhI/+VnjqUPUYcXLZ2jZMQ==log            : /var/log/rabbitmq/rabbit@nimbus.logsasl log       : /var/log/rabbitmq/rabbit@nimbus-sasl.logdatabase dir   : /var/lib/rabbitmq/mnesia/rabbit@nimbuserlang version : 5.9-- rabbit boot startstarting file handle cache server                                     ...donestarting worker pool                                                  ...donestarting database                                                     ...donestarting database sync                                                ...donestarting codec correctness check                                      ...donestarting recent history exchange type: mnesia                         ...done  %%% 看这里 看这里-- external infrastructure readystarting statistics event manager                                     ...donestarting logging server                                               ...donestarting plugin registry                                              ...donestarting auth mechanism amqplain                                      ...donestarting auth mechanism cr-demo                                       ...donestarting auth mechanism plain                                         ...donestarting exchange type direct                                         ...donestarting exchange type fanout                                         ...donestarting exchange type headers                                        ...donestarting exchange type x-recent-history                               ...done   %%%%   看这里 看这里 starting exchange type topic                                          ...done-- kernel readystarting node monitor                                                 ...donestarting cluster delegate                                             ...donestarting guid generator                                               ...donestarting alarm handler                                                ...donestarting memory monitor                                               ...done-- core initializedstarting empty DB check                                               ...donestarting background garbage collection                                ...donestarting HA policy validation                                         ...donestarting policy parameters                                            ...donestarting exchange, queue and binding recovery                         ...donestarting mirror queue slave sup                                       ...donestarting adding mirrors to queues                                     ...done-- message delivery logic readystarting error log relay                                              ...donestarting networking                                                   ...donestarting notify cluster nodes                                         ...donestarting direct client                                                ...donebroker running
复制代码
 
 
  感兴趣的话,可以输出rabbit:boot_steps()看一下,内容略长,请展开:
 
Boot Step Dump

 

  最后小图一张:迅哥,周末愉快!

原创粉丝点击