nginx 入門指導

stu_wei發表於2019-01-02

本篇翻譯原文地址

初學者指導

  • 啟動、停止和過載配置
  • 配置檔案的結構
  • 提供靜態檔案下載服務
  • 搭建一個簡單的代理伺服器
  • 搭建 FastCGI 代理

這篇指導簡單介紹 nginx 並且描述 nginx 可以做的一些簡單的任務。現在假定 nginx 已經被安裝到讀者的機器上,如果還沒安裝的話,請參考安裝頁。這篇指導描述如何啟動和停止 nginx、過載它的配置、解釋配置檔案結構、描述如何設定 nginx 以用來作為靜態檔案伺服器、如何配置 nginx 來使它成為一個代理伺服器、如何將它與一個 FastCGI 應用連線。

nginx 有一個主程式和多個工作程式(worker process)。主程式的主要目的是讀取和評估配置,並且維護工作程式。實際上,是工作程式來處理請求。nginx 使用以事件為基礎的模型和依賴作業系統的機制(OS-dependent mechanisms)來在工作程式之間高效地分發請求。工作程式的數量定義在配置檔案中,數量可以是一個固定值(在配置檔案中給定)或者根據可用的 CPU 核心的數量自動調整(詳參工作程式)(譯者注:也就是說,你可以在配置檔案中設定一個固定值,也可以不設定,不設定的話,nginx 就會根據 CPU 的核心的數量計算一個合理的數值)。

nginx 和它的模組的工作方式取決於配置檔案。預設的,配置檔案的檔名是 nginx.conf,被放置在 /usr/local/nginx/conf、/etc/nginx、或者 /usr/local/etc/nginx 目錄下。

啟動、停止和過載配置

執行可執行檔案(the executable)以啟動 nginx。一旦 nginx 被啟動,可以通過呼叫那個可執行檔案並附帶 -s 引數來控制它。使用下面的語法:

nginx -s signal

signal 可以是下列中的一個

  • stop — 快速停止
  • quit — 優雅的(graceful)停止
  • reload — 過載配置
  • reopen — 重新開啟日誌檔案

例如,停止 nginx 並且等待工作程式完成處理當前的請求,執行下面的命令:

nginx -s quit

這個命令應該被啟動 nginx 的使用者執行。

配置檔案的改動不會立即被應用,你可以向 nginx 傳送過載命令或者重啟。請執行下面命令以過載配置檔案:

nginx -s reload

一旦主程式收到過載配置的訊號,它會檢查新配置的語法的有效性,並且嘗試應用新的配置。如果成功了,主程式就會開啟新的工作程式,並且傳送訊號給老的工作程式,請求它們關閉。否則(譯者注:新配置語法存在錯誤,或應用不成功),主程式回滾改變,並且繼續和老的工作程式工作。老工作程式收到停止的命令後,停止接受新的連線並且繼續處理當前請求,直到所有請求被處理。在這之後,老工作程式退出。

訊號也可以通過 unix 工具(例如 kill 工具)被髮送給 nginx。這種情況下,訊號被直接傳送給指定程式 id 的程式。nginx 主程式的程式號被寫入到 /usr/local/nginx/logs 或者 /var/run 下的 nginx.pid 檔案(預設情況下)。比如,如果主程式的程式 id 是 1628,那麼想通過發訊號的方式讓 nginx 優雅地(graceful)停止,可以執行:

kill -s QUIT 1628

為了得到正在執行的 nginx 程式的列表(list),可以使用 ps 工具。比如,通過以下方式:

ps -ax | grep nginx

想知道更多關於傳送訊號給 nginx 的資訊,參閱控制 nginx

配置檔案的結構

配置檔案裡宣告瞭各種指令,用來控制 nginx 的各個模組。指令分為兩種:簡單指令和塊指令。簡單指令包含命令名和引數,並用空格隔開,以分號結束。塊指令的結構和簡單指令一樣,但是塊指令的結尾不是分號,而是一個用括號包圍起來的附加指令(additional instruction)的集合。如果一個塊指令的括號裡可以有其他指令,那麼這種塊指令叫做上下文(context)(例如:events, http, server, 和 location)。

配置檔案中,在任何上下文之外的指令被認為處於主上下文中(main context)。events 和 http 指令被放在主上下文中,server 被放在 http 上下文中,location 被放在 server 上下文中。

配置檔案中的註釋,寫在 # 之後。

提供靜態檔案下載服務

web 伺服器的一個重要任務就是提供靜態檔案下載(比如圖片和靜態 HTML 頁面)。你可以實現這樣一個例子:提供在不同目錄下的靜態檔案的下載服務(實際情況也取決於需求):/data/www(可能用來放 HTML 檔案)和 /data/image(放圖片)。這需要編輯配置檔案,在 http 塊中設定一個 server 塊,並且包含兩個 location 塊:

http {
  server {
  }
}

通常情況下,配置檔案包含若干 server 塊(區別在於監聽的埠,和 server 的名字)。一旦 nginx 決定哪個 server 程式處理一個請求,它就會比較宣告在請求頭裡的 URI 和 server 塊中 location 指令的引數。

新增下列 location 塊到 server 塊中:

location / {
  root /data/www;
}

這個 location 塊宣告 “/” 字首,和請求中 URI 比較。對於匹配到的請求,URI 將被新增到 root 指令中宣告的路徑之後,也就是 /data/www,以此來組成所請求檔案在本地檔案系統中的路徑。如果有多個匹配成功的 location 塊,nginx 將會選擇最長字首的那一個。上面的 location 塊提供了一個最短的字首,長度為一。只有當其他 location 塊都匹配失敗,這個塊才會被使用。

接下來,新增第二個 location 塊:

location /images/ {
  root /data;
}

以 /images/ 開頭的請求會匹配成功( “/” 也會匹配成功,但是字首較短)。

現在配置檔案中的 server 塊,應該是下面這樣子:

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

這已經是一個監聽在 80 埠的伺服器的有效配置,並且可以在本地通過 http://localhost/ 訪問到。作為以 /images/ 為開頭的 URI 的請求的響應,伺服器將會從 /data/images/ 目錄下傳送檔案。例如,對於這個請求:http://localhost/images/example.png,nginx 將會響應 /data/images/example.png。如果這個檔案不存在,nginx 將會響應 404 錯誤。URI 不以 /images/ 開頭的請求將被對映到 /data/www/ 目錄。例如,請求 http://localhost/some/example.html,nginx 將響應 /data/www/some/example.html 檔案。

為了應用新配置,如果 nginx 沒被啟動的話,就啟動 nginx,否則向 nginx 主程式傳送過載命令:

nginx -s reload

也許某些東西不按預期執行,你可以嘗試在 access.log 和 error.log 裡找到原因(這兩個檔案在 /usr/local/nginx/logs 或者 /var/log/nginx 目錄下)。

搭建一個簡單的代理伺服器

nginx 的一個被頻繁使用的功能就是搭建一個代理伺服器(接收請求,並把這個請求傳給被代理的伺服器,然後收到被代理伺服器的響應,最後返回給客戶端)。

我們將配置一個基礎的代理伺服器,它提供對圖片檔案(譯者注:此處存疑,原文是“images with files”)的下載並且把其他請求傳送給被代理伺服器。這個例子中,兩個伺服器被定義在一個單獨的 nginx 例項中。

首先,再新增一個 server 塊到配置檔案,以定義被代理的伺服器:

server {
  listen 8080;
  root /data/up1;

  location / {
  }
}

這是一個簡單的伺服器,監聽在 8080 埠(之前,監聽指令未被宣告,nginx 會預設監聽 80 埠)。它將對映所有 /data/up1 請求到本地檔案系統。建立這個目錄,並且把 index.html 放進去。注意,root 指令放到 server 上下文中。當被選中作為處理請求的 location 塊沒有自己的 root 指令時,使用這樣的 root 指令。

接下來,使用前面部分的 server 配置,做出一點修改,使它成為代理伺服器。在第一個 location 塊中,新增 proxy_pass 指令,並附帶生被代理伺服器的協議、名稱(在我們的例子中,是 http://localhost:8080):

server {
  location / {
    proxy_pass http://localhost:8080;
  }
  location /images/ {
    root /data;
  }
}

然後我們修改第二個 location 塊,它當前對映所有的以 /images/ 為字首的請求到 /data/images 目錄下的檔案。修改之後,使它匹配特定副檔名的圖片請求。修改後的 location 塊如下:

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

這個引數是一個正規表示式,匹配所有以 .gif、.jpg 和 .png 結尾的 URI。正規表示式必須在前面放一個符號:~。對應的請求會被對映到 /data/images 目錄下。

當 nginx 選擇哪個 location 塊來處理一個請求時,首先檢查宣告瞭字首了的 location 指令,記住帶有最長字首的 location,之後檢查正規表示式。如果用正規表示式匹配到,nginx 就會選擇這個 location,否則選擇之前記住的那個。

現在的代理伺服器的配置是這樣的:

server {
  location / {
    proxy_pass http://localhost:8080/;
  }
  location ~ \.(gif|jpg|png)$ {
    root /data/images;
  }
}

這個伺服器會過濾所有以 gif、jpg 或者 png 為結尾的請求,並且把他們對映到 /data/images 目錄下(通過新增 URI 到 root 指令的引數後面)並且把所有其他的請求傳遞給之前配置的被代理的伺服器。

為了應用新配置,傳送過載訊號給 nginx(像之前部分描述的那樣)。

還有更多配置代理連線的指令。

搭建一個代理 FastCGI

nginx 可以用來 route 一個到 FastCGI 伺服器的請求,不管這個伺服器上執行的程式是哪個框架、何種語言(例如 PHP)。最基礎的使 nginx 和一個 FastCGI 伺服器工作的配置包含使用 fastcgi_pass 指令,而不是 proxy_pass 指令。fastcgi_param 指令可以用來設定傳給 FastCGI 伺服器的引數。假定 FastCGI 伺服器可以在 localhost:9000 訪問到。用上面的代理部分的配置作為基礎,用 fastcgi_pass 代替 proxy_pass 指令,然後改變它的引數為 localhost:9000。在 PHP 中,SCRIPT_FILENANME 引數被用來決定指令碼名稱,QUERY_STRING 引數被用來傳遞請求引數。當前的配置是這樣的:

server {
  location / {
    fastcgi_pass  localhost:9000;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param QUERY_STRING    $query_string;
  }
  location ~ \.(gif|jpg|png)$ {
    root /data/images;
  }
}

這樣就搭建了一個伺服器,它可以通過 FastCGI 協議 route 所有的請求(除了靜態圖片)到執行在 localhost:9000 的被代理的伺服器。

相關文章