成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

【Nginx源碼分析】Nginx的listen處理流程分析

yuanzhanghu / 1262人閱讀

摘要:四監(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ǔ)

nginx源碼采用1.15.5

后續(xù)部分僅討論http中的listen配置解析以及優(yōu)化流程

1.1 概述

假設(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)系


端口是指一個(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

1.2 存在的問(wèn)題

是否需要在讀取完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?

比較合適的方案是通過(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)。

1.3 nginx listen解析的流程

總體而言分為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

2.1 源碼

listen的處理流程:

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ù)定義)。

三. 創(chuàng)建監(jiān)聽(tīng)套接字

nginx最終創(chuàng)建的監(jiān)聽(tīng)套接字及其相關(guān)的結(jié)構(gòu)圖如下,


每個(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

3.1 源碼

讀取完http塊后, 需要?jiǎng)?chuàng)建監(jiān)聽(tīng)套接字綁定監(jiān)聽(tīng)地址, 處理函數(shù)ngx_http_optimize_servers, 該函數(shù)的處理流程:

遍歷所有監(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)地址。

四. 監(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)求。

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)

五. 總結(jié)

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

相關(guān)文章

  • [轉(zhuǎn)載] PHP升級(jí)導(dǎo)致系統(tǒng)負(fù)載過(guò)高問(wèn)題分析

    摘要:分析的結(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%以...

    awokezhou 評(píng)論0 收藏0
  • Nginx源碼分析Nginx中http2淺析

    摘要:主要涉及到的協(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....

    孫吉亮 評(píng)論0 收藏0
  • docker進(jìn)階,nginx部署幾個(gè)重要點(diǎn)詳解以及開(kāi)發(fā)流程---持續(xù)更新

    摘要:無(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...

    KunMinX 評(píng)論0 收藏0
  • docker進(jìn)階,nginx部署幾個(gè)重要點(diǎn)詳解以及開(kāi)發(fā)流程---持續(xù)更新

    摘要:無(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...

    ytwman 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<