ejabberd分析(三)启动流程

ejabberd的启动从ejabberd:start() 开始。

application:start(ejabberd).

application用来表示一个可以单独启动和停止、并被复用的程序单元。通常一个application都有一个同名的app文件来定义。

对于系统工具(systool)直接调用的app文件必须包含以下几项:

description, vsn, modules, registered, applications

我们查看ejabberd.app可以看到以下内容:

 {application, ejabberd,
 [{description, "ejabberd"},
  {vsn, "2.1.7"},
  {modules, [acl,
  ......
  {registered, [ejabberd,
  ......
  {applications, [kernel, stdlib]},
  {env, []},
  {mod, {ejabberd_app, []}}]}.

最后一项:mod 定义了应用程序的回调模块和启动参数。 在应用程序启动时会由主导进程来调用这个模块的start/2方法。

ejabberd_app.erl 中的start/2 :

start(normal, _Args) ->
    ejabberd_loglevel:set(4),
    write_pid_file(),
    application:start(sasl),
    randoms:start(),
    db_init(),
    sha:start(),
    stringprep_sup:start_link(),
    xml:start(),
    start(),
    translate:start(),
    acl:start(),
    ejabberd_ctl:init(),
    ejabberd_commands:init(),
    ejabberd_admin:start(),
    gen_mod:start(),
    ejabberd_config:start(),
    ejabberd_check:config(),
    connect_nodes(),
    %% Loading ASN.1 driver explicitly to avoid races in LDAP
    catch asn1rt:load_driver(),
    Sup = ejabberd_sup:start_link(),
    ejabberd_rdbms:start(),
    ejabberd_auth:start(),
    cyrsasl:start(),
    % Profiling
    %ejabberd_debug:eprof_start(),
    %ejabberd_debug:fprof_start(),
    maybe_add_nameservers(),
    start_modules(),
    ejabberd_listener:start_listeners(),
    ?INFO_MSG("ejabberd ~s is started in the node ~p", [?VERSION, node()]),
    Sup;
 我们可以看到它调用了一系列的方法和函数来完成整个应用的启动。

1. ejabberd_loglevel:set(4)  //设置日志级别

2. write_pid_file()  //将当前进程标识写到环境变量EJABBERD_PID_PATH定义的文件中

3. application:start(sasl) //启动sasl应用 ,具体sasl应用所提供的服务请查看sasl

4. randoms:start() //注册一个名为random_generator,用当前时间做种子生成随机字符串的进程

5. db_init() //初始化并启动本地的mnesia数据库,并等待直到所有表可用或超时

6. sha:start() //加载一些驱动

7. stringprep_sup:start_link() //启动一个监控进程

8. xml:start() //提供xml处理功能

9. start() //注册进程自身为ejabberd,设置日志目录,加载驱动

10. translate:start()//从环境变量EJABBERD_MSGS_PATH定义的位置找*.msg 并加载到ets:translations 表中(国际化)

11. acl:start() //访问控制

12. ejabberd_ctl:init() //创建两张表ejabberd_ctl_cmds,ejabberd_ctl_host_cmd

13. ejabberd_commands:init()  //创建表ejabberd_commands

14. ejabberd_admin:start() //注册常用的ejabberd_command到表ejabberd_commands
    这里的ejabberd_command类似于java中的虚方法,这个ejabberd_command 具有指定的名称、指定类型数量参数、指定类型返回值。

    例如:

        #ejabberd_commands{name = register, tags = [accounts],
            desc = "Register a user",
            module = ?MODULE, function = register,
            args = [{user, string}, {host, string}, {password, string}],
            result = {res, restuple}},

    定义了一个名为register,接受[{user, string}, {host, string}, {password, string}] 参数,返回{res, restuple}的虚方法。


15. gen_mod:start()   //创建表ejabberd_modules

16. ejabberd_config:start()  //创建config,local_config两张表,并加载配置文件中的配置到表中

17. ejabberd_check:config()  //检查配置文件中指定要加载的模块是否存在

18. connect_nodes()    //建立到集群中其他节点的链接,其他节点在配置中定义

19. Sup = ejabberd_sup:start_link()  //启动一个supervisor,并启动和监控定义的子进程

      详细看下这个supervisior 的init()定义:

{ok, {{one_for_one, 10, 1},
	  [Hooks,
	   NodeGroups,
	   SystemMonitor,
	   Router,
	   SM,
	   S2S,
	   Local,
	   Captcha,
	   ReceiverSupervisor,
	   C2SSupervisor,
	   S2SInSupervisor,
	   S2SOutSupervisor,
	   ServiceSupervisor,
	   HTTPSupervisor,
	   HTTPPollSupervisor,
	   IQSupervisor,
	   STUNSupervisor,
	   FrontendSocketSupervisor,
	   CacheTabSupervisor,
	   Listener]}}

重启策略为one_for_one(只重启终止的子进程自身),如果1s内重启次数超过10则终止所有子进程和自身。列表中为子进程的定义。以Hooks为例子:

Hooks =
	{ejabberd_hooks,
	 {ejabberd_hooks, start_link, []},
	 permanent,
	 brutal_kill,
	 worker,
	 [ejabberd_hooks]}
子进程定义的格式为:{Id, StartFunc, Restart, Shutdown, Type, Modules}

                id:  分配的ID

                StartFunc: 启动子进程时调用的方法

                Restart:  重启子进程时调用的方法

                Shutdown: 关闭子进程时调用的方法

                Type: 子进程的类型,(supervisior or worker)

                Modules:  回调模块

     可以看到这里启动了不少的子进程,从名字上大体上可以看出各个子进程的功能。

   

20. ejabberd_rdbms:start() //启动数据库相关模块
   
21. ejabberd_auth:start() //启动所有鉴权模块
   
22. cyrsasl:start() //启动SASL安全认证模块

23. maybe_add_nameservers() //如果运行在windows系统,则添加域名服务器(DNS)地址到erlang系统中

24. start_modules()   //启动所有节点上的定义在local_config中的模块

25. ejabberd_listener:start_listeners()  //启动配置文件中的监听器模块



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值