首頁 後端開發 php教程 nginx基礎概念-connection

nginx基礎概念-connection

Aug 08, 2016 am 09:27 AM
mutex nginx

在nginx中connection就是tcp連接的封裝,其中包括連接的socket,讀取事件,寫事件。利用nginx封裝的connection,我們可以很方便的使用nginx來處理與連接相關的事情,例如,建立連接,發送與接受數據等。而nginx中的http請求的處理就是建立在connection之上的,所以nginx不僅可以作為一個web伺服器,也可以作為郵件伺服器。當然,利用nginx提供的connection,我們可以與任何後端服務打交道。 結合一個tcp連結的生命週期,我們來看看nginx是如何處理一個連結的。首先,nginx在啟動時,會解析設定文件,得到需要監聽的連接埠與ip位址,然後在nginx的master進程裡面,先初始化好這個監控的socket(創建socket,設定addrreuse等選項,綁定到指定的ip位址端口,再listen),然後再fork出多個子進程出來,然後子進程會競爭accept新的連接。此時,客戶端就可以向nginx發起連線了。當客戶端與服務端透過三次握手建立好一個連線後,nginx的某一個子程序會accept成功,得到這個建立好的連線的socket,然後建立nginx對連線的封裝,也就是ngx_connection_t結構體。接著,設定讀寫事件處理函數並新增讀寫事件來與客戶端進行資料的交換。最後,nginx或客戶端來主動關掉連接,到此,一個連接就壽終正寢了。 當然,nginx也是可以作為客戶端來請求其它server的資料的(如upstream模組),此時,與其它server創建的連接,也封裝在ngx_connection_t中。作為客戶端,nginx先取得一個ngx_connection_t結構體,然後建立socket,並設定socket的屬性( 例如非阻塞)。然後再透過新增讀寫事件,呼叫connect/read/write來呼叫連接,最後關掉連接,並釋放ngx_connection_t。 在nginx中,每個進程會有一個連線數的最大上限,這個上限與系統對fd的限制不一樣。在作業系統中,透過ulimit -n,我們可以得到一個行程所能夠開啟的fd的最大數,也就是nofile,因為每個socket連線會佔用掉一個fd,所以這也會限制我們行程的最大連線數,當然也會直接影響我們程式所能支援的最大並發數,當fd用完後,再創建socket時,就會失敗。 nginx透過設定worker_connectons來設定每個進程支援的最大連線數。如果該值大於nofile,那麼實際的最大連線數是nofile,nginx會有警告。 nginx實現時,是透過一個連線池來管理的,每個worker進程都有一個獨立的連線池,連線池的大小是worker_connections。這裡的連接池裡面保存的其實不是真實的連接,它只是一個worker_connections大小的一個ngx_connection_t結構的陣列。並且,nginx會透過一個鍊錶free_connections來保存所有的空閒ngx_connection_t,每次取得一個連接時,就從空閒連接鍊錶中取得一個,用完後,再放回空閒連接鍊錶裡面。 在這裡,很多人會誤解worker_connections這個參數的意思,認為這個值就是nginx所能建立連結的最大值。其實不然,這個值是表示每個worker行程所能建立連線的最大值,所以,一個nginx能建立的最大連線數,應該是worker_connections * worker_processes。當然,這裡說的是最大連線數,對於HTTP請求本地資源來說,能夠支援的最大並發數量是worker_connections * worker_processes,而如果是HTTP作為反向代理來說,最大並發數量應該是worker_connections * worker_processes/2。因為作為反向代理伺服器,每個並發會建立與客戶端的連接和與後端服務的連接,會佔用兩個連接。 那麼,我們前面有說過一個客戶端連接過來後,多個空閒的進程,會競爭這個連接,很容易看到,這種競爭會導致不公平,如果某個進程得到accept的機會比較多,它的空閒連接很快就用完了,如果不提前做一些控制,當accept到一個新的tcp連接後,因為無法得到空閒連接,而且無法將此連接轉交給其它進程,最終會導致此tcp連接得不到處理,就中止掉了。很顯然,這是不公平的,有的進程有剩餘連接,卻沒有處理機會,有的進程因為沒有空餘連接,卻人為地丟棄連接。那麼,如何解決這個問題呢?首先,nginx的處理得先打開accept_mutex選項,此時,只有獲得了accept_mutex的進程才會去添加accept事件,也就是說,nginx會控制進程是否添加accept事件。 nginx使用一個叫ngx_accept_disabled的變數來控制是否去競爭accept_mutex鎖。在第一段程式碼中,計算ngx_accept_disabled的值,這個值是nginx單一進程的所有連接總數的八分之一,減去剩下的空閒連接數量,得到的這個ngx_accept_disabled有一個規律,當剩餘連接數小於總連接數的八分之一時,其值才大於0,而且剩餘的連接數越小,這個值越大。再看第二段程式碼,當ngx_accept_disabled大於0時,不會去嘗試取得accept_mutex鎖,並且將ngx_accept_disabled減1,於是,每次執行到此處時,都會去減1,直到小於0。不去取得accept_mutex鎖,就是等於讓出獲取連接的機會,很顯然可以看出,當空餘連接越少時,ngx_accept_disable越大,於是讓出的機會就越多,這樣其它進程獲取鎖的機會也就越大。不去accept,自己的連接就控制下來了,其它進程的連接池就會被利用,這樣,nginx就控制了多進程間連接的平衡了。 ngx_accept_disabled = ngx_cycle->connection_n / 8 - ngx_cycle->free_connection_n; if (ngx_accept_disabled > 0) { ngx_accept_disabled--; } else { if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) { return; } if (ngx_accept_mutex_held) { flags |= NGX_POST_EVENTS; } else { if (timer == NGX_TIMER_INFINITE || timer > ngx_accept_mutex_delay) { timer = ngx_accept_mutex_delay; } } }

以上就介紹了nginx基礎概念-connection,包括了方面的內容,希望對PHP教程有興趣的朋友有幫助。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

docker容器名稱怎麼查 docker容器名稱怎麼查 Apr 15, 2025 pm 12:21 PM

可以通過以下步驟查詢 Docker 容器名稱:列出所有容器(docker ps)。篩選容器列表(使用 grep 命令)。獲取容器名稱(位於 "NAMES" 列中)。

nginx在windows中怎麼配置 nginx在windows中怎麼配置 Apr 14, 2025 pm 12:57 PM

如何在 Windows 中配置 Nginx?安裝 Nginx 並創建虛擬主機配置。修改主配置文件並包含虛擬主機配置。啟動或重新加載 Nginx。測試配置並查看網站。選擇性啟用 SSL 並配置 SSL 證書。選擇性設置防火牆允許 80 和 443 端口流量。

怎麼查看nginx是否啟動 怎麼查看nginx是否啟動 Apr 14, 2025 pm 01:03 PM

確認 Nginx 是否啟動的方法:1. 使用命令行:systemctl status nginx(Linux/Unix)、netstat -ano | findstr 80(Windows);2. 檢查端口 80 是否開放;3. 查看系統日誌中 Nginx 啟動消息;4. 使用第三方工具,如 Nagios、Zabbix、Icinga。

docker怎麼啟動容器 docker怎麼啟動容器 Apr 15, 2025 pm 12:27 PM

Docker 容器啟動步驟:拉取容器鏡像:運行 "docker pull [鏡像名稱]"。創建容器:使用 "docker create [選項] [鏡像名稱] [命令和參數]"。啟動容器:執行 "docker start [容器名稱或 ID]"。檢查容器狀態:通過 "docker ps" 驗證容器是否正在運行。

nginx怎麼配置雲服務器域名 nginx怎麼配置雲服務器域名 Apr 14, 2025 pm 12:18 PM

在雲服務器上配置 Nginx 域名的方法:創建 A 記錄,指向雲服務器的公共 IP 地址。在 Nginx 配置文件中添加虛擬主機塊,指定偵聽端口、域名和網站根目錄。重啟 Nginx 以應用更改。訪問域名測試配置。其他注意事項:安裝 SSL 證書啟用 HTTPS、確保防火牆允許 80 端口流量、等待 DNS 解析生效。

docker怎麼創建容器 docker怎麼創建容器 Apr 15, 2025 pm 12:18 PM

在 Docker 中創建容器: 1. 拉取鏡像: docker pull [鏡像名] 2. 創建容器: docker run [選項] [鏡像名] [命令] 3. 啟動容器: docker start [容器名]

nginx怎麼查版本 nginx怎麼查版本 Apr 14, 2025 am 11:57 AM

可以查詢 Nginx 版本的方法有:使用 nginx -v 命令;查看 nginx.conf 文件中的 version 指令;打開 Nginx 錯誤頁,查看頁面的標題。

怎麼啟動nginx服務器 怎麼啟動nginx服務器 Apr 14, 2025 pm 12:27 PM

啟動 Nginx 服務器需要按照不同操作系統採取不同的步驟:Linux/Unix 系統:安裝 Nginx 軟件包(例如使用 apt-get 或 yum)。使用 systemctl 啟動 Nginx 服務(例如 sudo systemctl start nginx)。 Windows 系統:下載並安裝 Windows 二進製文件。使用 nginx.exe 可執行文件啟動 Nginx(例如 nginx.exe -c conf\nginx.conf)。無論使用哪種操作系統,您都可以通過訪問服務器 IP

See all articles