搜尋
首頁運維NginxNginx中的upstream模組如何使用

upstream模組簡介

  • nginx模組一般被分成三大類:handler、filter和upstream。在前面的章節中,讀者已經了解了handler、filter。利用這兩類模組,可以讓nginx輕鬆完成任何單機工作。

  • 而upstream模組,將使nginx跨越單機的限制,完成網路資料的接收、處理和轉送。

  • 資料轉送功能,為nginx提供了跨越單機的橫向處理能力,使nginx擺脫只能為終端節點提供單一功能的限制,使它具備了網路應用層級的拆分、封裝和整合的功能。

  • 資料轉送是nginx有能力建構一個網路應用的關鍵元件。當然,鑑於開發成本的問題,一個網頁應用的關鍵元件一開始往往會採用高階程式語言開發。但是當系統到達一定規模,並且需要更重視效能的時候,為了達到所要求的效能目標,高階語言所發展的元件必須進行結構化修改。

此時,對於修改代價而言,nginx的upstream模組體現出了它的優勢,因為它天生就快。作為附帶,nginx的配置系統提供的層次化和鬆散耦合使得系統的擴展性也達到比較高的程度。

upstream模組介面

本質上說,upstream屬於handler,只是他不產生自己的內容,而是透過請求後端伺服器得到內容,所以才稱為upstream(上游) 。請求並且取得回應內容的整個過程已經被封裝到nginx內部,所以upstream模組只需要開發若干回呼函數,完成建構請求和解析回應等特定的工作。

upstream模組回呼函數列舉如下:

##process_headerabort_request
#函數名稱 描述
create_request 產生傳送到後端伺服器的請求緩衝(緩衝鏈),在初始化upstream 時使用
reinit_request #在某台後端伺服器出錯的情況,nginx會嘗試另一台後端伺服器。 nginx選定新的伺服器以後,會先呼叫此函數,以重新初始化upstream模組的工作狀態,然後再進行upstream連線
##處理後端伺服器傳回的資訊頭部。所謂頭部是與upstream server 通訊的協定規定的,例如HTTP協定的header部分,或是memcached 協定的回應狀態部分
####################################################################################################################################################################1請求時被呼叫。不需要在函數中實現關閉後端伺服器連接的功能,系統會自動完成關閉連接的步驟,所以一般此函數不會進行任何具體工作############finalize_request#### ##正常完成與後端伺服器的請求後呼叫函數,與abort_request 相同,一般也不會進行任何特定工作###########input_filter######處理後端伺服器傳回的回應正文。 nginx預設的input_filter會 將收到的內容封裝成為緩衝區鏈ngx_chain。此鏈由upstream的 out_bufs指標域定位,所以開發人員可以在模組以外透過該指標得到後端伺服器傳回的正文資料。 memcached模組實作了自己的 input_filter,後面會具體分析這個模組。 ############input_filter_init######初始化input filter的上下文。 nginx預設的input_filter_init 直接回傳############

memcached模組分析

  • memcache是​​高效能的分散式cache系統,得到了非常廣泛的應用。 memcache定義了一套私有通訊協議,使得無法透過HTTP請求來存取memcache。但協議本身簡單高效,而且memcache使用廣泛,所以大部分現代開發語言和平台都提供了memcache支持,方便開發者使用memcache。

  • nginx提供了ngx_http_memcached模組,提供從memcache讀取資料的功能,而不提供向memcache寫資料的功能。

upstream模組使用的就是handler模​​組的存取方式。

同時,upstream模組的指令系統的設計也是遵循handler模​​組的基本規則:設定模組才會執行該模組。

那麼,upstream模組的特別之處究竟在哪裡呢?那就是upstream模組的處理函數,upstream模組的處理函數進行的操作都包含一個固定的流程:(以memcached模組舉例,在memcached的處理函數ngx_http_memcached_handler中)

建立upstream資料結構:

ngx_http_upstream_t            *u;
if (ngx_http_upstream_create(r) != NGX_OK) {
    return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
u = r->upstream;

設定模組的tag和schema。 schema現在只會用於日誌,tag會用於buf_chain管理:

ngx_str_set(&u->schema, "memcached://");
u->output.tag = (ngx_buf_tag_t) &ngx_http_memcached_module;

設定upstream的後端伺服器清單資料結構:

mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module);
u->conf = &mlcf->upstream;

設定upstream回呼函數:

u->create_request = ngx_http_memcached_create_request;
u->reinit_request = ngx_http_memcached_reinit_request;
u->process_header = ngx_http_memcached_process_header;
u->abort_request = ngx_http_memcached_abort_request;
u->finalize_request = ngx_http_memcached_finalize_request;
   
u->input_filter_init = ngx_http_memcached_filter_init;
u->input_filter = ngx_http_memcached_filter;

建立並設定upstream環境資料結構:

ctx = ngx_palloc(r->pool, sizeof(ngx_http_memcached_ctx_t));
if (ctx == NULL) {
    return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
ctx->request = r;

ngx_http_set_ctx(r, ctx, ngx_http_memcached_module);

u->input_filter_ctx = ctx;

完成upstream初始化並進行收尾工作:

r->main->count++;
ngx_http_upstream_init(r);
return NGX_DONE;

任何upstream模組,簡單如memcached,複雜如proxy、fastcgi都是如此。
不同的upstream模組在這6步驟中的最大差異會出現在第2、3、4、5上。

其中第2、4兩步很容易理解,不同的模組設定的標誌和使用的回調函數肯定不同。第5步也不難理解。

只有第3步是有點費解的,不同的模組在取得後端伺服器清單時,策略的差異非常大,有如memcached這樣簡單明了的,也有如proxy那樣邏輯複雜的。

第6步不同模組之間通常是一致的。將count加1,然後返回NGX_DONE。
nginx遇到這種情況,雖然會認為目前請求的處理已經結束,但是不會釋放請求使用的記憶體資源,也不會關閉與客戶端的連線。
之所以需要這樣,是因為nginx建立了upstream請求和客戶端請求之間一對一的關係,在後續使用ngx_event_pipe將upstream回應傳送回客戶端時,還要使用到這些保存著客戶端訊息的資料結構。
將upstream請求和客戶端請求進行一對一綁定,這個設計有優勢也有缺陷。優點就是簡化模組開發,可以將精力集中在模組邏輯上,而缺陷同樣明顯,一對一的設計很多時候都無法滿足複雜邏輯的需要。

回呼函數:(還是以memcached模組的處理函數為例)

  • ngx_http_memcached_create_request:很簡單的依照設定的內容產生一個key,接著產生一個「get $key」的請求,放在r->upstream->request_bufs裡面。

  • ngx_http_memcached_reinit_request:無需初始化。

  • ngx_http_memcached_abort_request:無需額外操作。

  • ngx_http_memcached_finalize_request:無需額外操作。

  • ngx_http_memcached_process_header:模組的業務重點函數。 memcache協定的頭部資訊被定義為第一行文本,程式碼如下:

#define LF     (u_char) '\n'
for (p = u->buffer.pos; p < u->buffer.last; p++) {
    if (*p == LF) {
        goto found;
    }
}

如果在已讀入緩衝的資料中沒有發現LF(‘\n’)字符,函數傳回NGX_AGAIN,表示頭部未完全讀入,需要繼續讀取資料。 nginx收到新的資料後會再呼叫函數。

nginx處理後端伺服器的回應頭時只會使用一塊緩存,所有資料都在這塊快取中,所以解析頭部資訊時不需要考慮頭部資訊跨越多塊快取的情況。而如果頭部過大,不能保存在這塊快取中,nginx會回傳錯誤訊息給客戶端,並記錄error log,提示快取不夠大。

ngx_http_memcached_process_header的重要職責是將後端伺服器傳回的狀態翻譯成傳回給客戶端的狀態。例如:

u->headers_in.content_length_n = ngx_atoof(start, p - start);
···
u->headers_in.status_n = 200;
u->state->status = 200;
···
u->headers_in.status_n = 404;
u->state->status = 404;

u->state用來計算upstream相關的變數。例如u->state->status將被用來計算變數「upstream_status」的值。 u->headers_in將被當作傳回給客戶端的回應傳回狀態碼。而u->headers_in.content_length_n則是設定回傳給客戶端的回應的長度。

在這個函數中一定要在處理完頭部資訊以後需要將讀取指標pos後移,否則這段資料也會被複製到傳回給客戶端的回應的正文中,進而導致正文內容不正確。

ngx_http_memcached_process_header函數完成回應頭的正確處理,應該回傳NGX_OK。如果傳回NGX_AGAIN,表示未讀取完整數據,則需要從後端伺服器繼續讀取數據。傳回NGX_DECLINED無意義,其他任何回傳值都被視為出錯狀態,nginx將結束upstream請求並傳回錯誤訊息。

ngx_http_memcached_filter_init:修正從後端伺服器收到的內容長度。因為在處理header時沒有加上這部分長度。

ngx_http_memcached_filter:
memcached模組是少有的帶有處理正文的回調函數的模組。
因為memcached模組需要過濾正文末尾CRLF “END” CRLF,所以實現了自己的filter回呼函數。

處理正文的實際意義是將從後端伺服器收到的正文有效內容封裝成ngx_chain_t,並加在u->out_bufs末尾。

nginx不進行資料拷貝,而是建立ngx_buf_t資料結構指向這些資料記憶體區,然後由ngx_chain_t組織這些buf。這種實作避免了記憶體大量搬遷,也是nginx高效的原因之一。

以上是Nginx中的upstream模組如何使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:亿速云。如有侵權,請聯絡admin@php.cn刪除
NGINX:高性能Web服務器的簡介NGINX:高性能Web服務器的簡介Apr 29, 2025 am 12:02 AM

NGINX始於2002年,由IgorSysoev開發,旨在解決C10k問題。 1.NGINX是高性能Web服務器,基於事件驅動的異步架構,適用於高並發。 2.提供反向代理、負載均衡和緩存等高級功能,提升系統性能和可靠性。 3.優化技巧包括調整worker進程數、啟用Gzip壓縮、使用HTTP/2和安全配置。

Nginx vs. Apache:看他們的架構Nginx vs. Apache:看他們的架構Apr 28, 2025 am 12:13 AM

NGINX和Apache在架構上的主要區別在於:NGINX採用事件驅動、異步非阻塞模型,而Apache使用進程或線程模型。 1)NGINX通過事件循環和I/O多路復用機制高效處理高並發連接,適合靜態內容和反向代理。 2)Apache採用多進程或多線程模型,穩定性高但資源消耗大,適合需要豐富模塊擴展的場景。

NGINX與Apache:檢查優點和缺點NGINX與Apache:檢查優點和缺點Apr 27, 2025 am 12:05 AM

NGINX適合處理高並發和靜態內容,Apache則適用於復雜配置和動態內容。 1.NGINX高效處理並發連接,適合高流量場景,但處理動態內容需額外配置。 2.Apache提供豐富模塊和靈活配置,適合複雜需求,但高並發性能較差。

nginx和apache:了解關鍵差異nginx和apache:了解關鍵差異Apr 26, 2025 am 12:01 AM

NGINX和Apache各有優劣,選擇應基於具體需求。 1.NGINX適合高並發場景,因其異步非阻塞架構。 2.Apache適用於需要復雜配置的低並發場景,因其模塊化設計。

NGINX單元:關鍵功能NGINX單元:關鍵功能Apr 25, 2025 am 12:17 AM

NGINXUnit是一個開源應用服務器,支持多種編程語言,提供動態配置、零停機更新和內置負載均衡等功能。 1.動態配置:無需重啟即可修改配置。 2.多語言支持:兼容Python、Go、Java、PHP等。 3.零停機更新:支持不中斷服務的應用更新。 4.內置負載均衡:可將請求分發到多個應用實例。

NGINX單元與其他應用程序服務器NGINX單元與其他應用程序服務器Apr 24, 2025 am 12:14 AM

NGINXUnit優於ApacheTomcat、Gunicorn和Node.js內置HTTP服務器,適用於多語言項目和動態配置需求。 1)支持多種編程語言,2)提供動態配置重載,3)內置負載均衡功能,適合需要高擴展性和可靠性的項目。

NGINX單元:架構及其工作原理NGINX單元:架構及其工作原理Apr 23, 2025 am 12:18 AM

NGINXUnit通過其模塊化架構和動態重配置功能提高了應用的性能和可管理性。 1)模塊化設計包括主控進程、路由器和應用進程,支持高效管理和擴展。 2)動態重配置允許在運行時無縫更新配置,適用於CI/CD環境。 3)多語言支持通過動態加載語言運行時實現,提升了開發靈活性。 4)高性能通過事件驅動模型和異步I/O實現,即使在高並發下也保持高效。 5)安全性通過隔離應用進程提高,減少應用間相互影響。

使用NGINX單元:部署和管理應用程序使用NGINX單元:部署和管理應用程序Apr 22, 2025 am 12:06 AM

NGINXUnit可用於部署和管理多種語言的應用。 1)安裝NGINXUnit。 2)配置它以運行不同類型的應用,如Python和PHP。 3)利用其動態配置功能進行應用管理。通過這些步驟,你可以高效地部署和管理應用,提升項目效率。

See all articles

熱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

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

熱工具

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具