Nginx 配置初步(上)
本節(jié)的目標(biāo)是了解 Nginx 的基本配置。關(guān)于 Nginx 的配置,主要是以下 5 個(gè)方面:
- 初始配置
- 基本語法
- http 服務(wù)配置
- tcp/udp
- 反向代理
每個(gè)部分其實(shí)有比較多的擴(kuò)展內(nèi)容,今天我們會(huì)講解初始配置以及配置文件的基本語法,后續(xù)的 http 服務(wù)配置、tcp/udp 配置和反向代理配置會(huì)在下一節(jié)中介紹。
1. 初始配置
在前面搭建好 Nginx 環(huán)境后,編譯的 Nginx 根路徑為 /root/nginx,那么對(duì)應(yīng)的配置文件為 /root/nginx/conf/nginx.conf ,直接用 cat 命令查看這里的配置文件內(nèi)容(刪除掉了原配置文件中的英文注釋,并對(duì)主要配置項(xiàng)增加中文注釋):
$ cat /root/nginx/conf/nginx.conf
# 啟動(dòng)的worker進(jìn)程數(shù)
worker_processes 1;
# 設(shè)置每個(gè)worker進(jìn)程的最大連接數(shù),它決定了Nginx的并發(fā)能力
events {
worker_connections 1024;
}
# http塊配置
http {
include mime.types;
default_type application/octet-stream;
# 注釋了日志格式的配置,使用默認(rèn)
...
sendfile on;
# 重要參數(shù),是一個(gè)請(qǐng)求完成之后還要保持連接多久,不是請(qǐng)求時(shí)間多久,
# 目的是保持長連接,減少創(chuàng)建連接過程給系統(tǒng)帶來的性能損耗
keepalive_timeout 65;
# server塊配置
server {
# 監(jiān)聽80端口
listen 80;
server_name localhost;
# 匹配url /,會(huì)在html目錄下,訪問index.html或index.htm文件
location / {
root html;
index index.html index.htm;
}
# 指定500 502 503 504出錯(cuò)的錯(cuò)誤頁面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
案例 1
修改 worker_processes 指令的參數(shù),比如改為 2,再啟動(dòng) Nginx,觀察 Nginx 的進(jìn)程,相比原來為 1 時(shí)的變化?
Nginx 默認(rèn)會(huì)啟動(dòng)一個(gè) Master 進(jìn)程(也可以無 Master 啟動(dòng)),可以把 Master 可以看做是包工頭,主要的工作就是招募工人(生成 Worker 進(jìn)程)并監(jiān)督他們干活。worker_processes 指令用于控制 Worker 進(jìn)程的數(shù)目,也就是所謂的工人數(shù)。我們用ps
可以看到,當(dāng) worker_processes 指令參數(shù)為 2 時(shí),worker 進(jìn)程會(huì)變成 2 個(gè)。通常情況下,我們會(huì)把 worker 進(jìn)程數(shù)會(huì)設(shè)置成系統(tǒng)的 cpu 核數(shù)(這里要看大家的機(jī)器配置而定),這樣 worker 進(jìn)程會(huì)分配到各個(gè) cpu 核心上去執(zhí)行請(qǐng)求處理,真正做到并行處理。
案例 2
我們請(qǐng)求在頁面上請(qǐng)求 80 端口,會(huì)出現(xiàn) Nginx 的默認(rèn)頁面,也就是 html 目錄下的那個(gè) index.html 頁面;另外直接訪問http://localhost/50x.html
時(shí)候,會(huì)出現(xiàn)針對(duì)狀態(tài)碼為 50x 異常頁面。接下來,我們添加一個(gè)簡單的請(qǐng)求訪問接口,模擬 500 異常,然后會(huì)將請(qǐng)求重定向到這個(gè)異常頁面。
在上述默認(rèn)配置的 server 塊中,我們添加一個(gè)新的匹配路徑,如下:
location /internal_error {
return 500;
}
return 指令一般用于對(duì)請(qǐng)求的客戶端直接返回響應(yīng)狀態(tài)碼。在該作用域內(nèi) return 指令之后的所有 Nginx 配置都是無效的。
可以使用在 server、location 以及 if 配置中。 除了支持跟狀態(tài)碼,還可以跟字符串或者 url 鏈接,比如寫成這樣的形式:
return 200 ‘hello, world’
這樣,使用 -s reload 熱加載 Nginx 后,我們直接在瀏覽器中敲 http://ip/internal_error
, 就可以看到50x的異常頁面了。
2. 基本語法
接下來,我將會(huì)介紹 Nginx 配置文件的通用語法,想深入學(xué)習(xí)一些指令的用法,可以多多上官網(wǎng)進(jìn)行查閱。
2.1 配置文件有指令和指令塊構(gòu)成
例如前面的默認(rèn) Nginx.conf 示例中,下面一行就是一個(gè)指令:
worker_processes 1;
而使用花括號(hào)包圍起來的就是一個(gè)指令塊,比如 http 指令塊:
http {
# 繼續(xù)指令或者指令塊,如http指令塊可以包括server指令塊
...
}
對(duì)于具體指令的參數(shù)、含義以及指令可以放入的指令塊等信息都可以在官方查到;
2.2 每個(gè)指令塊以分號(hào)(;)結(jié)尾
這個(gè)在默認(rèn)的 Nginx.conf 中都有體現(xiàn),如果是沒有分號(hào)結(jié)尾啟動(dòng) Nginx 或者執(zhí)行 -t 檢查時(shí)會(huì)報(bào)錯(cuò);
2.3 include 語句允許組合多個(gè)配置文件以提升可維護(hù)性
這個(gè)比較常用,因?yàn)樵诖笮途W(wǎng)站中使用 Nginx 監(jiān)聽的端口比較多,同時(shí)也會(huì)存在各種復(fù)雜的請(qǐng)求處理,如果都寫在同一個(gè) Nginx.conf中,會(huì)使得 Nginx 的配置文件變得異常復(fù)雜,難以維護(hù)。
此時(shí),比較好的方法是使用 include,對(duì)配置文件進(jìn)行按功能,或者按端口等任意的方式進(jìn)行劃分,將對(duì)應(yīng)的處理指令寫到另一個(gè)文件中,而主配置文件只要使用 include 指令包含該文件或者該文件所在的目錄即可,比如如下的寫法也是可以的:
include /etc/nginx/conf.d/*.conf;
2.4 使用 # 符號(hào)添加注釋
使用 # 符號(hào)給配置文件添加注釋可以提高配置文件的可讀性, 這個(gè)和代碼添加注釋是一個(gè)道理。
2.5 使用 $ 符號(hào)使用變量
Nginx 有內(nèi)置變量和自定義變量兩種。內(nèi)置變量往往代表著客戶端請(qǐng)求頭的內(nèi)容,如 $http_user_agent , ? $http_cookie 等。Nginx 支持的常用內(nèi)置變量有:
變量名 | 內(nèi)容 |
---|---|
$arg_name | 請(qǐng)求中的參數(shù)名,比如請(qǐng)求http://localhost?a=x&b=y, 則 $arg_a 表示的就是字符串’x’ |
$args | 請(qǐng)求中的參數(shù)值 |
$binary_remote_addr | 客戶端地址的二進(jìn)制形式, 固定長度為4個(gè)字節(jié) |
$body_bytes_sent | 傳輸給客戶端的字節(jié)數(shù),響應(yīng)頭不計(jì)算在內(nèi) |
$bytes_sent | 傳輸給客戶端的字節(jié)數(shù) |
$content_length | “Content-Length” 請(qǐng)求頭字段 |
$remote_addr | 客戶端地址 |
$remote_user | 用于 HTTP 基礎(chǔ)認(rèn)證服務(wù)的用戶名 |
$request_body | 客戶端的請(qǐng)求主體 |
$request_length | 請(qǐng)求的長度 (包括請(qǐng)求的地址, http請(qǐng)求頭和請(qǐng)求主體) |
$request_method | HTTP 請(qǐng)求方法 |
$request_time | 處理客戶端請(qǐng)求使用的時(shí)間,從讀取客戶端的第一個(gè)字節(jié)開始計(jì)時(shí) |
$request_uri | 這個(gè)變量等于包含一些客戶端請(qǐng)求參數(shù)的原始 URI ,它不包含主機(jī)名 |
$server_addr | 服務(wù)器端地址, 注意:為了避免訪問 linux 系統(tǒng)內(nèi)核,應(yīng)將ip地址提前設(shè)置在配置文件中 |
$status | HTTP 響應(yīng)代碼 |
$time_local | 服務(wù)器時(shí)間 |
$uri | 請(qǐng)求中的當(dāng)前 URI, 不帶請(qǐng)求參數(shù),且不包含主機(jī)名 |
2.6 案例:體驗(yàn) Nginx 的 include 指令和內(nèi)置變量
我們準(zhǔn)備三個(gè)配置文件,分別為主配置文件 Nginx.conf 和次配置文件 8080.conf、8088.conf,在 Nginx 根目錄下的 conf 目錄中,新建 conf.d 目錄,然后將 8080.conf、8088.conf 兩個(gè)文件放到此處。通過cat
命令查看三個(gè)配置文件內(nèi)容,如下:
$ cat 8080.conf
server {
listen 8080;
server_name localhost;
location / {
default_type text/html;
return 200 'hello, 8080\n';
}
}
$ cat 8088.conf
server {
listen 8088;
server_name localhost;
location / {
default_type text/html;
return 200 'hello, 8088\n';
}
}
$ cat nginx.conf
...
http: {
...
server: {
...
# 前面的不變化,但是我們需要變化兩個(gè)地方
location / {
default_type text/html;
# 自定義變量
set $limit_rate 10k;
return 200 '
arg_a: $arg_a, arg_b: $arg_b, args: $args
connection: $connection, connection_requests: $connection_requests
cookie_a: $cookie_a
uri: $uri, document_uri: $document_uri, request_uri: $request_uri
request: $request , request_id: $request_id
server: $server_addr, $server_name, http_host: $http_host,
limit_rate: $limit_rate, hostname: $hostname,
content_length: $content_length
status: $status, body_bytes_sent: $body_bytes_sent, bytes_sent: $bytes_sent
time: $request_time, $msec, $time_iso8601, $time_local\n';
}
}
...
# 包含其他配置文件,包括了8080.conf和8088.conf
include conf.d/*.conf;
}
準(zhǔn)備好這三個(gè)三個(gè)配置文件后,直接啟動(dòng) Nginx,可以發(fā)現(xiàn) Nginx 服務(wù)分別監(jiān)聽了 80、8080 和 8088 端口。這說明 include 指令生效了,8080.conf、8088.conf 配置被包含進(jìn)來了。
當(dāng)然我們也可以去掉這個(gè) include 指令再看看 Nginx 會(huì)不會(huì)監(jiān)聽 8080 和 8088 端口,來個(gè)終極確認(rèn)。最后我們?cè)诜?wù)器上使用 curl 命令來模擬 Http 請(qǐng)求訪問服務(wù)器的 8080 和 8088 端口,看是否會(huì)有對(duì)應(yīng)的相應(yīng)文本輸出。最后請(qǐng)求 80 端口,帶上相應(yīng)的參數(shù),具體操作以及打印結(jié)果如下:
[root@server ~]# cd /root/nginx/sbin
# 如果Nginx服務(wù)已經(jīng)啟動(dòng),使用 -s reload 重新加載配置,否則直接使用 ./nginx 啟動(dòng)Nginx服務(wù)
[root@server sbin]# ./nginx -s reload
[root@server sbin]# curl http://localhost:8080
hello, 8080
[root@server sbin]# curl http://localhost:8088
hello, 8088
# 一定要使用雙引號(hào)包含整個(gè)URL,不然后面的b參數(shù)會(huì)被漏掉
[root@server sbin]# curl "http://localhost:80?a=xxxx&b=yyyy"
arg_a: xxxx, arg_b: yyyy, args: a=xxxx&b=yyyy
connection: 27, connection_requests: 1
cookie_a:
uri: /, document_uri: /, request_uri: /?a=xxxx&b=yyyy
request: GET /?a=xxxx&b=yyyy HTTP/1.1 , request_id: 3784dd519727856c17b38e2ec9f2c8a1
server: 127.0.0.1, , http_host: localhost,
limit_rate: 10240, hostname: server,
content_length:
status: 200, body_bytes_sent: 0, bytes_sent: 0
time: 0.000, 1581417768.174, 2020-02-11T18:42:48+08:00, 11/Feb/2020:18:42:48 +0800
3. 小結(jié)
今天我們簡單了解了下 Nginx 的配置文件以及相應(yīng)的語法規(guī)則。但是我們僅僅簡單介紹了 Nginx 一些簡單的語法并完成了幾個(gè)簡單的案例,接下來我們將簡單學(xué)習(xí) Nginx 的 Http 配置以及反向代理等常用配置。