帶參數的請求怎麼配置nginx
1. Nginx Http 模塊中 Upstream 的 keepalive 參數配置注意事項
在高並發環境下 keepalive 參數配置不當容易產生大量 TIME_WAIT,導致埠耗盡,服務異常。
keepalive 值應該大於等於 upstream 中 server 的數量。(建議是 server 數的 2 倍)
keepalive 用於設置保留在每個 nginx worker 緩存中『已經與上游伺服器建立的空閑連接』的最大連接數,如果超過這個值,最近最少使用的連接將被關閉。
Nginx 官方建議這個值應該盡可能小,以便讓上游伺服器也能處理新進入的連接。但是『盡可能小』有些太模糊,如果配置不當會降低性能以及產生其他問題。
在大量短鏈接(或者大量分散用戶)的請求場景下,同時 upstream 為輪詢模式時,因為 keepalive 值小於 upstream server 數,upstream 新的空閑連接會從緩存中擠出老的空閑鏈接,導致 keepalive 在某種意義上失效。
根據下面配置,以單個 nginx worker 處理請求為例,這里做個更詳細的解釋:
第一個請求進來,nginx 與 10.0.0.1 建立連接,請求處理完成後,nginx 與 10.0.0.1 的空閑連接被放入空閑連接池;
第二個請求進來,nginx 與 10.0.0.2 建立連接,請求處理完成後,nginx 與 10.0.0.2 的空閑連接被放入空閑連接池;
第三個請求進來,nginx 與 10.0.0.3 建立連接,請求處理完成後,因為最大空閑連接數為 2,連接數已滿,所以 nginx 與 10.0.0.1 的空閑連接被 close,nginx 與 10.0.0.3 的空閑連接被放入空閑連接池;
第四個請求進來,nginx 再次與 10.0.0.1 建立連接,請求處理完成後,因為最大空閑連接數為 2,連接數已滿,所以 nginx 與 10.0.0.2 的空閑連接被 close,nginx 與 10.0.0.1 的空閑連接被放入空閑連接池
。。。以此類推
這種效果就像沒有配置 keepalive
挖個坑:以上內容根據實踐經驗以及推測而得出,待我用源碼來證明 :)
nginx 官方文檔: https://nginx.org/en/docs/http/ngx_http_upstream_mole.html#keepalive
2. Nginx轉發請求過程解析
How nginx processes a request
這種配置情況下,第一個server就是默認配置。請求通過Header中的"Host"來匹配到對應的服務,如果沒有匹配到任何server_name,則路由到默認server(第一個server)處理。
通過給 listen 增加 default_server 參數明確指定哪個server是默認server( default_server 參數從0.8.21版本開始有效)。 注意: default_server 是用作用於埠的,而不是 server_name 的
可以定義一個 server_name 屬性為空的server來處理沒有Host的請求(從0.8.48版本開始, server_name 默認是"",之前的版本默認是hostname)。
這個配置標識請求Header中Host為空時,會返回「444」響應碼,然後關閉鏈接。
請求Header中的Host匹配到 server_name 後,會轉發到IP+埠上,如果為匹配到 server_name ,如前面所述,會轉發到第一個server來處理請求,當然也可以通過 default_server 屬性來指定埠的默認server。
如上配置,處理請求流程如下:
請求進來時,nginx會按照如下步驟來匹配請求(匹配請求只用URI不帶參數的部分)
spring web service系列1
spring web service系列2
spring web service系列3
maven配置文件settings.xml詳解
Nginx中的負載均衡演算法
Nginx upstream指令配置說明
Nginx中虛擬伺服器server指令配置說明
Nginx中proxy_pass/proxy_redirect/proxy_set_header配置說明
Nginx中ngx_http_core_mole相關指令配置說明
Java自帶JVM監控工具jstat使用詳細說明
Java自帶JVM監控工具jps使用詳細說明
Java自帶故障分析工具jmap工具使用說明
Java自帶故障分析工具jhat工具使用說明
3. Nginx運行原理和配置詳解(個人總結筆記)
話不多說,擼起鍵盤就是干!正所謂知其然知其所以然,個人總結了下Nginx運行原理和配置詳解,便於理解和後續復盤。
先來看這一張圖。
nginx啟動後會有 一個master進程和多個worker進程 。master進程用來管理worker進程, 一個worker進程處理一個請求 ,一個請求,只可能在一個worker進程中處理,一個worker進程,不可能處理其它進程的請求。 worker進程的個數是可以設置的,一般我們會設置與機器cpu核數一致 ,這裡面的原因與nginx的進程模型以及事件處理模型是分不開的 ,過多的worker數,只會導致進程來競爭cpu資源,從而帶來不必要的上下文切換。
php WEB伺服器目前最佳方式之一就是: Nginx + FastCGI(解決CGI並發重復fork問題) + PHP-FPM(管理PHP-CGI進程) 。nginx是怎麼做到把請求拋給PHP解釋來處理的呢?這個過程又是怎麼實現的呢?稍後我們來看一下參數配置。
代理,反向代理,負載均衡是Nginx常用功能。
Http代理,反向代理:作為web伺服器最常用的功能之一,尤其是反向代理。如果你和小馬之前一樣還是分不清代理和反向代理的區別,下面這個圖對理解會有所幫助。
它們的區別就是,前者知道我要找的人並知道地址在哪,代理伺服器按這個地址代為請求一下然後把他說的話返回給我。後者就是,我知道我要找誰問話但不知道地址在哪,我也不想管,代理服務你自己去找,只要幫我返回他要說的話就可以了。
負載均衡:其實也是 反向代理 的一種。負載均衡,熱備等等其實都屬於高可用范疇,Nginx提供的負載均衡策略有2種:內置策略和擴展策略。內置策略為 輪詢,加權輪詢,Ip hash 等等。擴展策略,就天馬行空,只有你想不到的沒有他做不到的啦,你可以參照所有的負載均衡演算法,給他做下實現。思考一個問題,IP hash真的能解決session共享的問題么?
我們來簡單看下兩個 配置示例 。
這個配置將請求轉發轉向mysvr 定義的伺服器列表。 注意proxy_pass配置。其實這塊也是負載均衡的配置 。如下:
在訪問網站時,由於配置了proxy_pass地址,所有請求都會先通過nginx反向代理伺服器,在伺服器將請求轉發給目的主機時,讀取upstream為 tomcatsever1的地址,讀取分發策略,配置tomcat1權重為3,所以nginx會將大部分請求發送給49伺服器上的tomcat1,也就是8080埠;較少部分給tomcat2來實現有條件的負載均衡,當然這個條件就是伺服器1、2的硬體指數處理請求能力。
負載均衡配置 還有其他的相關參數,這是只是打個樣,不贅述。
可以認為fastcgi_pass這個配置非常關鍵,將Nginx + FastCGI + PHP-FPM串連 。這個配置將PHP請求都交給 fastcgi_pass配置的PHP-FPM處理。 location分別通過正則過濾和轉發配置決定了各個請求URL將要轉發交與的處理方式 ,location /表示默認請求,location ~\.php(.*)$ 表示PHP 腳本請求全部轉發到 FastCGI處理。 使用FastCGI默認配置.。
以上配置指定了這些 靜態文件要nginx自己處理 。
NGINX負載均衡可以用於很多服務負載均衡的實現,比如做Redis服務的負載均衡,配置upstream的IP列表再配置 proxy_pass 代理即可。那要實現負載均衡除了NGINX,還有哪些呢?
根據7層OSI模型可將負載均衡分為 :
1)二層負載均衡(一般是用虛擬mac地址方式,外部對虛擬MAC地址請求,負載均衡接收後分配後端實際的MAC地址響應);
2)三層負載均衡(一般採用虛擬IP地址方式,外部對虛擬的ip地址請求,負載均衡接收後分配後端實際的IP地址響應);
3)四層負載均衡(在三次負載均衡的基礎上,用 ip+port 接收請求,再轉發到對應的機器);
4)七層負載均衡(根據虛擬的url或是IP,主機名接收請求,再轉向相應的處理伺服器)。
這其中,最常見的是四層和七層負載均衡。思考一下,NGINX的負載均衡是屬於哪一種?
關於負載均衡的架構
4. [code.nginx] Nginx伺服器高級配置
這里提及的參數是和IPv4網路有關的linux內核參數。我們可以將這些內核參數的值追加到Linux系統的/etc/sysctl.conf文件中,然後使用如下命令使修改生效:
這些常用的參數包括以下這些。
** 1. net.core.netdev_max_backlog參數 **
net.core.netdev_max_backlog,表示當每個網路介面接收數據包的速率比內核處理這些包的速率快時,允許發送到隊列的數據包的最大數目。一般默認值為128(可能不同的Linux系統該數值也不同)。Nginx伺服器中定義的NGX_LISTEN_BACKLOG默認為511.我們可以將它調整一下:
** 2.net.core.somaxconn參數 **
該參數用於調節系統同時發起的TCP連接數,一般默認值為128。在客戶端存在高並發請求的情況下,在默認值較小,可能導致鏈接超時或者重傳問題,我們可以根據實際需要結合並發請求數來調節此值。
** 3.net.ipv4.tcp_max_orphans參數 **
該參數用於設定系統中最多允許存在多少TCP套接字不被關聯到任何一個用戶文件句柄上。如果超過這個數字,沒有與用戶文件句柄關聯的TCP套接字將立即被復位,同時給出警告信息。這個限制只是為了防止簡單的DoS(Denial of Service,拒絕服務)攻擊。一般在系統內存比較充足的情況下,可以增大這個參數的賦值:
** 4.net.ipv4.tcp_max_syn_backlog參數 **
該參數用於記錄尚未收到客戶端確認信息的連接請求的最大值。對於擁有128MB內存的系統而言,此參數的默認值是1024,對小內存的系統則是128。一般在系統內存比較充足的情況下,可以增加這個參數的賦值:
** 5.net.ipv4.tcp_timestamps參數 **
該參數用於設置時間戳,這可以避免序列號的卷繞。在一個1Gb/s的鏈路上,遇到以前用過的序列號的概率很大。當此值賦值為0時,禁用對於TCP時間戳的支持。在默認情況下,TCP協議會讓內核接受這種「異常」的數據包。針對Nginx伺服器來說,建議將其關閉:
** 6.net.ipv4.tcp_synack_retries參數 **
該參數用於設置內核放棄TCP連接之前向客戶端發送SYN+ACK包的數量。為了建立對端的連接服務,伺服器和客戶端需要進行三次握手,第二次握手期間,內核需要發送SYN並附帶一個回應前一個SYN的ACK,這個參數主要影響這個進程,一般賦值為1,即內核放棄連接之前發送一次SYN+ACK包,可以設置其為:
** 7.net.ipv4.tcp_syn_retries參數 **
該參數的作用和上一個參數類似,設置內核放棄建立連接之前發送SYN包的數量,它的賦值和上個參數一樣即可:
在Nginx配置文件中,有這樣兩個指令:worker_processes和worker_cpu_affinity,它們可以針對多核CPU進行配置優化。
** 1.worker_processes指令 **
worker_processes指令用來設置Nginx服務的進程數。官方文檔建議此指令一般設置為1即可,賦值太多會影響系統的IO效率,降低Nginx伺服器的性能。為了讓多核CPU能夠很好的並行處理任務,我們可以將worker_processes指令的賦值適當的增大一些,最好是賦值為機器CPU的倍數。當然,這個值並不是越大越好,Nginx進程太多可能增加主進程調度負擔,也可能影響系統的IO效率。針對雙核CPU,建議設置為2或
4。如果是四核CPU,設置為:
設置好worker_processes指令之後,就很有必要設置worker_cpu_affinity指令。
** 2. worker_cpu_affinity指令 **
worker_cpu_affinity指令用來為每個進程分配CPU的工作內核。這個指令用來為每個進程分配CPU的工作內核。這個指令的設置方法有些麻煩。
如下圖所示:
worker_cpu_affinity指令的值是由幾組二進制值表示的。其中,每一組代表一個進程,每組中的每一位表示該進程使用CPU的情況,1表示使用,0表示不使用。注意,二進制位排列順序和CPU的順序是相反的。建議將不同的進程平均分配到不同的CPU運行內核上。
如果設置的Nginx服務的進程數為4,CPU為4核,因此會有四組值,並且每組有四位,所以,此指令的設置為:
四組二進制數值分別對應4個進程,第一個進程對應0001,表示使用第一個CPU內核。第二個進程對應0010,表示使用第二個CPU內核,以此類推。
如果將worker_processes指令的值賦值為8,即賦值為CPU內核個數的兩倍,則worker_cpu_affinity指令的設置可以是:
如果一台機器的CPU是八核CPU,並且worker_processes指令的值賦值為8,那麼worker_cpu_affinity指令的設置可以是:
** 1.keepalive_timeout指令 **
該指令用於設置Nginx伺服器與客戶端保持連接的超時時間。
這個指令支持兩個選項,中間用空格隔開。第一個選項指定客戶端連接保持活動的超時時間,在這個時間之後,伺服器會關閉此連接。第二個選項可選,其指定了使用Keep-Alive消息頭保持活動的有效時間,如果不設置它,Nginx伺服器不會向客戶端發送Keep-Alive消息頭以保持與客戶端某些瀏覽器(如Mozilla、Konqueror等)的連接,超過設置的時間後,客戶端就可以關閉連接,而不需要伺服器關閉了。你可以根據自己的實際情況設置此值,建議從伺服器的訪問數量、處理速度以及網路狀態方面考慮。下面是此指令的設置示例:
該設置表示Nginx伺服器與客戶端連接保持活動的時間是60s,60s後伺服器與客戶端斷開連接。使用Keep-Alive消息頭保持與客戶端某些瀏覽器(如Mozilla、Konqueror等)的連接時間為50s,50s後瀏覽器主動與伺服器斷開連接。
** 2.send_timeout指令 **
該指令用於設置Nginx伺服器響應客戶端的超時時間,這個超時時間僅針對兩個客戶端和伺服器之間建立連接後,某次活動之間的時間。如果這個時間後客戶端沒有任何活動,Nginx伺服器將會關閉連接。此指令的設置需要考慮伺服器訪問數量和網路狀況等方面。下面是此指令的設置示例:
該設置表示Nginx伺服器與客戶端建立連接後,某次會話中伺服器等待客戶端響應超時10s,就會自動關閉連接。
** 3.client_header_buffer_size指令 **
該指令用於設置Nginx伺服器允許的客戶端請求頭部的緩沖區大小,默認為1KB。此指令的賦值可以根據系統分頁大小來設置。分頁大小可以用以下命令取得:
有過Nginx伺服器工作經驗的可能遇到Nginx伺服器返回400錯誤的情況。查找Nginx伺服器的400錯誤原因比較困難,因為此錯誤並不是每次都會出現,出現錯誤的時候,通常在瀏覽器和日誌里也看不到任何有關提示信息。根據實際的經驗來看,有很大一部分情況是客戶端的請求頭部過大造成的。請求頭部過大,通常是客戶單cookie中寫入了較大的值引起的。於是適當增大此指令的賦值,允許Nginx伺服器接收較大的請求頭部,可以改善伺服器對客戶端的支持能力。一般將此指令賦值為4KB大小,即:
** 4.multi_accept指令 **
該指令用於配置Nginx伺服器是否盡可能多的接收客戶端的網路連接請求,默認值為off。
本節涉及的指令與Nginx伺服器的事件驅動模型密切相關。
其中,number為設置的最大數量。結合worker_processes指令,我們可以計算出Nginx伺服器允許同時連接的客戶端最大數量Client = worker_processes * worker_connections / 2;
在使用Nginx伺服器的過程中,筆者曾經遇到過無法訪問Nginx伺服器的情況,查看日誌發現一直在報如下錯誤:
根據報錯信息,推測可能是Nginx伺服器的最大訪問連接數設置小了。此指令設置的就是Nginx伺服器能接受的最大訪問量,其中包括前端用戶連接也包括其他連接,這個值在理論上等於此指令的值與它允許開啟的工作進程最大數的乘積。此指令一般設置為65535:
此指令的賦值與linux操作系統中進程可以打開的文件句柄數量有關系。按照以上設置修改此項賦值以後,Nginx伺服器報以下錯誤:
究其原因,Linux系統中有一個系統指令open file resource limit,它設置了進程可以打開的文件句柄數量。worker_connections指令的賦值當然不能超過open file resource limit的賦值。可以使用以下命令查看在你的Linux系統中open file resource limit的賦值。
可以通過一下命令將open file resource limit指令的值設為2390251:
這樣,Nginx的worker_connections指令賦值為65535就沒問題了。
其中,limit為Linux平台事件信號隊列的長度上限值。
該指令主要影響事件驅動模型中rfsig模型可以保存的最大信號數。Nginx伺服器的每一個工作進程有自己的事件信號隊列用於暫存客戶端請求發生信號,如果超過長度上線,Nginx伺服器自動轉用poll模型處理未處理器的客戶端請求。為了保證Nginx伺服器對客戶端請求的高效處理,請大家根據實際的客戶端並發請求數量和伺服器運行環境的處理能力設定該值。設置示例為:
其中,number為要設置的數量,默認值均為32。
其中,number為要設置的數量,默認值均為512.
使用kequeue_changes方式,可以設置與內核之間傳遞事件的數量。
其中,number為要設置的數量,默認值均為512。
7.rtsig_signo指令
該指令用於設置rtsig模式使用的兩個信號中的第一個,第二個信號是在第一個信號的編號上加1,語法為:
默認的第一個信號設置為SIGRTMIN+10。
提示
在Linux中可以使用一下命令查看系統支持的SIGRTMIN有哪些。
8.rtsig_overflow_* 指令
該指令代表三個具體的指令,分別為rtsig_overflow_events指令、rtsig_overflow_test指令和rtsig_overflow_threshold指令。這些指令用來控制當rtsig模式中信號隊列溢出時Nginx伺服器的處理方式,語法結構為:
其中,number是要設定的值。
rtsig_overflow_events指令指定隊列溢出時使用poll庫處理的事件數,默認值為16。
rtsig_overflow_test指令設定poll庫處理完第幾件事件後將清空rtsig模型使用的信號隊列,默認值為32。
rtsig_overflow_threshold指令指定rtsig模式使用的信號隊列中的事件超過多少時就需要清空隊列了。
5. 初識Nginx配置文件以及基本命令
配置文件名為 nginx.conf ,Linux放在目錄: /usr/local/nginx/conf 、 /etc/nginx , 或 /usr/local/etc/nginx 中;Windows放在 安裝目錄conf 中。 依據實際安裝情況決定
nginx由配置文件中指定的指令控制模塊組成。 指令分為 簡單指令 和 塊指令 :
簡單指令 由空格分隔的名稱和參數組成,並以分號 ; 結尾;
塊指令 具有與簡單指令相同的結構,但是是以大括弧 { 和 } 包圍的一組附加指令。 如果塊指令在大括弧內部有其他指令,則稱為上下文(例如: events , http , server 和 location );
配置文件中放置在任何上下文之外的偽指令都被認為是主上下文。 events 和 http 指令駐留在主上下文中, server 在 http 中的,而 location 在 server 塊中。一個配置文件一個 http ,一個及以上個 server ,一個 server 運行一個工作進程並代表一個虛擬伺服器;
# 號所在的一行被視為注釋;
幾個頂級指令將適用於不同流量類型的指令組合在一起:
對於大多數指令,在子上下文中定義的上下文將繼承父級中包含的偽指令的值,要覆蓋從父進程繼承的值,子上下文中需要包含該指令(即子上下文要顯式聲明)。
打開配置文件(如 /usr/local/nginx/conf/nginx.conf ),默認的配置文件已經包含了伺服器塊的幾個示例,大部分是注釋掉的。 現在注釋掉所有這樣的塊,並啟動一個新的伺服器塊:
每個 server 上下文都可以指定要監聽的埠、server_name,當nginx決定哪個伺服器處理請求後,它會根據伺服器塊內部定義的location指令的參數測試請求頭中指定的URI, 比如如下配置,系統中創建 /data 目錄及其子目錄 /www :
第一個 location 塊指定與請求中的URI比較 / 前綴。 對於匹配請求,URI將被添加到 root 指令中指定的路徑(即 /data/www ),形成本地文件系統中的請求文件路徑。 如果有幾個匹配的location塊,nginx將選擇具有最長前綴來匹配location塊。 上面第一個 location 塊提供最短的前綴長度為1,因此只有當所有其他location塊不能提供匹配時,才會使用該塊。第二個 location ,將是以 /images/ 的請求來匹配,位置 / 也匹配這樣的請求,但具有較短前綴,也就是 /images/ 比 / 長。
這已經是一個在標准埠 80 上偵聽並且可以在本地機器上訪問的伺服器 http://localhost/ 的工作配置, 埠 80 和 server_name localhost 可以省略,它們為默認值 。 響應以/images/開頭的URI的請求,伺服器將從 /data/images 目錄發送文件。 例如,響應 http://localhost/images/logo.png 請求,nginx將發送服務上的 /data/images/logo.png 文件。 如果文件不存在,nginx將發送一個指示 404 錯誤的響應。 不以 /images/ 開頭的URI的請求將映射到 /data/www 目錄。 例如,響應 http://localhost/about/example.html 請求時,nginx將發送 /data/www/about/example.html 文件。
反向代理應該是Nginx做的最多的一件事了,反向代理(Reverse Proxy)方式是指以代理伺服器來接受internet上的連接請求,然後將請求轉發給內部網路上的伺服器,並將從伺服器上得到的結果返回給internet上請求連接的客戶端,此時代理伺服器對外就表現為一個反向代理伺服器。簡單來說就是真實的伺服器不能直接被外部網路訪問,所以需要一台代理伺服器,而代理伺服器能被外部網路訪問的同時又跟真實伺服器在同一個網路環境,當然也可能是同一台伺服器,埠不同而已。
通過向nginx配置文件添加一個server塊來定義代理伺服器,其中包含以下內容:
這將是一個監聽埠 8080 的簡單伺服器,並將所有請求映射到本地文件系統上的 /data/up1 目錄。 請注意,root指令位於server塊上下文中,當選擇用於服務請求的 location 塊不包含自己的 root 指令時,將使用此root指令。創建 /data/up1 目錄然後可以將一個靜態網頁比如 index.html 文件放入其中,然後訪問 http://localhost:8080/ 即可訪問該文件。
目前為止,還是配置的靜態資源訪問,並不是代理伺服器,然後增加或修改現有 location 上下文,改為如下:
當用戶訪問 http://localhost:8080/ 時,會返回 http://localhost:8181 伺服器的的資源。
location 上下文後面的參數,可以是正則表達式,如果是正則表達式,前面要加 ~ ,比如:
以上配置表示,nginx接收到所有以.gif,.jpg或.png結尾的URI,相應的請求將映射到/data/images目錄。當nginx選擇一個location塊來提供請求時,它首先檢查指定前綴的location指令,記住具有最長前綴的location,然後檢查正則表達式。 如果與正則表達式匹配,nginx會選擇此location,否則選擇之前記住的那一個。
要找到最符合URI的位置,NGINX首先將URI與前綴字元串的位置進行比較。然後用正則表達式搜索位置。除非使用^~修飾符對正則表達式給予更高的優先順序。在前綴字元串中,NGINX選擇最具體的字元串(也就是最長和最完整的字元串)。 下面給出了選擇處理請求的位置的確切邏輯:
測試所有URI的前綴字元串。 = (等號)修飾符定義了URI和前綴字元串完全匹配。如果找到完全匹配,則搜索停止。如果 ^~ (插入符號)修飾符預先添加最長匹配前綴字元串,則不會檢查正則表達式。存儲最長匹配的前綴字元串。根據正則表達式測試URI。斷開第一個匹配的正則表達式並使用相應的位置。如果沒有正則表達式匹配,則使用與存儲的前綴字元串相對應的位置。
= 修飾符的典型用例是 / (正斜杠)的請求。 如果請求/是頻繁的,則指定 = / 作為location指令的參數加速處理,因為搜索匹配在第一次比較之後停止。
要啟動nginx,請運行可執行文件。 當nginx啟動後,可以通過使用-s參數調用可執行文件來控制它。 使用以下語法:
信號(signal)的值可能是以下之一:
當主進程收到要重新載入配置的信號,它將檢查新配置文件的語法有效性,並嘗試應用其中提供的配置。 如果這是成功的,主進程將啟動新的工作進程,並向舊的工作進程發送消息,請求它們關閉。 否則,主進程回滾更改,並繼續使用舊配置。 老工作進程,接收關閉命令,停止接受新連接,並繼續維護當前請求,直到所有這些請求得到維護。 之後,舊的工作進程退出。
兩者在 location 中,指定一個路徑,其中使用 alias 做如下配置:
若按照上述配置的話,則訪問/img/目錄裡面的文件時,ningx會自動去/var/www/image/目錄找文件
若按照這種配置的話,則訪問/img/目錄下的文件時,nginx會去/var/www/image/img/目錄下找文件。alias是一個目錄別名的定義,root則是最上層目錄的定義,指的是 /var/www/image/img/ 。還有一個重要的區別是alias後面必須要 / 結束,否則會找不到文件,而root則可有可無。
另外對於index,含義如下
這樣,當用戶請求 / 地址時,Nginx 就會自動在 root 配置指令指定的文件系統目錄下依次尋找 index.htm 和 index.html 這兩個文件。如果 index.htm 文件存在,則直接發起「內部跳轉」到 /index.htm 這個新的地址;而如果 index.htm 文件不存在,則繼續檢查 index.html 是否存在。如果存在,同樣發起「內部跳轉」到 /index.html ;如果 index.html 文件仍然不存在,則放棄處理權給 content 階段的下一個模塊。
參考地址1
參考地址2:B站
6. 跟我學Nginx,nginx 如何處理請求
基於名稱(指 HTTP 請求頭 Host 欄位)的虛擬伺服器指通過 HTTP 請求頭的 Host 來決定客戶端請求由哪個 server 進行處理。
讓我們從一個簡單的配置開始,下面配置了三個虛擬伺服器,它們均偵聽 80 埠 :
上面配置中,nginx 僅測試請求的頭欄位「Host」以確定應將請求路由到哪個 server。如果「Host」的值與任何 server 名稱都不匹配,或者請求根本不包含「Host」頭欄位,則 nginx 會將請求路由到此埠的默認 server。
上面的配置中,默認 server 是第一個 —— 這是 nginx 的標准默認行為。還可以使用 listen 指令中的 default_server 參數明確設置哪個 server 應該是默認 server:
如果不允許處理沒有「Host」頭欄位的客戶端請求(反過來說,只處理帶有 Host 頭欄位的客戶端請求),可以定義一個只丟棄請求的 server:
在這里,server_name 設置為一個空字元串,它將匹配沒有「Host」頭欄位的請求,並返回一個特殊的 nginx 非標准代碼 444 來關閉連接。
讓我們看一個更復雜的配置,其中一些虛擬伺服器偵聽不同的地址:
上面配置中,nginx 首先根據 server 塊的 listen 指令測試請求的 IP 地址和埠。然後,它根據與 IP 地址和埠匹配的 server 塊的 server_name 條目測試請求的「Host」標頭欄位。如果未找到伺服器名稱,則請求將由默認伺服器處理。例如,在 192.168.1.1:80 埠上收到的 www.example.com 請求將由 192.168.1.1:80 埠的默認伺服器處理,即由第一個伺服器處理,因為沒有 www.example .com 為此埠定義。
如前所述,默認伺服器是監聽埠的一個屬性,可以為不同的埠定義不同的默認伺服器:
現在讓我們看看 nginx 如何選擇一個位置來處理一個典型的、簡單的 PHP 站點的請求:
無論列出的順序如何,nginx 首先搜索由文字字元串給出的最具體的前綴位置。在上面的配置中,唯一的前綴位置是「/」,並且由於它匹配任何請求,因此將用作最後的手段。然後 nginx 按照配置文件中列出的順序檢查正則表達式給出的位置。第一個匹配的表達式停止搜索,nginx 將使用這個位置。如果沒有正則表達式匹配請求,則 nginx 使用之前找到的最具體的前綴位置。
注意: 所有類型的位置僅測試不帶參數的請求行的 URI 部分。這樣做是因為查詢字元串中的參數可以通過多種方式給出,例如:
此外,任何人都可以在查詢字元串中請求任何內容:
現在讓我們看看在上面的配置中如何處理請求:
7. nginx 配置詳解是什麼
Nginx是lgor Sysoev為俄羅斯訪問量第二的rambler.ru站點設計開發的。從2004年發布至今,憑借開源的力量,已經接近成熟與完善。
Nginx功能豐富,可作為HTTP伺服器,也可作為反向代理伺服器,郵件伺服器。支持FastCGI、SSL、Virtual Host、URL Rewrite、Gzip等功能。並且支持很多第三方的模塊擴展。
Nginx的穩定性、功能集、示例配置文件和低系統資源的消耗讓他後來居上,在全球活躍的網站中有12.18%的使用比率,大約為2220萬個網站。
1、全局塊:配置影響nginx全局的指令。一般有運行nginx伺服器的用戶組,nginx進程pid存放路徑,日誌存放路徑,配置文件引入,允許生成worker process數等。
2、events塊:配置影響nginx伺服器或與用戶的網路連接。有每個進程的最大連接數,選取哪種事件驅動模型處理連接請求,是否允許同時接受多個網路連接,開啟多個網路連接序列化等。
3、http塊:可以嵌套多個server,配置代理,緩存,日誌定義等絕大多數功能和第三方模塊的配置。如文件引入,mime-type定義,日誌自定義,是否使用sendfile傳輸文件,連接超時時間,單連接請求數等。
4、server塊:配置虛擬主機的相關參數,一個http中可以有多個server。
5、location塊:配置請求的路由,以及各種頁面的處理情況。
Nginx常用功能。
1、Http代理,反向代理:作為web伺服器最常用的功能之一,尤其是反向代理。
Nginx在做反向代理時,提供性能穩定,並且能夠提供配置靈活的轉發功能。Nginx可以根據不同的正則匹配,採取不同的轉發策略,比如圖片文件結尾的走文件伺服器,動態頁面走web伺服器,只要你正則寫的沒問題,又有相對應的伺服器解決方案。
。並且Nginx對返回結果進行錯誤頁跳轉,異常判斷等。如果被分發的伺服器存在異常,他可以將請求重新轉發給另外一台伺服器,然後自動去除異常伺服器。
2、負載均衡
Nginx提供的負載均衡策略有2種:內置策略和擴展策略。內置策略為輪詢,加權輪詢,Ip hash。擴展策略,就天馬行空,只有你想不到的沒有他做不到的啦,你可以參照所有的負載均衡演算法,給他一一找出來做下實現。
8. 13《Nginx 入門教程》Nginx負載均衡(下)
這一小節中,我們將實戰 Nginx 的四層和七層負載均衡功能。條件有限,使用一台公網主機,在上面搭建好 Nginx 服務。公網 IP 為 180.76.152.113。
首先會進行簡單的四層負載均衡實驗,不會涉及多種負載均衡演算法,只使用默認的 Round-Robin演算法。在後續的七層負載均衡實驗中,會重點測試不同的負載均衡策略,完成相關實驗。
首先在 nginx.conf 中添加如下 stream 指令塊配置:
上述配置用埠3000和3001模擬兩個上游伺服器,然後在 upstream 指令塊中指定這兩個上游伺服器的地址,同時給第一個設置權重為2。由於默認採用的是加權的 Round-Robin 演算法,默認伺服器的權重為1。設置為2,表明3次請求中,2次會轉發到3000埠,一次會轉發到3001埠,下面的測試也驗證了這一點。
和四層的配置其實差不多,在七層中除了測試最基本的,我們還將測試前面提到的幾種負載均衡策略,進一步熟悉 Nginx 中的負載均衡配置。
在 nginx.conf 中添加如下的 http 指令塊:
上述配置中,我們用8000,8001和8002三個埠模擬了3個上游伺服器,默認使用輪詢負載均衡演算法,而且三個的權重均為1。進行如下的 http 請求操作,可以看到 Nginx 轉發 http 請求會均勻地分配到3個伺服器上。
我們打開 ip_hash 指令的注釋,這個時候默認是使用客戶端的 ip 地址作為 hash 的 key,然後重啟 Nginx 服務並進行如下的命令行操作:
接下來,注釋 ip_hash 指令,我們打開 hash user_$arg_username 這行配置的注釋, hash 指令可以讓我們根據我們設置的 key 進行 hash,然後根據 hash 值選擇上游的伺服器。具體測試參看下面的 Linux 命令:
這里我們可以看到,在請求中帶上 username 參數,Nginx 中配置的 hash 演算法會根據請求中帶的 username 參數作為 key 去進行 hash,然後在根據 hash 結果映射上游伺服器。username 相同時,選擇的上游伺服器肯定是一樣的,只有在 username 的值發生變化時,返回的響應才可能有變化。
今天我們完成了幾個測試實驗,主要是針對 Nginx 的四層和七層的負載均衡功能進行了測試。這個功能在微服務部署中會有較多的應用。因為高流量企業為保證服務的高可用性,往往會水平擴展多個相同功能的服務,部署在多台主機上,這個時候負載均衡技術就能派上用場了,而 Nginx 提供了完善的負載均衡功能以及多種負載均衡演算法,能滿足大部分企業的需求,如果還不夠,可以通過編寫內部開發模塊並集成到 Nginx,實現相應的需求。所以說 Nginx 是非常值得學習和深入研究的。
9. Nginx配置文件詳解
說到該指令 ,首先得闡述一下什麼是所謂的 「驚群問題」,可以參考 WIKI網路的解釋。就Nginx的場景來解釋的話大致的意思就是:當一個新網路連接來到時,多個worker進程會被同時喚醒,但僅僅只有一個進程可以真正獲得連接並處理之。如果每次喚醒的進程數目過多的話,其實是會影響一部分性能的。
所以在這里,如果accept_mutex on,那麼多個worker將是以串列方式來處理,其中有一個worker會被喚醒;反之若accept_mutex off,那麼所有的worker都會被喚醒,不過只有一個worker能獲取新連接,其它的worker會重新進入休眠狀態。
用rewrite轉發的話,url會發生變化的,那就用proxy_pass吧,於是添加了如下的配置:
在現有環境的nginx里添加這段配置之後,訪問卻始終轉不過去,查看nginx日誌也只能看到是404信息,並沒有更多定位問題的信息。檢查了許久也沒找到原因,於是重新裝了一台新nginx,裡面只加上面這段配置,結果nginx是能夠轉發成功的,這說明單獨來看這條location的配置是沒有問題的,很有可能是現有環境nginx里的某些配置影響到了這個轉發。
為了定位問題原因,我將aaa.example.com虛擬主機下的其他配置注意注釋掉來調試,最後發現當注釋掉proxy_set_header Host $http_host ;這條配置之後,就能成功轉發了。這才注意到是反向代理配置的問題。現有環境中原有的配置也不能隨便刪掉,上網查了下原因,找到下面這種解決方案:
即,在location裡面添加一條proxy_set_header Host http_host時,則不改變請求頭的值,所以當要轉發到bbb.example.com的時候,請求頭還是aaa.example.com的Host信息,就會有問題;當Host設置為$proxy_host時,則會重新設置請求頭為bbb.example.com的Host信息。
另外,關於proxy_pass轉發url的參數,可以通過在location中用rewrite來做,所以完善後的配置如下:
在location用rewrite改變了URI之後,proxy_pass將使用改變後的URI。上面例子(.*)是將所有參數傳給 1會拼接在 http://bbb.example.com 後面。
先來看下proxy_set_header的語法
允許重新定義或者添加發往後端伺服器的請求頭。value可以包含文本、變數或者它們的組合。 當且僅當當前配置級別中沒有定義proxy_set_header指令時,會從上面的級別繼承配置。 默認情況下,只有兩個請求頭會被重新定義:
當匹配到/customer/straightcustomer/download時,使用crmtest處理,到upstream就匹配到crmtest.aty.sohuno.com,這里直接轉換成IP進行轉發了。假如crmtest.aty.sohuno.com是在另一台nginx下配置的,ip為10.22.10.116,則$proxy_host則對應為10.22.10.116。此時相當於設置了Host為10.22.10.116。如果想讓Host是crmtest.aty.sohuno.com,則進行如下設置:
如果不想改變請求頭「Host」的值,可以這樣來設置:
但是,如果客戶端請求頭中沒有攜帶這個頭部,那麼傳遞到後端伺服器的請求也不含這個頭部。 這種情況下,更好的方式是使用$host變數——它的值在請求包含「Host」請求頭時為「Host」欄位的值,在請求未攜帶「Host」請求頭時為虛擬主機的主域名:
此外,伺服器名可以和後端伺服器的埠一起傳送:
如果某個請求頭的值為空,那麼這個請求頭將不會傳送給後端伺服器:
nginx配置項,裡面的配置項有代理https,http,代理靜態文件,H5分發,代理TCP連接,能滿足大多數搭建測試環境所要用的nginx的情況,大家碰到要使用nginx的時候可以參考下
10. nginx如何配置代理
nginx源碼: https://trac.nginx.org/nginx/browser
nginx官網: http://www.nginx.org/
... #全局塊
events { #events塊
...
}
http #http塊
{
}
1、全局塊:全局模塊影響nginx的全局指令,一般有運行nginx伺服器的用戶,nginx進程pid存放路勁,日誌存放路徑,配置文件引入,允許生成worker,process數。
2、events塊:配置影響nginx伺服器或與用戶的網路連接, ,有每個進程的最大連接數,選取哪種事件驅動模型處理連接請求,是否允許同時接受多個連接,開啟多個網路連接序列化。
3、http塊:可以嵌套多個server,配置代理,緩存
4、server塊:配置虛擬主機參數,一個http中有多個server
5、location塊:配置請求的路由。
########### 每個指令必須有分號結束。#################
error_log log/error.log debug; #制定日誌路徑,級別。這個設置可以放入全局塊,http塊,server塊,級別以此為:
debug|info|notice|warn|error|crit|alert|emerg
events {
} http {
}
四、nginx的簡單命令
五、配置解析
server {
1、location 支持配置項目的絕對路徑
2、假設我們的後台API地址是以API開頭,location ^~ /user/ 代表nginx將會攔截請求地址中包含"/user/"字樣的請求,其實這就是我們的ajax請求路徑,攔截到請求之後根據寫法會分成兩種情況把這個請求轉發到 下面 proxy_pass 的地址上。
舉個例子:
a、如上圖,如果proxy_pass 的URL以 / 結尾 ,那麼請求轉發的時候 將 不會 帶上 匹配到的 /api/ ,也就是說如果 登錄請求 URL是 localhost:80/user/login,proxy_pass URL 是 http://a.xx.com:8080/platform/, Nginx將會 把這個請求轉發成 http://a.xx.com:8080/platform/user/login
b、如果proxy_pass 的URL不以 / 結尾 ,那麼請求轉發的時候 將 會帶上 匹配到的 /user/ ,也就是說如果 登錄請求 URL是 localhost:60001/user/login,proxy_pass URL 是 http://a.xx.com:8080/platform/, Nginx將會 把這個請求轉發成 http://a.xx.com:8080/user/login
3、一般我們登錄之後伺服器會通過Set-Cookie把token寫回到我們本地,如果不設置 proxy_cookie_path 的話,伺服器Set-Cookie命令會失效,本地存不了cookie,從而導致token丟失。
這里proxy_cookie_path有一點需要注意的是 如果 proxy_pass URL 是 http://a.xx.com:8080/user/ 這種情況 proxy_cookie_path應該設置成 /platform/ / (注意兩個斜杠之間有空格)。
如果 proxy_pass URL 是 http://a.xx.com:8080/這種情況 proxy_cookie_path應該設置成 / / (注意兩個斜杠之間有空格)
語法規則:location [=| | *|^~] /uri/ { … }