鍍金池/ 教程/ Linux/ Nginx配置Web服務(wù)器
Nginx安裝
Nginx內(nèi)容緩存
Nginx架構(gòu)
Nginx進(jìn)程和運(yùn)行時(shí)控制
Nginx配置虛擬機(jī)
Nginx從源碼構(gòu)建安裝配置
為什么需要Nginx?
Nginx配置文件
Nginx壓縮和解壓
Nginx+PHP7+MySQL5.7(LNMP)環(huán)境配置
Nginx反向代理
Nginx+PHP7源碼安裝配置
Nginx快速入門(mén)
Nginx的優(yōu)勢(shì)(優(yōu)點(diǎn))
Nginx教程
Nginx特性
Nginx配置Web服務(wù)器
Nginx配置日志
Nginx配置靜態(tài)內(nèi)容服務(wù)器
Nginx主要應(yīng)用場(chǎng)景(必讀)
Nginx安裝(從Linx包安裝)

Nginx配置Web服務(wù)器

本文介紹如何將NGINX配置作為Web服務(wù)器,并包括以下部分:

  • 設(shè)置虛擬服務(wù)器
  • 配置位置
  • 使用變量
  • 返回特定狀態(tài)碼
  • 重寫(xiě)請(qǐng)求中的URI
  • 重寫(xiě)HTTP響應(yīng)
  • 處理錯(cuò)誤

在高層次上,將NGINX配置作為Web服務(wù)器有一些問(wèn)題需要了解,定義它處理哪些URL以及如何處理這些URL上的資源的HTTP請(qǐng)求。 在較低層次上,配置定義了一組控制對(duì)特定域或IP地址的請(qǐng)求的處理的虛擬服務(wù)器。

用于HTTP流量的每個(gè)虛擬服務(wù)器定義了稱(chēng)為位置的特殊配置實(shí)例,它們控制特定URI集合的處理。 每個(gè)位置定義了自己的映射到此位置的請(qǐng)求發(fā)生的情況。 NGINX可以完全控制這個(gè)過(guò)程。 每個(gè)位置都可以代理請(qǐng)求或返回一個(gè)文件。 此外,可以修改URI,以便將請(qǐng)求重定向到另一個(gè)位置或虛擬服務(wù)器。 此外,可以返回特定的錯(cuò)誤代碼,也可以配置特定的頁(yè)面以對(duì)應(yīng)于每個(gè)錯(cuò)誤代碼。

1. 設(shè)置虛擬服務(wù)器

NGINX配置文件必須至少包含一個(gè)服務(wù)器指令來(lái)定義虛擬服務(wù)器。 當(dāng)NGINX處理請(qǐng)求時(shí),它首先選擇提供請(qǐng)求的虛擬服務(wù)器。
虛擬服務(wù)器由http上下文中的服務(wù)器指令定義,例如:

http {
    server {
        # Server configuration
    }
}

可以將多個(gè)server指令添加到http上下文中以定義多個(gè)虛擬服務(wù)器。
server配置塊通常包括一個(gè)listen指令,用于指定服務(wù)器偵聽(tīng)請(qǐng)求的IP地址和端口(或Unix域套接字和路徑)。IPv4和IPv6地址均被接受; 將方括號(hào)(。
下面的示例顯示了監(jiān)聽(tīng)I(yíng)P地址127.0.0.1和端口8080的服務(wù)器的配置:

server {
    listen 127.0.0.1:8080;
    # The rest of server configuration
}

如果省略端口,則使用標(biāo)準(zhǔn)端口。 同樣地,如果省略一個(gè)地址,服務(wù)器將偵聽(tīng)所有地址。 如果沒(méi)有包含listen指令,則“標(biāo)準(zhǔn)”端口為80/tcp,“default”端口為8000/tcp,具體取決于超級(jí)用戶(hù)權(quán)限。

如果有多個(gè)服務(wù)器與請(qǐng)求的IP地址和端口相匹配,則NGINX將根據(jù)服務(wù)器塊中的server_name指令測(cè)試請(qǐng)求的主機(jī)頭域。 server_name的參數(shù)可以是完整(精確)名稱(chēng),通配符或正則表達(dá)式。 通配符是一個(gè)字符串,其開(kāi)頭,結(jié)尾或兩者都包含星號(hào)(*); 星號(hào)匹配任何字符序列。 NGINX將Perl語(yǔ)法用于正則表達(dá)式; 在它們之前使用波浪號(hào)(?)。 此示例說(shuō)明了一個(gè)確切的名稱(chēng)。

server {
    listen      80;
    server_name example.org www.example.org;
    ...
}

如果匹配主機(jī)頭幾個(gè)名稱(chēng),則NGINX通過(guò)按以下順序搜索名稱(chēng)并使用其找到的第一個(gè)匹配來(lái)選擇一個(gè):

  1. 確切的名字(完整準(zhǔn)確的名稱(chēng))
  2. 以星號(hào)開(kāi)頭的最長(zhǎng)通配符,例如:*.example.org
  3. 以星號(hào)結(jié)尾的最長(zhǎng)通配符,如:mail.*
  4. 第一個(gè)匹配正則表達(dá)式(按照出現(xiàn)在配置文件中的順序)

如果主機(jī)頭字段與服務(wù)器名稱(chēng)不匹配,則NGINX會(huì)將請(qǐng)求路由到請(qǐng)求到達(dá)端口的默認(rèn)服務(wù)器。 默認(rèn)服務(wù)器是nginx.conf文件中列出的第一個(gè)服務(wù)器,除非您將listen_server參數(shù)包含在listen指令中以明確指定服務(wù)器為默認(rèn)值。

server {
    listen    80    default_server;
    ...
}

一個(gè)完整的Nginx虛擬機(jī)配置示例,這里我們演示配置兩個(gè)虛擬機(jī),對(duì)應(yīng)域名分別為:vhost1.comvhost2.com,vhost1.com網(wǎng)站的主目錄在/data/www/vhost1,vhost2.com網(wǎng)站的主目錄在/data/www/vhost2

server {
    listen       80;
    server_name vhost1.com www.vhost1.com;
    index index.html index.html;
    root  /data/www/vhost1;
    access_log  /var/log/vhost1.com.log;
}

server {
    listen       80;
    server_name vhost2.com www.vhost2.com;
    index index.html index.html;
    root  /data/www/vhost2;
    access_log  /var/log/vhost2.com.log;
}

2. 配置位置

NGINX可以根據(jù)請(qǐng)求URI向不同的代理發(fā)送流量或提供不同的文件。 這些塊是使用放置在server指令中的location指令來(lái)定義的。

例如,您可以定義三個(gè)location塊,以指示虛擬服務(wù)器向一個(gè)代理服務(wù)器發(fā)送一些請(qǐng)求,將其他請(qǐng)求發(fā)送到不同的代理服務(wù)器,并通過(guò)從本地文件系統(tǒng)傳遞文件來(lái)提供其余請(qǐng)求。

NGINX測(cè)試根據(jù)所有location指令的參數(shù)請(qǐng)求URI,并應(yīng)用匹配location中定義的指令。 在每個(gè)location塊內(nèi),通常可能(除了一些例外)放置更多的location指令以進(jìn)一步細(xì)化特定組請(qǐng)求的處理。

注意:在本教程文章中,單詞location是指單個(gè)location上下文。

location指令有兩種類(lèi)型的參數(shù):前綴字符串(路徑名)和正則表達(dá)式。 對(duì)于要匹配前綴字符串的請(qǐng)求URI,必須以前綴字符串開(kāi)頭。

具有pathname參數(shù)的以下示例位置匹配以/some/path/開(kāi)頭的請(qǐng)求URI,例如/some/path/document.html,它不匹配/my-site/some/path,因?yàn)?code>/some/path不在該URI的開(kāi)頭出現(xiàn)。

location /some/path/ {
    ...
}

正則表達(dá)式之前是區(qū)分大小寫(xiě)匹配的波形符號(hào)(~),或者不區(qū)分大小寫(xiě)匹配的波形符號(hào)(~*)。 以下示例將包含字符串.html.html的URI與任何位置相匹配。

location ~ \.html? {
    ...
}

要找到最符合URI的位置,NGINX首先將URI與前綴字符串的位置進(jìn)行比較。然后用正則表達(dá)式搜索位置。
除非使用^~修飾符對(duì)正則表達(dá)式給予更高的優(yōu)先級(jí)。在前綴字符串中,NGINX選擇最具體的字符串(也就是最長(zhǎng)和最完整的字符串)。 下面給出了選擇處理請(qǐng)求的位置的確切邏輯:

  1. 測(cè)試所有URI的前綴字符串。
  2. =(等號(hào))修飾符定義了URI和前綴字符串完全匹配。如果找到完全匹配,則搜索停止。
  3. 如果^~(插入符號(hào))修飾符預(yù)先添加最長(zhǎng)匹配前綴字符串,則不會(huì)檢查正則表達(dá)式。
  4. 存儲(chǔ)最長(zhǎng)匹配的前綴字符串。
  5. 根據(jù)正則表達(dá)式測(cè)試URI。
  6. 斷開(kāi)第一個(gè)匹配的正則表達(dá)式并使用相應(yīng)的位置。
  7. 如果沒(méi)有正則表達(dá)式匹配,則使用與存儲(chǔ)的前綴字符串相對(duì)應(yīng)的位置。

=修飾符的典型用例是/(正斜杠)的請(qǐng)求。 如果請(qǐng)求/是頻繁的,則指定=/作為location指令的參數(shù)加速處理,因?yàn)樗阉髌ヅ湓诘谝淮伪容^之后停止。

location = / {
    ...
}

location上下文可以包含定義如何解析請(qǐng)求的指令 - 提供靜態(tài)文件或?qū)⒄?qǐng)求傳遞給代理的服務(wù)器。 在以下示例中,匹配第一個(gè)location上下文的請(qǐng)求將從/data/images目錄中提供文件,并將匹配第二個(gè)位置的請(qǐng)求傳遞給承載 www.example.com 域內(nèi)容的代理服務(wù)器。

server {
    location /images/ {
        root /data;
    }

    location / {
        proxy_pass http://www.example.com;
    }
}

root指令指定要在其中搜索要提供的靜態(tài)文件的文件系統(tǒng)路徑。 與該位置相關(guān)聯(lián)的請(qǐng)求URI將附加到路徑,以獲取要提供的靜態(tài)文件的全名。 在上面的示例中,要響應(yīng)/images/logo.png的請(qǐng)求,NGINX提供服務(wù)器本地實(shí)際對(duì)應(yīng)文件是:/data/images/logo.png

proxy_pass指令將請(qǐng)求傳遞給使用配置的URL訪(fǎng)問(wèn)代理服務(wù)器。然后將代理服務(wù)器的響應(yīng)傳回客戶(hù)端。在上面的示例中,所有不以/images/開(kāi)頭的URI的請(qǐng)求都將被傳遞給代理的服務(wù)器(也就是:www.example.com)。

3. 使用變量

可以使用配置文件中的變量,使NGINX進(jìn)程的請(qǐng)求根據(jù)定義的情況而有所不同。 變量是在運(yùn)行時(shí)計(jì)算的命名值,用作指令的參數(shù)。 一個(gè)變量由它的名字開(kāi)頭的$(美元)符號(hào)表示。 變量根據(jù)NGINX的狀態(tài)定義信息,例如正在處理的請(qǐng)求的屬性。

有許多預(yù)定義的變量,如核心HTTP變量,您可以使用setmapgeo指令定義自定義變量。 大多數(shù)變量在運(yùn)行時(shí)計(jì)算的,并包含與特定請(qǐng)求相關(guān)的信息。 例如,$remote_addr包含客戶(hù)端IP地址,$uri保存當(dāng)前的URI值。

4. 返回特定狀態(tài)碼

一些網(wǎng)站URI需要立即返回具有特定錯(cuò)誤或重定向代碼的響應(yīng),例如當(dāng)頁(yè)面被暫時(shí)移動(dòng)或永久移動(dòng)時(shí)。 最簡(jiǎn)單的方法是使用return指令。 例如返回未找到的404狀態(tài)碼:

location /wrong/url {
    return 404;
}

返回的第一個(gè)參數(shù)是響應(yīng)代碼。可選的第二個(gè)參數(shù)可以是重定向的URL(代碼301,302,303307)或在響應(yīng)體中返回文本。 例如:

location /permanently/moved/url {
    return 301 http://www.example.com/moved/here;
}

返回指令可以包含在 locationserver 上下文中。

重寫(xiě)URI請(qǐng)求

可以通過(guò)使用rewrite指令在請(qǐng)求處理期間多次修改請(qǐng)求URI,該指令具有一個(gè)可選參數(shù)和兩個(gè)必需參數(shù)。 第一個(gè)(必需)參數(shù)是請(qǐng)求URI必須匹配的正則表達(dá)式。 第二個(gè)參數(shù)是用于替換匹配URI的URI。 可選的第三個(gè)參數(shù)是可以停止進(jìn)一步重寫(xiě)指令的處理或發(fā)送重定向(代碼301302)的標(biāo)志。例如:

location /users/ {
    rewrite ^/users/(.*)$ /show?user=$1 break;
}

如該示例所示,用戶(hù)通過(guò)匹配正則表達(dá)式捕獲第二個(gè)參數(shù)。

您可以在locationserver上下文中包含多個(gè)rewrite指令。 NGINX按照它們發(fā)生的順序逐個(gè)執(zhí)行指令。 當(dāng)選擇該上下文時(shí),server上下文中的rewrite指令將被執(zhí)行一次。
在NGINX處理一組rewrite指令之后,它根據(jù)新的URI選擇一個(gè)location上下文。 如果所選location塊包含rewrite指令,則依次執(zhí)行它們。 如果URI與其中任何一個(gè)匹配,則在處理所有定義的rewrite指令之后,將搜索新location塊。

以下示例顯示了與返回指令相結(jié)合的rewrite指令。

server {
    ...
    rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
    rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra  last;
    return  403;
    ...
}

此示例配置區(qū)分兩組URI。 諸如/download/some/media/file之類(lèi)的URI更改為/download/some/mp3/file.mp3。由于最后一個(gè)標(biāo)志,所以跳過(guò)后續(xù)指令(第二次rewritereturn指令),但NGINX繼續(xù)處理該請(qǐng)求,該請(qǐng)求現(xiàn)在具有不同的URI。類(lèi)似地,諸如/download/some/audio/file的URI被替換為/download/some/mp3/file.ra。 如果URI與rewrite指令不匹配,則NGINX將403錯(cuò)誤代碼返回給客戶(hù)端。

有兩個(gè)中斷處理重寫(xiě)指令的參數(shù):

  • last - 停止執(zhí)行當(dāng)前服務(wù)器或位置上下文中的重寫(xiě)指令,但是NGINX會(huì)搜索與重寫(xiě)的URI匹配的位置,并且應(yīng)用新位置中的任何重寫(xiě)指令(URI可以再次更改,往下繼續(xù)匹配)。
  • break - 像break指令一樣,在當(dāng)前上下文中停止處理重寫(xiě)指令,并取消搜索與新URI匹配的位置。新位置(location)塊中的rewrite指令不執(zhí)行。

5. 重寫(xiě)HTTP響應(yīng)

有時(shí)您需要重寫(xiě)或更改HTTP響應(yīng)中的內(nèi)容,將一個(gè)字符串替換為另一個(gè)字符串。 您可以使用sub_filter指令來(lái)定義要應(yīng)用的重寫(xiě)。 該指令支持變量和替代鏈,使更復(fù)雜的更改成為可能。
例如,您可以更改引用除代理服務(wù)器之外的絕對(duì)鏈接:

location / {
    sub_filter      /blog/ /blog-staging/;
    sub_filter_once off;
}

另一個(gè)示例將方法從http://更改為http://,并從請(qǐng)求頭域替換本地主機(jī)地址到主機(jī)名。 sub_filter_once指令告訴NGINX在一個(gè)位置(location)內(nèi)連續(xù)應(yīng)用sub_filter偽指令:

location / {
    sub_filter     'href="http://127.0.0.1:8080/'    'href="http://$host/';
    sub_filter     'img src="http://127.0.0.1:8080/' 'img src="http://$host/';
    sub_filter_once on;
}

請(qǐng)注意,如果發(fā)生另一個(gè)sub_filter匹配,則使用sub_filter修改的響應(yīng)部分將不再被替換。

  1. 處理錯(cuò)誤

使用error_page指令,您可以配置NGINX返回自定義頁(yè)面以及錯(cuò)誤代碼,替換響應(yīng)中的其他錯(cuò)誤代碼,或?qū)g覽器重定向到其他URI。 在以下示例中,error_page指令指定要返回404頁(yè)面錯(cuò)誤代碼的頁(yè)面(/404.html)。

error_page 404 /404.html;

請(qǐng)注意,此偽指令并不立即返回該錯(cuò)誤(返回指令執(zhí)行該操作),而僅僅是指定發(fā)生時(shí)如何處理錯(cuò)誤。 錯(cuò)誤代碼可以來(lái)自代理服務(wù)器,或者在NGINX處理期間發(fā)生(例如,當(dāng)NGINX找不到客戶(hù)端請(qǐng)求的文件時(shí),顯示404對(duì)應(yīng)的結(jié)果)。

在以下示例中,當(dāng)NGINX找不到頁(yè)面時(shí),它會(huì)將代碼301替換為代碼404,并將客戶(hù)端重定向到http:/example.com/new/path.html。 當(dāng)客戶(hù)端仍嘗試訪(fǎng)問(wèn)其舊URI的頁(yè)面時(shí),此配置非常有用。 301代碼通知瀏覽器頁(yè)面已經(jīng)永久移動(dòng),并且需要在返回時(shí)自動(dòng)替換舊地址。

location /old/path.html {
    error_page 404 =301 http:/example.com/new/path.html;
}

以下配置是在未找到文件時(shí)將請(qǐng)求傳遞給后端的示例。 因?yàn)樵?code>error_page指令的等號(hào)之后沒(méi)有指定狀態(tài)代碼,所以對(duì)客戶(hù)機(jī)的響應(yīng)具有代理服務(wù)器返回的狀態(tài)代碼(不一定是404)。

server {
    ...
    location /images/ {
        # Set the root directory to search for the file
        root /data/www;

        # Disable logging of errors related to file existence
        open_file_cache_errors off;

        # Make an internal redirect if the file is not found
        error_page 404 = /fetch$uri;
    }

    location /fetch/ {
        proxy_pass http://backend/;
    }
}

當(dāng)沒(méi)有找到文件時(shí),error_page指令指示NGINX進(jìn)行內(nèi)部重定向。 error_page指令的最終參數(shù)中的$uri變量保存當(dāng)前請(qǐng)求的URI,該URI在重定向中被傳遞。

例如,如果沒(méi)有找到/images/some/file,它將被替換為/fetch/images/some/file,并且新的搜索位置(location)開(kāi)始。最后請(qǐng)求最終在第二個(gè)location上下文中,并被代理到http://backend/。

如果沒(méi)有找到文件,則open_file_cache_errors指令可防止寫(xiě)入錯(cuò)誤消息。 因?yàn)閬G失的文件可被正確地處理,但這不是必需的。