3. Nginx web server配置

添加虛擬服務(wù)器

Nginx配置文件中至少包含一條定義虛擬服務(wù)器的server指令。當(dāng)Nginx處理一個(gè)請(qǐng)求時(shí),第一個(gè)被選中的虛擬服務(wù)器將用于處理該請(qǐng)求。

虛擬服務(wù)器通過(guò)http指令中的server指令來(lái)定義,示例如下:

http {
    server {
        # 服務(wù)器配置
    }
}

http中可以包含多條server指令來(lái)定義多個(gè)虛擬服務(wù)器。

通常server指令中會(huì)包含一條listen指令,用于指定該虛擬服務(wù)器將要監(jiān)聽(tīng)的IP地址和端口。示例如下:

server {
    listen 127.0.0.1:8080;
    # 其他配置
}

如果不填寫(xiě)端口,則采用標(biāo)準(zhǔn)端口。如果不填寫(xiě)ip地址,則監(jiān)聽(tīng)所有地址。如果缺少整條listen指令,則標(biāo)準(zhǔn)端口是80/tcp,默認(rèn)端口是8000/tcp,由超級(jí)用戶(hù)的權(quán)限決定。

如果有多個(gè)server配置了相同的ip地址和端口,Nginx會(huì)匹配server_name指令與請(qǐng)求頭部的host字段。server_name指令的參數(shù)可以是精確的文本、通配符或正則表達(dá)式。通配符可以在字符串的頭部、尾部或兩端包含*,*可以匹配任意字符。Nginx采用Perl格式的正則表達(dá)式,以~開(kāi)頭。以下是一個(gè)精確匹配的例子:

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

如果有多個(gè)server_name匹配host字段,Nginx根據(jù)以下規(guī)則選擇第一個(gè)相匹配的server處理請(qǐng)求:

  1. 精確匹配
  2. *開(kāi)始的最長(zhǎng)通配符,如*.example.org
  3. *結(jié)尾的最長(zhǎng)通配符,如mail.*
  4. 第一個(gè)匹配的正則表達(dá)式(根據(jù)在配置文件中出現(xiàn)的先后順序)

如果找不到任何與host字段相匹配的server_name,Nginx會(huì)根據(jù)請(qǐng)求端口將其發(fā)送給默認(rèn)的server。默認(rèn)server就是配置文件中第一個(gè)出現(xiàn)的server,也可以通過(guò)default_server指定某個(gè)server為默認(rèn)server,如下所示:

server {
    listen      80 default_server;
    ...
}

配置Location指令

Nginx根據(jù)URL將請(qǐng)求發(fā)送給不同的代理,或處理不同的文件請(qǐng)求。由server指令中的location指令配置規(guī)則。

比如,可以為虛擬服務(wù)器配置三個(gè)location指令,將一些請(qǐng)求發(fā)送給代理服務(wù)器#1,將另外一些請(qǐng)求發(fā)送給代理服務(wù)器#2,再由本地文件系統(tǒng)處理剩余請(qǐng)求。

Nginx會(huì)將請(qǐng)求的URL匹配所有的location指令,請(qǐng)執(zhí)行匹配location中的指令。每個(gè)location指令中通常還會(huì)包含多條更為精細(xì)匹配的location指令。

location指令包含兩類(lèi)參數(shù):前綴字符串正則表達(dá)式。請(qǐng)求要匹配前綴字符串的話(huà),必須以前綴字符串開(kāi)始。

以下例子中l(wèi)ocation參數(shù)匹配以/some/path/開(kāi)始的請(qǐng)求URI,如/some/path/document.html(不匹配/my-site/some/path,因?yàn)?code>/some/path不在起始位置)。

location /some/path/ {
    ...
}

~用于匹配區(qū)分大小寫(xiě)的正則表達(dá)式,~*用于匹配不區(qū)分大小寫(xiě)的正則表達(dá)式。下面例子匹配任意包含.html.htm的URI。

location ~ \.html? {
    ...
}

Nginx先匹配前綴字符串,然后再匹配正則表達(dá)式。正則表達(dá)式擁有較高優(yōu)先級(jí),除非使用^~修飾符。在所有前綴字符串中,Nginx會(huì)挑選最精確的那個(gè),也就是最長(zhǎng)最匹配的那個(gè)。詳細(xì)匹配過(guò)程如下:

  1. 匹配所有前綴字符串;
  2. 如果有一個(gè)=定義的精確匹配前綴字符串,停止繼續(xù)匹配;
  3. 如果^~在最長(zhǎng)匹配的前綴字符串之前,將忽略正則表達(dá)式;
  4. 存儲(chǔ)最長(zhǎng)的匹配前綴字符串;
  5. 匹配正則表達(dá)式;
  6. 找到第一個(gè)相匹配的正則表達(dá),停止匹配過(guò)程,并執(zhí)行該location指令;
  7. 如果沒(méi)有正則表達(dá)式匹配,則使用第4部存儲(chǔ)的最長(zhǎng)前綴字符串;

=修飾符的典型應(yīng)用是匹配 /請(qǐng)求。針對(duì)頻繁訪(fǎng)問(wèn)/的情況,將location參數(shù)設(shè)置為= /可以加速處理過(guò)程,因?yàn)檎麄€(gè)匹配過(guò)程在第一條之后就結(jié)束了。

location = / {
    ...
}

location指令內(nèi)可以配置如何處理請(qǐng)求:處理靜態(tài)文檔或?qū)⒄?qǐng)求轉(zhuǎn)發(fā)給代理服務(wù)器。在下面的例子中,匹配第一個(gè)location的請(qǐng)求可以訪(fǎng)問(wèn)/data目錄的文件,匹配第二個(gè)location的請(qǐng)求將被轉(zhuǎn)發(fā)到www.example.com服務(wù)器。

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

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

其中root指令指定了靜態(tài)文件的文件系統(tǒng)路徑,將與請(qǐng)求URI一起構(gòu)成靜態(tài)文件的完全路徑。在上述例子中,請(qǐng)求/images/example.png將返回服務(wù)器上位于/data/images/example.png的文件。

proxy_pass指令將請(qǐng)求轉(zhuǎn)發(fā)到代理服務(wù)器,并將代理服務(wù)器的響應(yīng)返回給客戶(hù)端。在上述例子中,所有不是以/images/開(kāi)頭的URI請(qǐng)求都將被轉(zhuǎn)發(fā)到代理服務(wù)器。

使用變量

通過(guò)在配置文件中使用變量,可以讓Nginx以不同的方式處理請(qǐng)求。變量的值在運(yùn)行時(shí)計(jì)算獲得,并可作為參數(shù)傳遞給指令。變量必須以$開(kāi)頭。變量基于Nginx的狀態(tài)定義信息,如正被處理請(qǐng)求的屬性。

Nginx包含許多預(yù)設(shè)的變量,如core HTTP變量集,也可以使用setmapgeo指令來(lái)自定義變量。大多數(shù)變量都在運(yùn)行時(shí)計(jì)算值,這些值一般都包含某個(gè)請(qǐng)求的相關(guān)信息。如$remote_addr包含了IP地址,而uri則包含了當(dāng)前訪(fǎng)問(wèn)的URI

返回指定狀態(tài)碼

有些網(wǎng)站在處理錯(cuò)誤或重定向時(shí),會(huì)要求立即返回一個(gè)狀態(tài)碼。最簡(jiǎn)單的方式就是使用return指令,如下所示:

location /wrong/url {
    return 404;
}

return指令的第一個(gè)參數(shù)是一個(gè)狀態(tài)碼。第二個(gè)是可選參數(shù),可以是重定向的URL(當(dāng)狀態(tài)碼是301、302、303和307時(shí)),也可以是返回的文本信息。示例如下:

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

locationserver中都可以包含return指令。

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

在處理請(qǐng)求過(guò)程中,可以通過(guò)rewrite指令重復(fù)修改請(qǐng)求的URI。rewrite指令包含2個(gè)必填參數(shù)和1個(gè)可選參數(shù)。第一個(gè)參數(shù)是請(qǐng)求URI必須匹配的正則表達(dá)式。第二個(gè)參數(shù)是要替換的目標(biāo)URI。第三個(gè)為可選參數(shù),可以是一個(gè)是否繼續(xù)執(zhí)行后續(xù)rewrite指令的標(biāo)記,也可以發(fā)送一個(gè)重定向指令(狀態(tài)碼是301或302)。示例如下:

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

locationserver中都可以包含多個(gè)rewrite指令。Nginx從上到下依次磁性rewrite指令,每次進(jìn)入server指令塊時(shí),rewrite指令都會(huì)被執(zhí)行一次。

Nginx執(zhí)行完一系列rewrite指令后,根據(jù)最新的URI來(lái)選擇location指令。如果location中也包含rewrite指令,它們也將被依次執(zhí)行,執(zhí)行完畢后將重新選擇location。

下面是一個(gè)rewritereturn聯(lián)合一起使用的例子。

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

這個(gè)例子用于區(qū)分兩套不同的URI。類(lèi)似于/download/some/media/file的URI將被改寫(xiě)為/download/some/mp3/file.mp3。由于最后的標(biāo)識(shí)last,Nginx將忽略隨后的兩條指令,然后以新的URI繼續(xù)處理請(qǐng)求。同樣地,類(lèi)似于/download/some/audio/file的URI將被改寫(xiě)為/download/some/mp3/file.ra。如果請(qǐng)求URI都不匹配上述兩條rewrite指令,Nginx將返回403錯(cuò)誤代碼。

rewrite指令可以包含以下兩種參數(shù),用于中斷處理過(guò)程:

  • last - 停止執(zhí)行當(dāng)前serverlocation中的rewrite指令,并以新的URI查找新的location;
  • break - 停止執(zhí)行當(dāng)前上下文環(huán)境內(nèi)的rewrite指令,并不以新的URI查找新的location;

重寫(xiě)HTTP返回信息

sub_filter指令支持重寫(xiě)或修改HTTP請(qǐng)求的響應(yīng)內(nèi)容,如替換某個(gè)字符串。該指令支持變量和鏈?zhǔn)教鎿Q。

下例中,將指向服務(wù)器的鏈接改為指向代理服務(wù)器的鏈接:

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

另一個(gè)例子是將http請(qǐng)求改為https請(qǐng)求,并將請(qǐng)求頭部的本地主機(jī)地址改為主機(jī)名。sub_filter_once指令用于告訴Nginx是否連續(xù)執(zhí)行location中的sub_filter指令。

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

注意:被sub_filter指令修改后的內(nèi)容將不會(huì)再被其他sub_filter指令修改。

錯(cuò)誤處理

error_page指令用于返回一個(gè)自定義錯(cuò)誤頁(yè)面和一個(gè)錯(cuò)誤代碼、修改響應(yīng)中的錯(cuò)誤代碼或重定向到不同的URI。在下面的例子中,error_page指令返回404錯(cuò)誤和一個(gè)錯(cuò)誤頁(yè):

error_page 404 /404.html;

注意:該指令并不會(huì)馬上返回(這是return指令做的事),僅僅指定出錯(cuò)時(shí)如何處理。錯(cuò)誤代碼可以能來(lái)自于代理服務(wù)器,也可能來(lái)自Nginx本身(如Nginx沒(méi)有找到請(qǐng)求的文件)。

在下面的例子中,當(dāng)Nginx未能找到請(qǐng)求的頁(yè)面時(shí),不會(huì)返回404,而會(huì)返回303和一個(gè)重定向到新頁(yè)面指令。這通常用于處理客戶(hù)端訪(fǎng)問(wèn)舊地址的情況。

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

以下例子中,當(dāng)訪(fǎng)問(wèn)一個(gè)不存在的文件時(shí),Nginx會(huì)將請(qǐng)求重定向到http://backend。由于error_page指令未指定重定向代碼,該代碼將由重定向后的http://backend返回。

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)請(qǐng)求文件未找到時(shí),error_page指令將發(fā)起一個(gè)內(nèi)部重定向。$url變量持有當(dāng)前請(qǐng)求的URI,并被傳遞給重定向。

假設(shè)請(qǐng)求的/images/some/file文件未找到,將被重定向到/fetch/images/some/file,同時(shí)搜索新的location。最終,請(qǐng)求將被第二個(gè)location處理,并被代理到http://backend

open_file_cache_errors指令可用于未找到請(qǐng)求文件時(shí),禁止產(chǎn)生錯(cuò)誤消息。在上述例子中可以忽略,因?yàn)殄e(cuò)誤已被正確處理。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容