• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            飛天

            快樂的生活......

             

            nginx源碼分析—啟動流程

            . 序
            1. main()分析
            2. 注意問題
            2.1 幾個初值
            2.2 nginx工作模式
            2.3 一些配置
            2.4 其他開關(guān)
            3. 小結(jié)

            0. 

            本文主要分析nginx主程序。

            nginx主程序main()實現(xiàn)文件:./src/core/nginx.c.表示nginx-1.0.4代碼目錄,本文為/usr/src/nginx-1.0.4

            1. main()分析

            nginx啟動過程如下。

            • 調(diào)用ngx_get_options()解析命令參數(shù);
            • 調(diào)用ngx_time_init()初始化并更新時間,如全局變量ngx_cached_time
            • 調(diào)用ngx_log_init()初始化日志,如初始化全局變量ngx_prefix,打開日志文件ngx_log_file.fd
            • 清零全局變量ngx_cycle,并為ngx_cycle.pool創(chuàng)建大小為1024B的內(nèi)存池;
            • 調(diào)用ngx_save_argv()保存命令行參數(shù)至全局變量ngx_os_argvngx_argcngx_argv中;
            • 調(diào)用ngx_process_options()初始化ngx_cycleprefix, conf_prefix, conf_file, conf_param等字段;
            • 調(diào)用ngx_os_init()初始化系統(tǒng)相關(guān)變量,如內(nèi)存頁面大小ngx_pagesize,ngx_cacheline_size,最大連接數(shù)ngx_max_sockets等;
            • 調(diào)用ngx_crc32_table_init()初始化CRC(后續(xù)的CRC校驗通過查表進行,效率高)
            • 調(diào)用ngx_add_inherited_sockets()繼承sockets
              • 解析環(huán)境變量NGINX_VAR="NGINX"中的sockets,并保存至ngx_cycle.listening數(shù)組;
              • 設(shè)置ngx_inherited=1
              • 調(diào)用ngx_set_inherited_sockets()逐一對ngx_cycle.listening數(shù)組中的sockets進行設(shè)置;
              • 具體可參考<nginx源碼分析—初始化過程中處理繼承的sockets>
            • 初始化每個moduleindex,并計算ngx_max_module;具體可參考<nginx源碼分析—模塊及其初始化>
            • 調(diào)用ngx_init_cycle()進行初始化;
              • 該初始化主要對ngx_cycle結(jié)構(gòu)進行;
              • 具體可參考<nginx源碼分析—全局變量ngx_cycle的初始化>
            • 若有信號,則進入ngx_signal_process()處理;
            • 調(diào)用ngx_init_signals()初始化信號;主要完成信號處理程序的注冊;
            • 若無繼承sockets,且設(shè)置了守護進程標識,則調(diào)用ngx_daemon()創(chuàng)建守護進程;
            • 調(diào)用ngx_create_pidfile()創(chuàng)建進程記錄文件;(NGX_PROCESS_MASTER=1進程,不創(chuàng)建該文件)
            • 進入進程主循環(huán);
              • 若為NGX_PROCESS_SINGLE=1模式,則調(diào)用ngx_single_process_cycle()進入進程循環(huán);
              • 否則為master-worker模式,調(diào)用ngx_master_process_cycle()進入進程循環(huán);
              • 具體可參考<nginx源碼分析—master/worker進程啟動>

             

            簡要的函數(shù)調(diào)用圖如下。具體的還是需要閱讀源代碼。圖的自動生成,可參考<Graphviz可視化函數(shù)調(diào)用-使用開源軟件來簡化復(fù)雜調(diào)用結(jié)構(gòu)>


            2. 注意問題

            2.1 幾個初值 

            1. 00353:    ngx_cycle = cycle;  /* cycle是調(diào)用ngx_init_cycle()的返回值,而調(diào)用該函數(shù)的參數(shù)也是ngx_cycle */  
            2. 00354:  
            3. 00355:    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);  
            4. 00356:  
            5. 00357:    if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) { /* ccf->master=-1 */  
            6. 00358:        ngx_process = NGX_PROCESS_MASTER;  
            7. 00359:    }  
            此處單獨將該段代碼拿出來,說明以下問題。

            ngx_process在此處的值是什么?——NGX_PROCESS_SINGLE=0

            ccf->master在此處的值之什么?——NGX_CONF_UNSET=-1

            ngx_prefix何時初始化的?——ngx_log_init()中初始化

            (1)ccf->master

            ccf->master的值是在ngx_init_cycle()函數(shù)中調(diào)用NGX_CORE_MODULE模塊的create_conf鉤子(callback)完成初始化的。

            具體可參考<nginx源碼分析—core模塊callback>。

            (2)ngx_process

            ngx_process是全局變量,定義如下。

            1. //./src/os/unix/ngx_process_cycle.c  
            2. ngx_uint_t    ngx_process;  
            3. ngx_pid_t     ngx_pid;  
            4. ngx_uint_t    ngx_threaded;  

            其在ngx_init_cycle()中沒有被初始化,故其初值為0。

            (3)ngx_prefix

            1. static u_char      *ngx_prefix;       /* nginx工作目錄,默認為/usr/local/nginx/ */  
            2. static u_char      *ngx_conf_file;    /* 配置文件 */  
            3. static u_char      *ngx_conf_params;  /* nginx指令 */  
            在ngx_log_init()中初始化。

            實際上,在main()函數(shù)開始調(diào)用的ngx_get_options()函數(shù),即是處理nginx啟動的命令,并從中獲取參數(shù)并賦予相應(yīng)的變量。

            -p:ngx_prefix

            -c:ngx_conf_file

            -g:ngx_conf_params

            -s:ngx_signal

            關(guān)于這一點,可從以下命令結(jié)果看出端倪。

            [plain] view plaincopy
            1. # ./nginx -h  
            2. nginx: nginx version: nginx/1.0.4  
            3. nginx: Usage: nginx [-?hvVtq] [-s signal] [-c filename] [-p prefix] [-g directives]  
            4.   
            5. Options:  
            6.   -?,-h         : this help  
            7.   -v            : show version and exit  
            8.   -V            : show version and configure options then exit  
            9.   -t            : test configuration and exit  
            10.   -q            : suppress non-error messages during configuration testing  
            11.   -s signal     : send signal to a master process: stop, quit, reopen, reload  
            12.   -p prefix     : set prefix path (default: /usr/local/nginx/)  
            13.   -c filename   : set configuration file (default: conf/nginx.conf)  
            14.   -g directives : set global directives out of configuration file  

            2.2 nginx工作模式

            因此,main()函數(shù)返回前調(diào)用ngx_master_process_cycle()函數(shù)進入多進程(master/worker)工作模式。如下。

            1. 00401:    if (ngx_process == NGX_PROCESS_SINGLE) {  /* 單進程 */  
            2. 00402:        ngx_single_process_cycle(cycle);  
            3. 00403:  
            4. 00404:    } else {                                  /* 多進程 */  
            5. 00405:        ngx_master_process_cycle(cycle);  
            6. 00406:    }  
            具體請參考<nginx源碼分析—master/worker進程啟動>。

            2.3 一些配置

            看源代碼時,會注意到有些宏(宏全部大寫,中間用下劃線隔開,這是nginx代碼規(guī)范。實際上,絕大多數(shù)系統(tǒng)均采用此規(guī)范)找不到定義,例如NGX_PREFIX、NGX_CONF_PREFIX、NGX_CONF_PATH等。

            實際上,這些宏定義由configure程序進行自動配置時生成。配置時會自動生成ngx_auto_config.h文件(如果你用source insight閱讀源代碼,需要將該文件加入工程),如下。

            ./objs/ngx_auto_config.h(此處列出其中一部分常用的宏,未按順序)

            1. #ifndef NGX_COMPILER  
            2. #define NGX_COMPILER  "gcc 4.6.1 20110908 (Red Hat 4.6.1-9) (GCC) "  
            3. #endif  
            4.   
            5. #ifndef NGX_PCRE  
            6. #define NGX_PCRE  1  
            7. #endif  
            8.   
            9. #ifndef NGX_PREFIX  
            10. #define NGX_PREFIX  "/usr/local/nginx/"  
            11. #endif  
            12.   
            13. #ifndef NGX_CONF_PREFIX  
            14. #define NGX_CONF_PREFIX  "conf/"  
            15. #endif  
            16.   
            17. #ifndef NGX_CONF_PATH  
            18. #define NGX_CONF_PATH  "conf/nginx.conf"  
            19. #endif  
            20.   
            21. #ifndef NGX_PID_PATH  
            22. #define NGX_PID_PATH  "logs/nginx.pid"  
            23. #endif  
            24.   
            25. #ifndef NGX_LOCK_PATH  
            26. #define NGX_LOCK_PATH  "logs/nginx.lock"  
            27.   
            28. #ifndef NGX_ERROR_LOG_PATH  
            29. #define NGX_ERROR_LOG_PATH  "logs/error.log"  
            30. #endif  
            31.   
            32. #ifndef NGX_HTTP_LOG_PATH  
            33. #define NGX_HTTP_LOG_PATH  "logs/access.log"  
            34. #endif  
            35.   
            36. #ifndef NGX_HTTP_CLIENT_TEMP_PATH  
            37. #define NGX_HTTP_CLIENT_TEMP_PATH  "client_body_temp"  
            38. #endif  
            39.   
            40. #ifndef NGX_HTTP_PROXY_TEMP_PATH  
            41. #define NGX_HTTP_PROXY_TEMP_PATH  "proxy_temp"  
            42. #endif  

            2.4 其他開關(guān)

            還有一些開關(guān),如NGX_FREEBSD, NGX_PCRE,NGX_OPENSSL等,這些宏也在configure過程中自動配置。nginx啟動時會根據(jù)這些宏是否定義調(diào)用相應(yīng)的函數(shù)。此處非本文重點,不再贅述。

            以上3個宏分別調(diào)用相應(yīng)函數(shù)進行debug的初始化、正則表達式初始化和SSL的初始化。如下。(代碼未按順序)

            1. #if (NGX_FREEBSD)  
            2.     ngx_debug_init();  
            3. #endif  
            4.   
            5. #if (NGX_PCRE)  
            6.     ngx_regex_init();  
            7. #endif  
            8.   
            9. #if (NGX_OPENSSL)  
            10.     ngx_ssl_init(log);  
            11.   
            12. #endif  

            3. 小結(jié)

            本文簡單分析nginx的啟動過程,后文繼續(xù)分析其中的ngx_init_cycle()和master/worker工作模型。

            Reference

            http://www.tbdata.org/archives/1092

            http://www.w3.org/TR/PNG (CRC相關(guān))

            Nginx代碼研究計劃 (RainX1982)

            nginx源碼分析—模塊及其初始化 (阿波)

            nginx源碼分析—內(nèi)存池結(jié)構(gòu)ngx_pool_t及內(nèi)存管理 (阿波)

            nginx源碼分析—數(shù)組結(jié)構(gòu)ngx_array_t (阿波)

            nginx源碼分析—鏈表結(jié)構(gòu)ngx_list_t (阿波)

            nginx源碼分析—隊列結(jié)構(gòu)ngx_queue_t (阿波)

            nginx源碼分析—模塊及其初始化 (阿波)

            nginx源碼分析—內(nèi)存池結(jié)構(gòu)ngx_pool_t及內(nèi)存管理 (阿波)

            nginx源碼分析—數(shù)組結(jié)構(gòu)ngx_array_t (阿波)

            nginx源碼分析—鏈表結(jié)構(gòu)ngx_list_t (阿波)

            nginx源碼分析—隊列結(jié)構(gòu)ngx_queue_t (阿波)

            nginx源碼分析—hash結(jié)構(gòu)ngx_hash_t(v1.0.4) (阿波)

            posted on 2012-07-02 17:14 飛天 閱讀(378) 評論(0)  編輯 收藏 引用


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            導(dǎo)航

            統(tǒng)計

            常用鏈接

            留言簿(2)

            隨筆分類

            隨筆檔案

            文章分類

            文章檔案

            Blogs

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            日韩va亚洲va欧美va久久| 久久久久久久久波多野高潮| 精品国产青草久久久久福利| 久久人人爽人爽人人爽av | 国产午夜免费高清久久影院| 久久久久人妻一区精品果冻| 久久久久久九九99精品| 国产美女久久精品香蕉69| 久久综合狠狠综合久久综合88| 亚洲成色WWW久久网站| 久久精品水蜜桃av综合天堂| 伊人久久大香线蕉影院95| 久久久国产精华液| 亚洲级αV无码毛片久久精品| 精品国产99久久久久久麻豆| 99久久人妻无码精品系列 | 久久精品中文字幕无码绿巨人| 久久精品国产亚洲77777| 2020最新久久久视精品爱| 中文字幕精品无码久久久久久3D日动漫| 久久露脸国产精品| 中文字幕无码精品亚洲资源网久久| 久久国产欧美日韩精品| 久久久无码精品午夜| 久久亚洲春色中文字幕久久久| 久久精品成人国产午夜| 欧美牲交A欧牲交aⅴ久久| 亚洲国产成人久久精品99| 久久99精品国产麻豆不卡| 精品久久久久久国产91| 久久久久久久久久久久中文字幕| 亚洲人成精品久久久久| 久久久久久久女国产乱让韩| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 久久99精品久久只有精品| 色欲综合久久中文字幕网| 亚洲精品无码久久久久久| 国内精品综合久久久40p| 一本色道久久综合亚洲精品| 久久AV高潮AV无码AV| 亚洲av伊人久久综合密臀性色|