Nginx-入門

本文對Nginx進行了基本介紹,並描述了一些可以使用它完成的簡單任務。假設已經安裝了Nginx,如果沒有,請參閱“Nginx-簡介”。本博文介紹瞭如何啓動和停止Nginx以及重新加載其配置,解釋了配置文件的結構,並描述瞭如何設置Nginx以提供靜態內容,如何將Nginx配置爲代理服務器以及如何將其與FastCGI應用程序相連接。

啓動、停止和重新加載配置

nginx -s <signal>

signal可以是以下信號之一:

  • stop: 快速關機
  • quit: 正常關機
  • reload: 重新加載配置文件
  • reopening: 重新打開日誌文件

如果要停止Nginx進程,等待工作進程完成當前請求,可以執行以下命令:

nginx -s quit

在諸如kill應用程序等Unix工具的幫助下,也可以向Nginx進程發送信號。在這種情況下,一個信號被直接發送到指定進程ID的進程。Nginx主進程的ID在默認情況下,被寫入在/usr/local/nginx/logs或者/var/run目錄下的nginx.pid文件當中。如果Nginx的主進程ID爲1628,要發送退出信號,優雅的關閉Nginx,我們可以這樣:

nginx -s QUIT 1628

配置文件的結構

Nginx由模塊組成,模塊由配置文件中指定的指定控制。指令分爲簡單指令塊指令。一個簡單的指令由名稱和參數組成,用空格分割,以分號結束。塊指令具有與簡單指令相同的結構,但不是分號,而是一組由大括號包圍的附加指令。如果一個塊指令可以在大括號中包含其他指令,那麼它被稱爲上下文(例如:events、http、server和location)

任何放置在上下文外部的配置文件中的指令被認爲是在主上下文中。eventshttp指令駐留在主上下文中,server駐留在http當中,location駐留在server當中。

其中“#”後面都代表是註釋內容

頂級上下文有:

  • events: 處理常規連接
  • http: http請求
  • mail: 郵件
  • stream: TCP和UDP

在每個http上下文中,都包含一個或多個server塊來定義控制請求處理的虛擬服務器。對於http上下文,每個server指令控制對特定域或IP地址上的資源請求的處理。每個server上下文中包含一個或多個location塊來處理特定的Uri集。對於mail或者stream上下文,server指令分別控制到達特定TCP端口或UNIX套接字的通信處理。

通常子上下文繼承父上下文中包含的指令的設置。一些指令可以出現在多個上下文當中,在這種情況之下,子上下文中的指令會覆蓋父上下文中的同名指令。

提供靜態內容

Web服務器的一項重要任務是分發文件。首先,我們先做一些準備工作,創建/user/image目錄,並放置一個favorite.png圖片。接下來,我們來修改一下/etc/nginx/sites-enabled目錄下的default文件(此文件安裝Nginx完後存在),在server上下文中添加一個location塊指令,如下:

location /image/ {
    root /user;
}

修改保存之後,重啓Nginx。對於匹配的請求,會將URL添加到root指定指定的路徑,即添加到/user中,形成/user/image/就是我們本地文件系統上所請求文件的路徑。我們在瀏覽器中訪問http://localhost/image/favorite.png就能正確定位到圖片了!如果有多個location塊,將匹配前綴最長的的那個!其中root指令指定目錄!

如果某些功能無法正常工作,你可以查看/var/log/nginx/access.log/var/log/nginx/error.log文件來查找原因!

設置簡單的代理服務器

Nginx的一個常見用法是將其設置爲代理服務器,這意味着服務器接收請求,將其傳遞給代理服務器,從代理服務器檢索響應並將其發送給客戶機。我們將配置一個基本的代理服務器,它使用本地目錄中的文件夾來處理圖像請求,並將所有請求發送到服務器中。在本例中,這兩個服務器定義在一個Nginx實例中,如下:

server {
    listen 8080;
    root /user/data;
    location / {
        index index.html;
    }
}

這是一個簡單的服務器,它監聽端口8080(如果沒有指定listen指令,將默認監聽80端口),並將所有的請求映射到本地文件系統上的/user/data目錄。需先創建該目錄,並將index.html文件放置在該目錄當中,否則請求將會引發404錯誤!

注意,當服務請求的location塊不包含root指令時,就會使用上下文中的root指令!

下面,我們將修改一下配置,將成爲代理服務器配置,如下:

server {
    listen 80;
    location / {
        proxy_pass http://localhost:8080;
    }
    location /image/ {
        root /user;
    }
}

在第一個location塊中,使用proxy_pass指令與參數中的協議、代理服務器的名稱和端口放在一起。我們還可以對location做一些正則匹配,如下:

location ~ \.(png|jpg|gif)$ {
    root /user;
}

如此,請求匹配所有以.gif.jpg.gif結尾的Uri。正則表達式的前面應該加上~,表示將使用正則表達式進行匹配!

設置FastCGI代理

Nginx可用於將請求路由到FastCGI服務器,FastCGI服務器運行各種框架和編程語言(如PHP)構建的應用程序。使用FastCGI服務器最基本的Nginx配置包括使用fastcgi_pass指令替代proxy_pass指令,使用facgi_param指令設置傳遞給FastCGI服務器的參數。假設FastCGI服務器可以在localhost:9000上訪問。以上一節中的代理配置爲基礎,將fastcgi_pass指令替代proxy_pass指令,並將參數更改爲localhost:9000。在PHP中,SCRIPT_FILENAME參數用於確定腳本,QUERY_STRING參數用於傳遞請求參數。配置如下:

server {
    location / {
        fastcgi_pass localhost:8080;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param QUERY_STRING $query_string;
    }
    location ~ \.(png|jgp|gif)$ {
        root /user;
    }
}

這將設置一個服務器,通過FastCGI協議將靜態圖像請求外的所有請求路由到localhost:9000上運行的代理服務器!

基於名稱的虛擬服務器

Nginx首先確定哪個服務器應處理該請求,讓我們從一個簡單的配置開始,下面三個虛擬服務器都在監聽80端口,如下:

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

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

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

在上面配置當中,Nginx只檢測請求的標頭字段“Host”以確定將請求路由到哪個服務器。如果其值與任何服務器都不匹配,或者請求根本不包含此標頭字段,則Nginx會將請求路由到該端口的默認服務器。在上面的配置當中,默認服務器是第一個服務器,這是Nginx的標準默認行爲。也可以在listen指令中使用default_server參數設置哪個服務器應該是默認的,如下:

server {
    listen 80 default_server;
    server_name example.net www.example.net;
}

值得注意的是,default_server是偵聽端口的屬性,而不是服務器名稱的屬性。自0.8.21版本以來,default_server就可以使用了,但是在更早的版本前,應使用default參數

如何防止未定義的服務器名稱處理請求

如果不允許不帶“主機”標頭字段的請求,則可以定義僅丟棄請求的服務器:

server {
    listen 80;
    server_name "";
    return 444;
}

在這裏,服務器名稱設置爲空字符串,該字符串將匹配沒有“Host”頭字段的請求,並且返回特殊的Nginx的非標準代碼444,以關閉連接。自從版本0.8.48開始,這是服務器名稱的默認設置,因此server_name可以省略。

基於名稱和基於IP的混合虛擬服務器

下面來看一個更爲複雜的配置,其中一些虛擬服務器偵聽不同的地址:

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

server {
    listen 192.168.1.1:80;
    server_name example.net www.example.net;
}

server {
    listen 192.168.1.2:80;
    server_name example.com www.example.com;
}

在上面配置中,Nginx首先根據server塊的listen指令檢測請求的IP地址和端口。然後,它根據與IP地址和端口匹配的server塊的server_name指令檢測請求的“Host”標頭字段。如果找不到服務器名稱,則默認服務器將處理該請求。例如,192.168.1.1:80端口上接收到的請求將由192.168.1.1:80端口的默認服務器(即第一臺服務器)處理。

一個簡單的PHP站點配置

現在讓我們看一下Nginx處理一個典型的、簡單的PHP站點的請求,如下:

server {
    listen 80;
    server_name example.org www.example.org;
    root /data/www;
    location / {
        index index.html index.php;
    }
    
    location ~* \.(png|jpg|gif)$ {
        expires 30d;
    }
    
    location ~ \.php$ {
        fastcgi_pass localhost:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

無論列出的順序如何,Nginx都會首先搜索文字字符串所給出的最特定的前綴location。在上面的配置當中,唯一的前綴location是“/”,因爲它匹配任何請求,所以它將被用作最後的手段。然後Nginx按照配置文件中列出的順序檢查正則表達式給出的location。第一個匹配的表達式將停止搜索,Nginx將使用這個location。如果沒有正則表達式的匹配請求,則Nginx使用前面找到的最特定的前綴的location

注意,所有類型的location只檢測請求的Uri部分,沒有參數。這樣做是因爲查詢字符串中的參數可能以幾種方式給出,如下:

/index.php?user=john&page=1
/index.php?page=1&user=john

此外,任何人都可以在查詢字符串中請求任何東西:

/index.php?page=1&something+else&user=john

現在讓我們看一下上面配置中如何處理請求:

  • 請求logo.gif首先與前綴location“/”匹配,然後與正則表達式\.(png|jpg|gif)$匹配,因此,請求由後一個location匹配。使用僞指令root /data/www將請求映射到文件/data/www/logo.gif,然後將文件發送到客戶端
  • 請求index.php也首先與前綴location“/”匹配,然後與正則表達式\.php$匹配。因此,請求由後一個location匹配,並且請求被傳遞到了localhost:9000上偵聽的FastCGI服務器上。fastcgi_param指令將FastCGI參數SCRIPT_FILENAME設置爲/data/www/index.php,作爲FastCGI的服務器執行文件。變量document_root等同於root指令的值,變量fastcgi_script_name等同於請求的Uri,即index.php.
  • 請求about.html僅與前綴location“/”匹配,因此在該location進行處理。使用僞指令root /data/www將請求映射到文件/data/www/about.html,然後將文件發送到客戶端
  • 處理請求/更爲複雜,它僅與前綴location“/”匹配,因此由該location處理。然後index指令根據其參數root /data/www指令檢測文件的存在。如果文件/data/www/index.html不存在,但是文件/data/www/index.php存在,則該指令內部將重定向到index.php,並且Nginx將再次搜索location,就好像請求是由客戶端發送的一樣。如前所述,重定向的請求最終將由FastCGI服務器處理

在上面栗子當中,我們看到請求FastCGI服務器時,需要使用fastcgi_pass替代proxy_pass,其中uwsgiSCGImemcachedgRPC服務也分別使用uwsgi_passscgi_passmemcached_passgrpc_pass指令替代proxy_pass

發佈了158 篇原創文章 · 獲贊 115 · 訪問量 52萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章