Nginx源碼分析之開篇
作者:那一劍的風(fēng)情
Nginx源碼構(gòu)思精巧,每每閱讀頗有收獲,寫此文與各碼農(nóng)分享。閱讀從main開始,流程非常清晰。
Nginx源碼構(gòu)思精巧,每每閱讀頗有收獲,寫此文與各碼農(nóng)分享。
閱讀從main開始,流程非常清晰。
- /* 系統(tǒng)錯(cuò)誤初始化,將構(gòu)建ngx_sys_errlist */
- ngx_strerror_init();
- /* 選項(xiàng)處理 */
- ngx_get_options(argc, argv);
- /* 時(shí)間初始化, 當(dāng)前時(shí)間:ngx_current_msec */
- ngx_time_init();
- /* 日志初始化 */
- log = ngx_log_init(ngx_prefix);
- /* 選項(xiàng)處理 */
- ngx_save_argv(..., argc, argv);
- ngx_process_options(...);
- /* 操作系統(tǒng)初始化處理 */
- ngx_os_init(log);
- /* 模塊點(diǎn)名, ngx_modules代表所有模塊,是個(gè)數(shù)組 */
- ngx_max_module = 0;
- for (i = 0; ngx_modules[i]; i++) {
- ngx_modules[i]->index = ngx_max_module++;
- }
- /*
- * 系統(tǒng)初始化,這里將發(fā)生配置文件解析,模塊上下文注冊(cè)鉤子調(diào)用,模塊初始化
- * module : 模塊
- * commands : 模塊指令集,負(fù)責(zé)解析配置文件的選項(xiàng),一個(gè)指令對(duì)應(yīng)一個(gè)配置選項(xiàng)
- * conf : 模塊配置結(jié)構(gòu)體,指令解析后的值就是存儲(chǔ)在這個(gè)里面,每個(gè)模塊都有自已的一個(gè)conf
- * ctx : 模塊上下文,有四種,core, event, http, mail,有注冊(cè)鉤子功能。比如 create conf, init conf
- */
- cycle = ngx_init_cycle(&init_cycle);
- /* 創(chuàng)建進(jìn)程id文件 */
- ngx_create_pidfile(&ccf->pid, cycle->log);
- /*
- * 進(jìn)程處理
- * 主進(jìn)程(master)產(chǎn)生多個(gè)工作進(jìn)程(worker)
- * 這里將做各模塊進(jìn)程初始化,監(jiān)聽,接受,請(qǐng)求處理,還有信號(hào)等
- */
- ngx_master_process_cycle(cycle) {
- ngx_start_worker_processes(cycle, ccf->worker_processes,
- NGX_PROCESS_RESPAWN) {
- for ( ... ) {
- ngx_spawn_process(cycle, ngx_worker_process_cycle, NULL,
- "worker process", type);
- }
- }
- }
- goto: 繼續(xù)
- /* 生產(chǎn)進(jìn)程都在這個(gè)函數(shù)里處理 */
- ngx_worker_process_cycle {
- /* 各模塊進(jìn)程注冊(cè)鉤子調(diào)用 */
- ngx_worker_process_init();
- for ( ;; ) {
- ngx_process_events_and_timers(cycle);
- }
- }
- goto: 繼續(xù)
- ngx_process_events_and_timers(cycle) {
- /*
- * 定時(shí)器,用紅黑樹實(shí)現(xiàn),這里找出某個(gè)event(事件)的超時(shí)時(shí)間
- * 每個(gè)事件在紅黑樹里的key的值為:ngx_currnet_msec + 超時(shí)時(shí)間(默認(rèn)60s)
- * timer的值為 -1 (如果沒有事件),或 ngx_current_msec - key
- */
- timer = ngx_event_find_timer();
- /* epoll 機(jī)制,這里將做 epoll_wait(..., timer); */
- ngx_process_events(cycle, timer, flags);
- /* 先處理所有可能超時(shí)的事件,如果超時(shí),將event的timedout設(shè)為1,并且馬上event->handler(ev); */
- ngx_event_expire_timers();
- /* 事件存隊(duì)列方式,開始遍歷,調(diào)用 */
- ngx_event_process_posted(cycle, &ngx_posted_events);
- }
- /*
- * 幾個(gè)重要的結(jié)構(gòu)體
- * ngx_listening_t : 監(jiān)聽套接字的結(jié)構(gòu)體,比如地址,端口等
- * ngx_connection_t : 每個(gè)socket將對(duì)應(yīng)一個(gè)connection,意為連接,里面存著 fd,read(讀事件),
- * write(寫事件) 等。
- * ngx_event_t : 事件結(jié)構(gòu)體,有個(gè)重要的函數(shù)指針handler,fd事件被驅(qū)動(dòng)時(shí),將調(diào)用這個(gè)函數(shù)。
- * 它有幾個(gè)重要成員
- * timer_set : 每個(gè)event在epoll_wait前,要先進(jìn)入定時(shí)器紅黑樹,這個(gè)標(biāo)記就是
- * 標(biāo)記是否在定時(shí)器里, 超時(shí)處理用的.
- * active : 當(dāng)ngx_add_event里(添加或更新事件) 進(jìn)入epoll時(shí),會(huì)置為1.
- * ready : 進(jìn)入事件隊(duì)列里,將置為1,只有為1,它對(duì)應(yīng)的socket fd才可以讀
- * timedout : 此事件對(duì)應(yīng)的socket fd將視為超時(shí)
- */
- /*
- * http處理
- * 當(dāng) listen fd 有連接過來(lái)時(shí),它將調(diào)用函數(shù) ngx_http_init_connection
- * 當(dāng) accept fd 有傳送東東時(shí),它將調(diào)用函數(shù) ngx_http_init_request,所以的處理都將從這函數(shù)開始
- */
- ngx_http_init_request {
- ngx_http_process_request_line {
- /* 讀請(qǐng)求頭 */
- ngx_http_read_request_header(...);
- /* 解析請(qǐng)求行 */
- ngx_http_parse_request_line(...);
- /* 處理請(qǐng)求頭部信息 */
- ngx_http_process_request_headers(...) {
- for ( ;; ) {
- /* 解析每一行 */
- ngx_http_parse_header_line(...);
- }
- /* 解析之后對(duì)所有行的處理 */
- ngx_http_process_request_header(...);
- /* 真正開始處理請(qǐng)求 */
- ngx_http_process_request(r) {
- ngx_http_handler(r) {
- /* 非常巧妙的設(shè)計(jì)處理即將開始 */
- ngx_http_core_run_phases(r);
- }
- }
- }
- }
- }
- /*
- * 精巧的設(shè)計(jì)函數(shù):責(zé)任鏈模式
- * http的每個(gè)請(qǐng)求可以分為好幾個(gè)階段
- * 規(guī)則重寫(rewrite)
- * 處理配置(不同url有不同的配置)
- * 權(quán)限訪問處理
- * 核心內(nèi)容處理(是走fastcgi,還是直接輸出或從緩存獲取等)
- * 日志處理
- *
- * 每個(gè)階段都可以由好幾個(gè)模塊處理,這些模塊組成一個(gè)鏈,
- * 這是設(shè)計(jì)模式里的一種,責(zé)任鏈模式
- */
- ngx_http_core_run_phases(r) {
- while (ph[r->phase_handler].checker) {
- rc = ph[r->phase_handler].checker(r, &ph[r->phase_handler]);
- if (rc == NGX_OK) {
- return;
- }
- }
- }
責(zé)任編輯:林師授
來(lái)源:
OSCHINA