打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
ejabberd分析(三)启动流程

  1. application:start(ejabberd).  

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

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

description, vsn, modules, registered, applications

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

  1.  {application, ejabberd,  
  2.  [{description, "ejabberd"},  
  3.   {vsn, "2.1.7"},  
  4.   {modules, [acl,  
  5.   ......  
  6.   {registered, [ejabberd,  
  7.   ......  
  8.   {applications, [kernel, stdlib]},  
  9.   {env, []},  
  10.   {mod, {ejabberd_app, []}}]}.  

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

ejabberd_app.erl 中的start/2 :

  1. start(normal, _Args) ->  
  2.     ejabberd_loglevel:set(4),  
  3.     write_pid_file(),  
  4.     application:start(sasl),  
  5.     randoms:start(),  
  6.     db_init(),  
  7.     sha:start(),  
  8.     stringprep_sup:start_link(),  
  9.     xml:start(),  
  10.     start(),  
  11.     translate:start(),  
  12.     acl:start(),  
  13.     ejabberd_ctl:init(),  
  14.     ejabberd_commands:init(),  
  15.     ejabberd_admin:start(),  
  16.     gen_mod:start(),  
  17.     ejabberd_config:start(),  
  18.     ejabberd_check:config(),  
  19.     connect_nodes(),  
  20.     %% Loading ASN.1 driver explicitly to avoid races in LDAP  
  21.     catch asn1rt:load_driver(),  
  22.     Sup = ejabberd_sup:start_link(),  
  23.     ejabberd_rdbms:start(),  
  24.     ejabberd_auth:start(),  
  25.     cyrsasl:start(),  
  26.     % Profiling  
  27.     %ejabberd_debug:eprof_start(),  
  28.     %ejabberd_debug:fprof_start(),  
  29.     maybe_add_nameservers(),  
  30.     start_modules(),  
  31.     ejabberd_listener:start_listeners(),  
  32.     INFO_MSG("ejabberd ~s is started in the node ~p", [?VERSION, node()]),  
  33.     Sup;  
 我们可以看到它调用了一系列的方法和函数来完成整个应用的启动。

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

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

  1. 3. application:start(sasl) //启动sasl应用 ,具体sasl应用所提供的服务请查看<a href="http://www.erlang.org/doc/man/sasl_app.html">sasl</a>  

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

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

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

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

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

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

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

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

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

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

  1. 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}的虚方法。


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

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

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

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

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

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

  1. {ok, {{one_for_one, 10, 1},  
  2.       [Hooks,  
  3.        NodeGroups,  
  4.        SystemMonitor,  
  5.        Router,  
  6.        SM,  
  7.        S2S,  
  8.        Local,  
  9.        Captcha,  
  10.        ReceiverSupervisor,  
  11.        C2SSupervisor,  
  12.        S2SInSupervisor,  
  13.        S2SOutSupervisor,  
  14.        ServiceSupervisor,  
  15.        HTTPSupervisor,  
  16.        HTTPPollSupervisor,  
  17.        IQSupervisor,  
  18.        STUNSupervisor,  
  19.        FrontendSocketSupervisor,  
  20.        CacheTabSupervisor,  
  21.        Listener]}}  

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

  1. Hooks =  
  2.     {ejabberd_hooks,  
  3.      {ejabberd_hooks, start_link, []},  
  4.      permanent,  
  5.      brutal_kill,  
  6.      worker,  
  7.      [ejabberd_hooks]}  
子进程定义的格式为:{Id, StartFunc, Restart, Shutdown, Type, Modules}

                id:  分配的ID

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

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

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

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

                Modules:  回调模块

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

   

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

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

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

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



本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
配置加载
ASP.NET MVC请求处理管道生命周期的19个关键环节(1-6)
win10应用Application Identity解决不能自动启动问题
Thinkphp 框架配置操作之配置加载与读取配置实例分析
阿帕奇·卡夫卡
Paimei调试跟踪示例
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服