架構師細說NGINX的配置及優化

java隋七哥發表於2018-08-14

最近感覺很多東西在運用到一定的程度之後,會發現原來是自己瞭解到的不夠。一方面限於實際運用到的不多,一方面可能是因為一開始沒有進行全面認識。遂這裡蒐集整理了一番NGINX。

一、nginx啟動和關閉

centos平臺,原始碼安裝的

/usr/local/nginx/nginx # 啟動

/usr/local/nginx/nginx -s reload # 平滑重啟

/usr/local/nginx/nginx.conf # 配置檔案

mac平臺,使用brew安裝的

/usr/local/bin/nginx # 啟動

/usr/local/bin/nginx -s reload # 平滑重啟

/usr/local/etc/nginx/nginx.cnf # 配置檔案

在此順便給大家推薦一個Java架構方面的交流學習群:725633148,裡面會分享一些資深架構師錄製的視訊錄影:有Spring,MyBatis,Netty原始碼分析,高併發、高效能、分散式、微服務架構的原理,JVM效能優化這些成為架構師必備的知識體系。相信對於已經工作和遇到技術瓶頸的同學,在這個群裡會有你需要的內容。有需要的同學請抓緊時間加入進來。

二、nginx.conf 配置檔案詳解

其實,對比,apache 的配置檔案,它的相對比較清晰和簡單,之前覺得很難,現在沉下心來想想,其實很簡單。大致的分塊下,基本就分為以下幾塊:

main

events {

….

}

http {

….

upstream myproject {

…..

}

server {

….

location {

….

}

}

server {

….

location {

….

}

}

….

}

以上我們可以看出,nginx配置檔案主要分為六個區域:

1、main (全域性設定)

2、events (nginx工作模式)

3、http (http設定)

4、sever (主機設定)

5、location (URL匹配)

6、upstream (負載均衡伺服器設定)

2.1 main模組

下面是一個main區域,他是一個全域性的設定

user nobody nobody; # 指定 Nginx Worker 程式執行使用者以及使用者組,預設由 nobody 賬號執行

worker_processes 2; # 指定 Nginx 要開啟的子程式數

error_log /usr/local/var/log/nginx/error.log notice; # 定義全域性錯誤日誌檔案

pid /usr/local/var/run/nginx/nginx.pid; # 指定程式 id 的儲存檔案位置

worker_rlimit_nofile 1024; # 指定一個 nginx 程式可以開啟的最多檔案描述符數目,如果設定 65535,需要使用命令 “ulimit -n 65535” 來設定

user 來指定 Nginx Worker 程式執行使用者以及使用者組,預設由 nobody 賬號執行。

worker_processes 來指定了 Nginx 要開啟的子程式數。每個 Nginx 程式平均耗費 10M~12M 記憶體。根據經驗,一般指定 1 個程式就足夠了,如果是多核 CPU,建議指定和 CPU 的數量一樣的程式數即可。我這裡寫 2,那麼就會開啟 2 個子程式,總共 3 個程式。

error_log 用來定義全域性錯誤日誌檔案。日誌輸出級別有 debug、info、notice、warn、error、crit 可供選擇,其中,debug 輸出日誌最為最詳細,而 crit 輸出日誌最少。

pid 用來指定程式id的儲存檔案位置。

worker_rlimit_nofile 用於指定一個 nginx 程式可以開啟的最多檔案描述符數目,這裡是 65535,需要使用命令 “ulimit -n 65535” 來設定。

2.2 events 模組

events 模組來用指定 nginx 的工作模式和工作模式及連線數上限,一般是這樣

events {

use kqueue; # mac 平臺,指定 Nginx 的工作模式

worker_connections 1024; # 定義 Nginx 每個程式的最大連線數,即接收前端的最大請求數,預設是 1024

}

use 用來指定 Nginx 的工作模式。Nginx 支援的工作模式有 select、poll、kqueue、epoll、rtsig 和 /dev/poll。其中 select 和 poll 都是標準的工作模式,kqueue 和 epoll 是高效的工作模式,不同的是 epoll 用在 Linux 平臺上,而 kqueue 用在 BSD 系統中,因為 Mac 基於 BSD ,所以 Mac 也得用這個模式,對於 Linux 系統,epoll 工作模式是首選。

worker_connections 用於定義Nginx每個程式的最大連線數,即接收前端的最大請求數,預設是1024。最大客戶端連線數由worker_processes 和 worker_connections 決定,即 Max_clients = worker_processes * worker_connections,在作為反向代理時,Max_clients 變為:Max_clients = worker_processes * worker_connections/4。

程式的最大連線數受 Linux 系統程式的最大開啟檔案數限制,在執行作業系統命令 “ulimit -n 65536” 後 worker_connections 的設定才能生效。

2.3 http 模組

http 模組可以說是最核心的模組了,它負責 HTTP 伺服器相關屬性的配置,它裡面的 server 和 upstream 子模組,至關重要,等到反向代理和負載均衡以及虛擬目錄等會仔細說。

http{

include mime.types; # 用來設定檔案的 mime 型別,來告訴 nginx 來識別檔案型別

default_type application/octet-stream; # 設定了預設的型別為二進位制流,也就是當檔案型別未定義時使用這種方式

log_format main `$remote_addr – $remote_user [$time_local] “$request” `

`$status $body_bytes_sent “$http_referer” `

`”$http_user_agent” “$http_x_forwarded_for”`;

# log_format 設定日誌的格式,和記錄哪些引數,這裡設定為 main 型別的日誌

access_log /usr/local/var/log/nginx/access.log main;

# access_log 記錄每次的訪問日誌的檔案地址,後面的 main 是日誌的格式樣式,對應於 log_format 的 main

sendfile on; # 開啟高效檔案傳輸模式

tcp_nopush on; # 設定為 on 用於防止網路阻塞

tcp_nodelay on; # 設定為 on 用於防止網路阻塞

keepalive_timeout 10; # 設定客戶端連線保持活動的超時時間。在超過這個時間之後,伺服器會關閉該連線

#gzip on;

upstream myproject {

…..

}

server {

….

}

}

下面詳細介紹下這段程式碼中每個配置選項的含義。

include 用來設定檔案的 mime 型別,型別在配置檔案目錄下的 mime.type 檔案定義,來告訴 nginx 來識別檔案型別。

default_type 設定了預設的型別為二進位制流,也就是當檔案型別未定義時使用這種方式,例如在沒有配置 asp 的 locate 環境時,Nginx 是不予解析的,此時,用瀏覽器訪問 asp 檔案就會出現下載了。

log_format 用於設定日誌的格式(格式設定可參照 Nginx日誌格式設定),和記錄哪些引數,這裡設定為 main,剛好用於 access_log 來記錄這種型別。

main 的型別日誌如下:也可以增刪部分引數。

127.0.0.1 – – [21/Apr/2015:18:09:54 +0800] “GET /index.php HTTP/1.1” 200 87151 “-” “Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.76 Safari/537.36”

access_log 用來記錄每次的訪問日誌的檔案地址,後面的 main 是日誌的格式樣式,對應於 log_format 的 main。

sendfile 引數用於開啟高效檔案傳輸模式。將 tcp_nopush 和 tcp_nodelay 兩個指令設定為 on 用於防止網路阻塞。

keepalive_timeout 設定客戶端連線保持活動的超時時間。在超過這個時間之後,伺服器會關閉該連線。

2.4 server 模組

sever 模組是 http 的子模組,它用來定一個虛擬主機。

我們來看一個簡單的 server 是如何做的?

server { # 標誌定義虛擬主機開始

listen 8080; # 指定虛擬主機的服務埠

server_name localhost 192.168.12.10 www.yangyi.com; # 指定IP地址或者域名,多個域名之間用空格分開

# 全域性定義,如果都是這一個目錄,這樣定義最簡單。

root /Users/yangyi/www;

# root 表示在這整個 server 虛擬主機內,全部的 root web 根目錄。注意要和 locate {} 下面定義的區分開來

index index.php index.html index.htm;

# index 全域性定義訪問的預設首頁地址。注意要和 locate {} 下面定義的區分開來

charset utf-8; # 設定網頁的預設編碼格式

access_log usr/local/var/log/host.access.log main;

# access_log 指定此虛擬主機的訪問日誌存放路徑,最後的 main 用於指定訪問日誌的輸出格式

error_log usr/local/var/log/host.error.log error;

….

}

server 標誌定義虛擬主機開始。

listen 用於指定虛擬主機的服務埠。

server_name 用來指定IP地址或者域名,多個域名之間用空格分開。

root 表示在這整個 server 虛擬主機內,全部的 root web 根目錄。注意要和 locate {} 下面定義的區分開來。

index 全域性定義訪問的預設首頁地址。注意要和 locate {} 下面定義的區分開來。

charset 用於設定網頁的預設編碼格式。

access_log 用來指定此虛擬主機的訪問日誌存放路徑,最後的 main 用於指定訪問日誌的輸出格式。

2.5 location 模組

location 模組是 nginx 中用的最多的,也是最重要的模組了,什麼負載均衡啊、反向代理啊、虛擬域名啊都與它相關。慢慢來講:

location 根據它字面意思就知道是來定位的,定位 URL,解析 URL,所以,它也提供了強大的正則匹配功能,也支援條件判斷匹配,使用者可以通過 location 指令實現 Nginx 對動、靜態網頁進行過濾處理。像我們的 php 環境搭建就是用到了它。

我們先來看這個,設定預設首頁和虛擬機器目錄。

location / { # 表示匹配訪問根目錄

root /Users/yangyi/www; # 指定訪問根目錄時,虛擬主機的 web 目錄

index index.php index.html index.htm; # 設定我們只輸入域名後訪問的預設首頁地址

}

location / 表示匹配訪問根目錄。

root 指令用於指定訪問根目錄時,虛擬主機的web目錄,這個目錄可以是相對路徑(相對路徑是相對於nginx的安裝目錄)。也可以是絕對路徑。

index 用於設定我們只輸入域名後訪問的預設首頁地址,有個先後順序:index.php index.html index.htm,如果沒有開啟目錄瀏覽許可權,又找不到這些預設首頁,就會報403錯誤。

location 還有一種方式就是正則匹配,開啟正則匹配這樣:location ~。後面加個~。

下面這個例子是運用正則匹配來連結php。我們之前搭建環境也是這樣做:

location ~ .php$ {

root /Users/yangyi/www;

fastcgi_pass 127.0.0.1:9000; # 連結的是 php-fpm 的地址

fastcgi_index index.php;

include fastcgi.conf;

}

.php$ 熟悉正則的我們直到,這是匹配 .php 結尾的 URL,用來解析 php 檔案。裡面的 root 也是一樣,用來表示虛擬主機的根目錄。

fast_pass 連結的是 php-fpm 的地址。

2.6 upstream 模組

upstream 模組負責負載均衡模組,通過一個簡單的排程演算法來實現客戶端 IP 到後端伺服器的負載均衡

upstream iyangyi.com{

ip_hash;

server 192.168.12.1:80;

server 192.168.12.2:80 down;

server 192.168.12.3:8080 max_fails=3 fail_timeout=20s;

server 192.168.12.4:8080;

}

在上面的例子中,通過 upstream 指令指定了一個負載均衡器的名稱 iyangyi.com。這個名稱可以任意指定,在後面需要的地方直接呼叫即可。

裡面是 ip_hash 這是其中的一種負載均衡排程演算法,下面會著重介紹。緊接著就是各種伺服器了。用 server 關鍵字表識,後面接 ip。

Nginx 的負載均衡模組目前支援 4 種排程演算法 :

1)weight 輪詢(預設)

每個請求按時間順序逐一分配到不同的後端伺服器,如果後端某臺伺服器當機,故障系統被自動剔除,使使用者訪問不受影響。weight。指定輪詢權值,weight值越大,分配到的訪問機率越高,主要用於後端每個伺服器效能不均的情況下。

2)ip_hash

每個請求按訪問IP的hash結果分配,這樣來自同一個IP的訪客固定訪問一個後端伺服器,有效解決了動態網頁存在的session共享問題。

3)fair

比上面兩個更加智慧的負載均衡演算法。此種演算法可以依據頁面大小和載入時間長短智慧地進行負載均衡,也就是根據後端伺服器的響應時間來分配請求,響應時間短的優先分配。Nginx本身是不支援fair的,如果需要使用這種排程演算法,必須下載Nginx的upstream_fair模組。

4)url_hash

按訪問url的hash結果來分配請求,使每個url定向到同一個後端伺服器,可以進一步提高後端快取伺服器的效率。Nginx本身是不支援url_hash的,如果需要使用這種排程演算法,必須安裝Nginx 的hash軟體包。

在 HTTP Upstream 模組中,可以通過server指令指定後端伺服器的IP地址和埠,同時還可以設定每個後端伺服器在負載均衡排程中的狀態。常用的狀態有:

down,表示當前的server暫時不參與負載均衡。

backup,預留的備份機器。當其他所有的非backup機器出現故障或者忙的時候,才會請求backup機器,因此這臺機器的壓力最輕。

max_fails,允許請求失敗的次數,預設為1。當超過最大次數時,返回proxy_next_upstream 模組定義的錯誤。

fail_timeout,在經歷了max_fails次失敗後,暫停服務的時間。max_fails可以和fail_timeout一起使用。

注意 當負載排程演算法為ip_hash時,後端伺服器在負載均衡排程中的狀態不能是weight和backup。


相關文章