nginx的main啓動:初始化master進程信息
- 解析命令:ngx_get_options()
- 解析啓動傳入的參數argv:
- 若是有p,則初始化前綴路徑全局變量 ngx_prefix
- 若是有c,則初始化配置文件全局變量 ngx_conf_file
- 若是有g,則初始化全局指令全局變量 ngx_conf_params
- 若是有s,則初始化信號全局變量 ngx_signal
- ngx_process = NGX_PROCESS_SIGNALLER
- ngx_signal=stop或quit或reopen或reload
- 初始化時間:ngx_time_init()
- 初始化ngx_cached_err_log_time的長度
- 初始化ngx_cached_http_time
- 初始化ngx_cached_http_log_time
- 初始化ngx_cached_http_log_iso8601
- 初始化ngx_cached_syslog_time
- 初始化ngx_cached_time的地址
- 調用全局變量 ngx_time_update=&cached_time[slot],初始化時間:
- 獲取ngx_time_lock鎖
- 獲取linux的時間timeval,解析成ngx_current_msec
- 初始化cached_time的值
- 釋放ngx_time_lock鎖
- 若是有NGX_PCRE,則初始化prel的正則功能能:ngx_regex_init()
- 初始化日誌:ngx_log_init()
- 打開log日誌,若是日誌不存在。則將日誌指向stderr
- 若是有NGX_OPENSSL,初始化SSL:ngx_ssl_init()
- 初始化內存池1024B:ngx_create_pool()
- 保存命令:ngx_save_argv()
- 保存命令行的數據到ngx_cycle_s中:ngx_process_options()
- 將前綴:ngx_prefix添加到ngx_cycle_s.conf_prefix
- 將命令行配置文件:ngx_conf_file添加到ngx_cycle_s.conf_file
- 將全局指令ngx_conf_params添加到ngx_cycle_s.conf_param
- 設置進程環境:ngx_os_init()
- 如內存頁面大小 ngx_pagesize , ngx_cacheline_size , 最大鏈接數 ngx_max_sockets 等
- 初始化CRC表:ngx_crc32_table_init()
- 初始化slab數據:ngx_slab_sizes_init()
- 初始化繼承的套接字鏈接池:ngx_add_inherited_sockets()
- 解析環境變量 NGINX_VAR = "NGINX" 中的 sockets,並保存至 ngx_cycle.listening 數組;
- 設置繼承套接字 ngx_inherited = 1;
- 調用 ngx_set_inherited_sockets() 逐一對 ngx_cycle.listening 數組中的 sockets 進行設置;
- 設置監聽文件符的sockaddr空間
- 設置監聽文件符的socklen空間
- 經過getsockname()獲取監聽套接字的地址
- 經過getsockname()獲取監聽套接字的地址
- ngx_preinit_modules()
- 初始化每一個 module 的 index,並計算 ngx_max_module
- 初始化master的ngx_cycle_s :ngx_init_cycle()
- 更新 timezone 和 time
- 建立內存池
- 給 cycle 指針分配內存
- 保存安裝路徑,配置文件,啓動參數等
- 初始化文件句柄
- 初始化共享內存
- 初始化鏈接隊列
- 保存 hostname
- 調用各 NGX_CORE_MODULE 的 create_conf 方法,建立模塊的上下文配置內存空間
- 解析配置文件,替換模塊的上下文配置
- 調用各NGX_CORE_MODULE的init_conf方法,檢測模塊的上下文配置是否設置徹底,沒有設置的參數設置爲默認值
- 打開新的文件句柄
- 建立共享內存
- 處理監聽socket
- 建立socket並監聽:ngx_open_listening_sockets(cycle)
- for i<5
- for cycle->listening.elts
- 非繼承
- 建立socket
- 設置socket套接字爲可重複使用
- bind套接字到地址上
- listen監聽套接字,將其放到backlog上
- end for cycle->listening.elts
- end for
- 關閉不須要的socket
- 關閉不須要的共享內存
- 關閉不須要的文件
- ngx_init_modules()-->模塊初始化函數init_module()
- 如有信號,則進入 ngx_signal_process() 處理
- 調用 ngx_init_signals() 初始化信號,主要完成信號處理程序的註冊
- 進入主循環:ngx_single_process_cycle() 和 ngx_master_process_cycle()
主循環初始化後的運行:ngx_master_process_cycle
- 阻塞nginx的消息
- 設置進程名稱
- 啓動工做進程:ngx_start_worker_processes
- 循環
- 調用:ngx_spawn_process() 建立 "worker process":
- 經過socketpair() 獲取UNIX域套接字傳輸管道,即管道
- 設置管道爲非阻塞模式:ngx_nonblocking()
- 設置管道爲異步模式:ioctl()
- 設置異步 I/O 的全部者:fcntl()
- fork()啓動子進程,並執行進程的初始化回調函數:proc(cycle, data)
- 即 ngx_worker_process_cycle
- 設置 ngx_processes[s] 相關屬性
- 通知以前的work進程新work進程建立完畢 ngx_pass_open_channel(cycle, &ch);
- 經過管道發送消息:ngx_write_channel()-->sendmsg()
- 結束循環
- 啓動cache管理進程:ngx_start_cache_manager_processes
- 調用:ngx_spawn_process() 建立 "cache manager process":
- 經過socketpair() 獲取UNIX域套接字,即管道
- 設置管道爲非阻塞模式:ngx_nonblocking()
- 設置管道爲異步模式:ioctl()
- 設置異步 I/O 的全部者:fcntl()
- fork()啓動子進程,並執行進程的初始化回調函數:proc(cycle, data)
- 即 ngx_cache_manager_process_cycle
- 設置 ngx_processes[s] 相關屬性
- work建立成功,通知以前的全部work進程新進程建立完畢 ngx_pass_open_channel(cycle, &ch);
- 經過管道發送消息:ngx_write_channel()-->sendmsg()
- 循環等待信號:
- setitimer()阻塞一段時間等待進程啓動
- sigsuspend()阻塞等待新號
- ngx_time_update()刷新新時間
- 若是有 worker 進程由於 SIGCHLD 信號退出了,則重啓 worker 進程
- master 進程退出。若是全部 worker 進程都退出了,而且收到 SIGTERM 信號或 SIGINT 信號或 SIGQUIT 信號等,master 進程開始處理退出
- 處理ngx_terminate、ngx_quit、ngx_reconfigure、ngx_restart、ngx_reopen、ngx_change_binary、ngx_noaccept信號
工做進程的運行流程(初始化回調函數):ngx_worker_process_cycle
work進程的cycle不須要在初始化ngx_listen_t信息:socket、bind、listen。只須要綁定一個讀的處理函數linux
- ngx_worker_process_init()初始化進程信息
- 初始化環境變量
- 設置進程優先級
- 設置文件句柄數量限制
- 設置 core_file 文件
- 用戶組設置
- cpu 親和度設置
- 設定工做目錄
- 設置隨機種子數
- 初始化監聽狀態
- 調用各模塊的init_process方法進行初始化(這裏會初始化 epoll)
- 關閉其它進程的fd[1],保留別人的fd[0]用於互相通訊。關閉本身的fd[0],保留本身的fd[1]接收master進程的消息。
- 監聽管道讀事件:ngx_add_channel_event(cycle, ngx_channel, NGX_READ_EVENT, ngx_channel_handler)
- 獲取鏈接文件描述符:ngx_get_connection()
- 初始化讀寫內存
- 添加管道讀事件回調函數:ngx_channel_handler 到讀事件NGX_READ_EVENT
- 經過 recvmsg() 阻塞獲取master進程發送的消息
- 這裏用來接受master進程的發送啓動成功的消息
- 循環執行事件和監聽信號
- ngx_process_events_and_timers()執行事件
- ngx_trylock_accept_mutex 當獲取到標誌位後才進行 accept 事件註冊。
- 執行進程事件ngx_process_events(cycle, timer, flags)。將epoll準備好的讀寫放到nginx的事件列表中
- 釋放 accept_mutex 鎖。
- 處理定時器事件
- ngx_event_process_posted(cycle, &ngx_posted_accept_events) 處理 ngx_posted_events和ngx_posted_accept_events 隊列的事件
- 監聽ngx_terminate、ngx_quit、ngx_reopen信號
進程事件處理函數:執行回調函數ngx_process_events
暫無
acceptd處理函數:ngx_event_process_posted
void
ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted)
{
ngx_queue_t *q;
ngx_event_t *ev;
while (!ngx_queue_empty(posted)) {
q = ngx_queue_head(posted);
ev = ngx_queue_data(q, ngx_event_t, queue);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"posted event %p", ev);
ngx_delete_posted_event(ev);//刪除事件
ev->handler(ev);//事件處理
}
}
- 全局事件隊列:
- ngx_posted_accept_events: 接受事件隊列
- ngx_posted_events: 讀、寫事件丟列
- NGX_READ_EVENT:讀類型nginx事件
- NGX_POST_EVENTS:寫類型nginx事件