摘要:四監(jiān)聽(tīng)套接字的使用假設(shè)此處我們使用作為事件處理模塊在增加事件時(shí)用戶(hù)可以使用中的字段當(dāng)事件發(fā)生時(shí)該字段也會(huì)帶回。在創(chuàng)建監(jiān)聽(tīng)套接字時(shí)將結(jié)構(gòu)分為級(jí)監(jiān)聽(tīng)套接字地址各級(jí)都是一對(duì)多的關(guān)系。
施洪寶
一. 基礎(chǔ)1.1 概述nginx源碼采用1.15.5
后續(xù)部分僅討論http中的listen配置解析以及優(yōu)化流程
假設(shè)nginx http模塊的配置如下
http{ server { listen 127.0.0.1:8000; server_name www.baidu.com; root html; location /{ index index.html; } } server { listen 10.0.1.1:8000; server_name www.news.baidu.com; root html; location /{ index index.html; } } server { listen 8000; #相當(dāng)于0.0.0.0:8000 server_name www.tieba.baidu.com; root html; location /{ index index.html; } } server { listen 127.0.0.1:8000; server_name www.zhidao.baidu.com; location / { root html; index index.html; } } }
端口, 地址, server的關(guān)系
1.2 存在的問(wèn)題端口是指一個(gè)端口號(hào), 例如上面的8000端口
地址是ip+port, 例如127.0.0.1:8000, 10.0.1.1:8000, 0.0.0.0:8000, listen后配置的是一個(gè)地址。
每個(gè)地址可以放到多個(gè)server中, 例如上面的127.0.0.1:8000
總而言之, 一個(gè)端口可以有多個(gè)地址, 每個(gè)地址可以有多個(gè)server
是否需要在讀取完http塊中所有的server才能建立監(jiān)聽(tīng)套接字, 綁定監(jiān)聽(tīng)地址?
是的, 因?yàn)樵试S配置通配地址, 故而必須將http塊中的server全部讀取完后, 才能知道如何建立監(jiān)聽(tīng)套接字。
一個(gè)端口可以對(duì)應(yīng)多個(gè)地址, 如何建立監(jiān)聽(tīng)套接字, 如何綁定地址?
通常情況下, 每個(gè)地址只能綁定一次(只考慮tcp協(xié)議), 這種情況下, 我們只能選擇部分地址創(chuàng)建監(jiān)聽(tīng)套接字, 綁定監(jiān)聽(tīng)地址。
當(dāng)配置中存在通配地址(0.0.0.0:port)時(shí), 只需要?jiǎng)?chuàng)建一個(gè)監(jiān)聽(tīng)套接字, 綁定這個(gè)通配地址即可, 但需要能夠依據(jù)該監(jiān)聽(tīng)套接字找到該端口配置的其他地址, 這樣當(dāng)客戶(hù)端發(fā)送請(qǐng)求時(shí), 可以根據(jù)客戶(hù)端請(qǐng)求的地址, 找到對(duì)應(yīng)地址下的相關(guān)配置。
當(dāng)配置中不存在通配地址時(shí), 需要對(duì)每個(gè)地址都創(chuàng)建一個(gè)監(jiān)聽(tīng)套接字, 綁定監(jiān)聽(tīng)地址。
一個(gè)地址多個(gè)server的情況下, 如何快速找到客戶(hù)端請(qǐng)求的server?
1.3 nginx listen解析的流程比較合適的方案是通過(guò)hash表。
為了快速找到客戶(hù)端請(qǐng)求的server, nginx以server_name為key, 每個(gè)server塊的配置(可以理解為一個(gè)指針, 該指針指向整個(gè)server塊的配置)為value, 放入到哈希表。
由于server_name中可以出現(xiàn)正則匹配等情況, nginx將server_name具體分為4類(lèi)進(jìn)行分別處理(www.baidu.com, *baidu.com, www.baidu*, ~*baidu)。
總體而言分為2步,
將所有http模塊內(nèi)的配置解析完成, 將listen的相關(guān)配置暫存(主要存儲(chǔ)監(jiān)聽(tīng)端口以及監(jiān)聽(tīng)地址)。
根據(jù)上一步暫存的監(jiān)聽(tīng)端口以及監(jiān)聽(tīng)地址, 創(chuàng)建監(jiān)聽(tīng)套接字, 綁定監(jiān)聽(tīng)地址
二. 配置解析nginx http塊解析完成后, 會(huì)存儲(chǔ)配置文件中配置的監(jiān)聽(tīng)端口以及監(jiān)聽(tīng)地址, 其核心結(jié)構(gòu)圖如下,
總體而言, 結(jié)構(gòu)可以分為3級(jí), 端口->地址->server
listen的處理流程:
三. 創(chuàng)建監(jiān)聽(tīng)套接字ngx_http_core_listen: 讀取配置文件配置
ngx_http_add_listen: 查看之前是否出現(xiàn)過(guò)當(dāng)前監(jiān)聽(tīng)的端口, 沒(méi)有則新建, 否則追加
ngx_http_add_address: 查看之前該端口下是否監(jiān)聽(tīng)過(guò)該地址, 沒(méi)有則新建, 否則追加。
ngx_http_add_server: 查看server之前是否出現(xiàn)過(guò), 沒(méi)有則新建, 否則報(bào)錯(cuò)(重復(fù)定義)。
nginx最終創(chuàng)建的監(jiān)聽(tīng)套接字及其相關(guān)的結(jié)構(gòu)圖如下,
3.1 源碼每個(gè)ngx_listening_t結(jié)構(gòu)對(duì)應(yīng)一個(gè)監(jiān)聽(tīng)套接字, 綁定一個(gè)監(jiān)聽(tīng)地址
每個(gè)ngx_listening_t結(jié)構(gòu)后面需要存儲(chǔ)地址信息, 地址可能不止一個(gè), 因?yàn)檫@個(gè)監(jiān)聽(tīng)套接字可能綁定的是通配地址, 這個(gè)端口下的其他地址都會(huì)放在這個(gè)監(jiān)聽(tīng)套接字下。例如, 1.1節(jié)的配置中, 只會(huì)創(chuàng)建一個(gè)ngx_listening_t結(jié)構(gòu), 其他地址的配置都會(huì)放到這個(gè)通配地址下。
每個(gè)監(jiān)聽(tīng)地址可能對(duì)應(yīng)多個(gè)域名(配置文件中的server_name), 需要將這些域名放到哈希表中, 以供后續(xù)使用
總體而言, 結(jié)構(gòu)分為3級(jí), 監(jiān)聽(tīng)套接字->監(jiān)聽(tīng)地址->server
讀取完http塊后, 需要?jiǎng)?chuàng)建監(jiān)聽(tīng)套接字綁定監(jiān)聽(tīng)地址, 處理函數(shù)ngx_http_optimize_servers, 該函數(shù)的處理流程:
四. 監(jiān)聽(tīng)套接字的使用遍歷所有監(jiān)聽(tīng)端口, 針對(duì)每個(gè)監(jiān)聽(tīng)端口, 執(zhí)行以下3步
對(duì)該端口下所有監(jiān)聽(tīng)地址排序(listen后配置bind的放在前面, 通配地址放在后面)
遍歷該端口下的所有地址, 將每個(gè)地址配置的所有server, 放到該地址的哈希表中。
為該端口建立監(jiān)聽(tīng)套接字, 綁定監(jiān)聽(tīng)地址。
假設(shè)此處我們使用epoll作為事件處理模塊
epoll在增加事件時(shí), 用戶(hù)可以使用epoll_event中的data字段, 當(dāng)事件發(fā)生時(shí), 該字段也會(huì)帶回。
nginx中的epoll_event指向的是ngx_connection_t結(jié)構(gòu), 事件發(fā)生時(shí), 調(diào)用ngx_connection_t結(jié)構(gòu)中的讀寫(xiě)事件, 負(fù)責(zé)具體處理事件, 參見(jiàn)下圖。
//c is ngx_connection_t rev = c->read; rev->hadler(rev); wev = c->write; wev->handler(wev);
每個(gè)監(jiān)聽(tīng)套接字對(duì)應(yīng)一個(gè)ngx_connection_t, 該結(jié)構(gòu)的讀事件回調(diào)函數(shù)為ngx_event_accept, 當(dāng)用戶(hù)發(fā)起tcp握手時(shí), 通過(guò)ngx_event_accept接受客戶(hù)端的連接請(qǐng)求。
五. 總結(jié)ngx_event_accept會(huì)接受客戶(hù)端請(qǐng)求, 初始化一個(gè)新的ngx_connection_t結(jié)構(gòu), 并將其加入到epoll中進(jìn)行監(jiān)聽(tīng), 最后會(huì)調(diào)用ngx_connection_t對(duì)應(yīng)的ngx_listening_t的處理函數(shù)(http塊對(duì)應(yīng)ngx_http_init_connection, mail塊ngx_mail_init_connection, stream塊對(duì)應(yīng)ngx_stream_init_connection)
nginx在讀取listen相關(guān)的配置時(shí), 將結(jié)構(gòu)分為3級(jí), 端口->地址->server, 各級(jí)都是一對(duì)多的關(guān)系。
nginx在創(chuàng)建監(jiān)聽(tīng)套接字時(shí), 將結(jié)構(gòu)分為3級(jí), 監(jiān)聽(tīng)套接字->地址->server, 各級(jí)都是一對(duì)多的關(guān)系。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/40187.html
摘要:分析的結(jié)果,發(fā)現(xiàn)內(nèi)存,基本沒(méi)有什么大的變化,網(wǎng)卡流量明顯降低,上下文切換明顯升高。網(wǎng)卡流量降低可以理解,因?yàn)楫?dāng)前系統(tǒng)已不能正常返回響應(yīng),但上下文切換升高卻不知道什么原因。 原文:http://chuansongme.com/n/797172 背景 據(jù)XX部門(mén)兄弟反應(yīng), 其在將PHP從5.3.8 升級(jí)到5.5.13 時(shí), 開(kāi)始運(yùn)行正常, 運(yùn)行一段時(shí)間后, 系統(tǒng)負(fù)載變高,達(dá)到200%以...
摘要:主要涉及到的協(xié)議以及的處理流程。并且中必須建立在協(xié)議之上。所以對(duì)協(xié)議的服務(wù)發(fā)起請(qǐng)求時(shí),一般瀏覽器會(huì)建立條連接,并行的去請(qǐng)求不同的資源。表明該字段是否使用了編碼。 運(yùn)營(yíng)研發(fā) 張仕華 本文通過(guò)一個(gè)小例子串一遍nginx處理http2的流程。主要涉及到http2的協(xié)議以及nginx的處理流程。 http2簡(jiǎn)介 http2比較http1.1主要有如下五個(gè)方面的不同: 二進(jìn)制協(xié)議 http1....
摘要:無(wú)論這個(gè)連接是外部主動(dòng)建立的,還是內(nèi)部建立的。協(xié)議有表示層數(shù)據(jù)的表示安全壓縮。在整個(gè)發(fā)展過(guò)程中的所有思想和著重點(diǎn)都以一種稱(chēng)為的文檔格式存在。 部署基礎(chǔ)知識(shí)url:協(xié)議://網(wǎng)站地址:端口(/)路徑地址?參數(shù)eg: http://www.baidu.com:80/abc/dd/ www.baidu.com找服務(wù)器 80端口:找服務(wù)器上提供服務(wù)的應(yīng)用 nginx uri:/ab...
摘要:無(wú)論這個(gè)連接是外部主動(dòng)建立的,還是內(nèi)部建立的。協(xié)議有表示層數(shù)據(jù)的表示安全壓縮。在整個(gè)發(fā)展過(guò)程中的所有思想和著重點(diǎn)都以一種稱(chēng)為的文檔格式存在。 部署基礎(chǔ)知識(shí)url:協(xié)議://網(wǎng)站地址:端口(/)路徑地址?參數(shù)eg: http://www.baidu.com:80/abc/dd/ www.baidu.com找服務(wù)器 80端口:找服務(wù)器上提供服務(wù)的應(yīng)用 nginx uri:/ab...
閱讀 781·2023-04-25 16:55
閱讀 2821·2021-10-11 10:59
閱讀 2086·2021-09-09 11:38
閱讀 1800·2021-09-03 10:40
閱讀 1495·2019-08-30 15:52
閱讀 1134·2019-08-30 15:52
閱讀 965·2019-08-29 15:33
閱讀 3505·2019-08-29 11:26