1. Nginx編譯安裝
- nginx-1.18.0.tar.gz
#!/bin/bash
GREEN='echo -e \033[1;32m'
RED='echo -e \033[1;31m'
END='\033[0m'
DIR='nginx-1.18.0'
PKG=$DIR.tar.gz
#1. download src code
wget -qP /usr/local/src http://nginx.org/download/nginx-1.18.0.tar.gz
#2. create nginx user
id nginx && $REDnginx already exists!$END &> /dev/null || useradd -s /sbin/nologin -r nginx
#3. install dependencies
yum -y install gcc pcre-devel openssl-devel zlib-devel &> /dev/null
#4. uncompress nginx.tar.gz
cd /usr/local/src
tar -xf $PKG
#5. compile nginx
cd $DIR
./configure --prefix=/apps/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module
#6. make && make install
make && make install
#7. modify access
chown -R nginx.nginx /apps/nginx
#8. create soft-link
ln -s /apps/nginx/sbin/* /usr/sbin
#9. backup conf
cp /apps/nginx/conf/nginx.conf{,.bak}
#10. setup pid folder
mkdir /apps/nginx/run
sed -ri 's@^#(pid).*@\1 /apps/nginx/run/nginx.pid;@' /apps/nginx/conf/nginx.conf
#11. create service unit
cat > /lib/systemd/system/nginx.service <<EOF
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/apps/nginx/run/nginx.pid
ExecStart=/apps/nginx/sbin/nginx -c /apps/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
EOF
#12. reload daemon & start nginx
systemctl daemon-reload
systemctl enable --now nginx.service
2. Nginx核心配置
2.1 配置文件說(shuō)明
- 主配置文件結(jié)構(gòu): 四部分
# main block: 主配置項(xiàng), 即全局配置端, 對(duì)http, mail都有效
#事件驅(qū)動(dòng)相關(guān)的配置
event {
}
# http/https 協(xié)議相關(guān)配置端
http {
}
# 默認(rèn)配置文件不包括下面兩個(gè)語(yǔ)句塊
# mail 協(xié)議相關(guān)配置段
mail {
}
# stream 服務(wù)器相關(guān)配置段
stream {
}
2.2 全局配置
- 全局配置段常見的配置指令分類
正常運(yùn)行必備的配置
優(yōu)化性能相關(guān)配置
用于調(diào)式及定位問題相關(guān)的配置
事件驅(qū)動(dòng)相關(guān)的配置
- 全局配置說(shuō)明
user nobody [nobody];
# 啟動(dòng)nginx工作進(jìn)程的用戶和組, 如果編譯時(shí)指定了運(yùn)行用戶, 那么這里可以注釋掉, 或者改成和編譯選項(xiàng)一致
worker_processes [number | auto];
# 啟動(dòng)nginx worker進(jìn)程的數(shù)量, 一般設(shè)為和cpu核心數(shù)相同, 充分利用cpu, 避免進(jìn)程間競(jìng)爭(zhēng)資源
# 同時(shí)并且配合worker_cpu_affinity指令, 把工作進(jìn)程綁定到指定的cpu核心上, 避免進(jìn)程在不同的cpu核心來(lái)回跳轉(zhuǎn), 導(dǎo)致需要重新加載進(jìn)程信息到新的cpu緩存, 帶來(lái)性能損失
# 可以手動(dòng)指定開啟幾個(gè)工作進(jìn)程, 也可使用auto, 自動(dòng)按照cpu核心數(shù)去開啟對(duì)應(yīng)數(shù)目的worker進(jìn)程
worker_cpu_affinity 00000001 00000010 00000100 00001000 ...;
# 將nginx工作進(jìn)程綁定到指定的cpu核心, 默認(rèn)nginx是不進(jìn)行進(jìn)程綁定的, 綁定并不是意味著當(dāng)前nignx進(jìn)程獨(dú)占一核心cpu, 別的進(jìn)程也可以跑在這核cpu, 只是nginx該worker進(jìn)程必須跑在該cpu
# 但是可以保證此進(jìn)程不會(huì)允許在其他cpu核心上, 這就極大減少了nginx的工作進(jìn)程在不同的cpu核心上的來(lái)回跳轉(zhuǎn), 減少了cpu對(duì)進(jìn)程的資源分配和回收以及內(nèi)存管理等, 因此可以有效地提升nginx服務(wù)器的性能
示例:
work_processes 4; # 開啟4個(gè)worker進(jìn)程
work_cpu_affinity 00000010 00001000 0010000 10000000; # 進(jìn)程和第1,3,5,7核cpu進(jìn)行綁定
[19:51:50 root@nginx ~]#ps axo pid,cmd,psr | grep nginx
927 nginx: master process /apps 0
928 nginx: worker process 1 # 該進(jìn)程跑在1號(hào)cpu
929 nginx: worker process 3
930 nginx: worker process 5
931 nginx: worker process 7
1434 vim /apps/nginx/conf/nginx. 0
1451 grep --color=auto nginx 0
# 可以配合watch命令, 對(duì)運(yùn)行狀況進(jìn)行監(jiān)控
[19:54:57 root@nginx ~]#watch -n 0.5 'ps axo pid,cmd,psr | grep nginx'
daemon off;
# 讓nginx以前臺(tái)運(yùn)行, 用于測(cè)試, docker等環(huán)境
master_process off | on; # 是否開啟nginx的master-worker工作模式, 默認(rèn)為on, off為只用master相應(yīng)請(qǐng)求, 僅用于開發(fā)調(diào)試場(chǎng)景
error_log logs/error.log notice;
# 錯(cuò)誤日志記錄配置, 語(yǔ)法: error_log /PATH/TO/FILE [debug | info | notice | warn | error | crit | alert | emerg]
pid logs/nginx.pid;
# pid文件保存路徑, 這里的pid是master的pid
worker_priority 0;
# 工作進(jìn)程優(yōu)先級(jí), 默認(rèn)0, (-20 ~ 19), nice優(yōu)先級(jí)
示例:
[20:05:48 root@nginx ~]#ps axo pid,cmd,ni | grep nginx
927 nginx: master process /apps 0
928 nginx: worker process 0
1434 vim /apps/nginx/conf/nginx. 0
1595 grep --color=auto nginx 0
worker_rlimit_nofile 65536;
# 所有worker進(jìn)程能打開的文件數(shù)量上限, 包括: nginx的所有連接(例如與后端服務(wù)器的連接等), 而不僅僅是與客戶的的連接
# 另一個(gè)考慮因素是實(shí)際的并發(fā)連接數(shù)不能超過系統(tǒng)級(jí)別的最大文件打開文件數(shù)的限制. 最好與ulimit -n(單個(gè)進(jìn)程能接受的最大連接數(shù)×worker進(jìn)程總數(shù))的值保持一致
示例:
worker_rlimit_nofile 100000;
vim /etc/security/limits.conf # 修改后, 重啟服務(wù)器生效
* - nproc 100000
* - nofile 100000
events {
worker_connections 1024; # 設(shè)置單個(gè)工作進(jìn)程的最大并發(fā)連接數(shù), 也要調(diào)大
use epoll; # 使用epoll事件驅(qū)動(dòng), 默認(rèn)就是epoll, 需要放在events語(yǔ)句塊, 否則語(yǔ)法報(bào)錯(cuò)
accept_mutex_on; # on為同一時(shí)刻一個(gè)請(qǐng)求輪流由worker進(jìn)程處理, 防止同時(shí)喚醒所有worker進(jìn)程, 避免多個(gè)睡眠被喚醒的設(shè)置; 默認(rèn)為off, 新請(qǐng)求會(huì)喚醒所有worker進(jìn)程, 此過程也成為'驚群', 因此nginx剛安裝完要進(jìn)行適當(dāng)?shù)膬?yōu)化, 建議設(shè)置為on
multi_accept_on; # on時(shí)nginx服務(wù)器的每個(gè)工作進(jìn)程可以同時(shí)接受多個(gè)新的網(wǎng)絡(luò)連接, 此指令默認(rèn)為off, 即默認(rèn)一個(gè)工作進(jìn)程只能一次接受一個(gè)新的網(wǎng)絡(luò)連接, 打開后能同時(shí)接受多個(gè), 建議設(shè)置為on
}
- 優(yōu)化項(xiàng)總結(jié)
worker_processes [number | auto];
worker_cpu_affinity 00000001 00000010 00000100 00001000 ...;
worker_priority 0;
worker_rlimit_nofile 65536;
vim /etc/security/limits.conf
* - nproc 100000
* - nofile 100000
event{
worker_connections 1024;
use epoll;
accept_mutex_on;
multi_accept_on;
}
需要重啟nginx服務(wù)
systemctl restart nginx
2.3 http配置塊
- http協(xié)議相關(guān)的配置結(jié)構(gòu)
http {
... # 各server虛擬主機(jī)的公共配置
... # 各server虛擬主機(jī)的公共配置
server { # 每個(gè)server用于定義一個(gè)虛擬主機(jī)
...
}
server {
...
server_name # 虛擬主機(jī)名
root # 主機(jī)目錄名
alias # 路徑別名
location [OPERATOR] URL { # 指定URL的特性
...
if condition {
...
}
}
}
}
- http協(xié)議配置說(shuō)明
http {
include mime.types; # 導(dǎo)入支持的文件類型, 是相對(duì)于/apps/nginx/conf的目錄
default_type application/octet-stream; # 除mime.types中包括的文件類型, 都默認(rèn)定義為octet-stream類型,如果通過瀏覽器訪問不屬于mime.types定義的文件類型的文件那么瀏覽器會(huì)直接下載
#可以修改默認(rèn)類型為test/html, 這樣即使訪問了不屬于mime類型的文件, 也會(huì)被當(dāng)做html格式, 直接嘗試打開, 而不是下載到本地. 不過不同的瀏覽器效果不同, 一般谷歌瀏覽器會(huì)直接打開, 有些瀏覽器還是會(huì)直接下載文件
# 日志配置部分
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
# 自定義優(yōu)化參數(shù)
sendfile on;
#tcp_nopush on; # 在開啟了sendfile的情況下, 會(huì)把多個(gè)響應(yīng)報(bào)文合并后統(tǒng)一發(fā)送給客戶端, 服務(wù)器節(jié)省了資源, 但是客戶端都會(huì)有延遲. 需要根據(jù)服務(wù)器負(fù)載情況進(jìn)行調(diào)整, 當(dāng)負(fù)載不高時(shí), 無(wú)需開啟, 可以直接發(fā)給客戶端, 當(dāng)過高時(shí), 可以考慮開啟
#tcp_nodelay off; # 在開啟了keepalived模式下的連接是否啟用tcp_nodelay選項(xiàng), 當(dāng)為off時(shí), 延遲0.2s發(fā)送, 默認(rèn)on時(shí), 不延遲發(fā)送, 立即發(fā)送響應(yīng)報(bào)文給用戶
#keepalive_timeout 0;
keepalive_timeout 65 65; # 設(shè)置會(huì)話保持時(shí)間, 第二個(gè)值為響應(yīng)首部: keep-alived:timeout=65, 可以和第一個(gè)值不同
#gzip on; # 開啟文件壓縮
# 虛擬主機(jī)設(shè)置
server {
listen 80; # 設(shè)置監(jiān)聽地址和端口, 10.0.0.238:80 | 80
server_name locahost; # 設(shè)置server_name, 基于server_name來(lái)區(qū)分虛擬主機(jī), 可以以空格隔開寫多個(gè)并支持正則表達(dá)式, 如: *.wang.com www.wang.*
#charset koi8-r; # 設(shè)置編碼格式, 默認(rèn)是俄語(yǔ), 改成utf-8. 不過不改也沒關(guān)系, 前端網(wǎng)站代碼都會(huì)指定字符集, 另外, 如果這里去掉注釋, 那么在客戶端查看響應(yīng)報(bào)文是可以看到服務(wù)器端字符集
#access_log logs/host.access.log main;
}
server {
...
server_name
root
alias
location [OPERATOR] URL {
...
if condition {
...
}
}
}
}
2.3.1 MIME
# 在響應(yīng)報(bào)文中指定的文件擴(kuò)展名映射至MIME對(duì)應(yīng)的類型
include mime.types; # 導(dǎo)入支持的文件類型, 是相對(duì)于/apps/nginx/conf的目錄
default_type application/octet-stream; # 除mime.types中包括的文件類型, 都默認(rèn)定義為octet-stream類型,如果通過瀏覽器訪問不屬于mime.types定義的文件類型的文件那么瀏覽器會(huì)直接下載. 如果需要通過瀏覽器訪問不在mime.types里的類型, 不讓瀏覽器直接下載, 那么可以修改default_type為包含在mime.types里的類型, 比如html
2.3.2 響應(yīng)報(bào)文字段
# 是否在響應(yīng)報(bào)文中的Content-Type顯示指定的字符集, 默認(rèn)off不顯示
charset CHARSET;
# 示例
charset utf-8;
# 是否在響應(yīng)報(bào)文的Server首部顯示nginx版本信息. 可以在http,server和location語(yǔ)句塊指定. on為顯示nginx和版本信息, off不會(huì)顯示版本但是還會(huì)顯示nginx. build和string是商業(yè)版支持的功能
server_tokens on | off | build | string
# 如果想要修改整個(gè)Server字段, 需要修改nginx源碼, 將已有的nginx二進(jìn)制文件做備份, 然后重新編譯nginx, 然后用新的nginx二進(jìn)制文件, 替換掉舊的. 然后重啟nginx服務(wù)
2.4 核心配置實(shí)例
- 基于不同的ip地址, 端口, 和域名來(lái)實(shí)現(xiàn)不同的虛擬主機(jī), 依賴于核心模塊[ngx_http_core_module]
2.4.1 新建pc和mobile Web站點(diǎn)
pc.wang.org
m.wang.org
- 準(zhǔn)備存放pc和mobile主頁(yè)面的目錄
[22:09:54 root@nginx ~]#mkdir -pv /data/nginx/html/pc
mkdir: created directory '/data/nginx'
mkdir: created directory '/data/nginx/html'
mkdir: created directory '/data/nginx/html/pc'
[22:26:33 root@nginx ~]#mkdir -pv /data/nginx/html/mobile
mkdir: created directory '/data/nginx/html/mobile'
- 修改配置文件, 指定include目錄, 將pc和mobile網(wǎng)站的配置文件單獨(dú)存放
[22:26:37 root@nginx ~]#vim /apps/nginx/conf/nginx.conf
...
#}
include /apps/nginx/conf.d/*.conf; # include指令需要放到http語(yǔ)句塊
}
[22:27:17 root@nginx ~]#mkdir -pv /apps/nginx/conf.d/
mkdir: created directory '/apps/nginx/conf.d/'
[20:55:23 root@nginx ~]#nginx -s reload
- 創(chuàng)建pc和mobile的主頁(yè)面
[22:27:29 root@nginx ~]#echo "pc website" > /data/nginx/html/pc/index.html
[22:30:24 root@nginx ~]#echo "mobile website" > /data/nginx/html/mobile/index.html
- 編輯配置文件
- m.wang.org
[22:37:05 root@nginx ~]#cat /apps/nginx/conf.d/mobile.conf
server {
listen 80;
server_name m.wang.org;
# root 指定網(wǎng)站數(shù)據(jù)的總目錄
root /data/nginx/html/mobile;
# index 指定默認(rèn)主頁(yè)面, 默認(rèn)就是index和index.html
index index index.html;
}
- pc.wang.org
[22:37:40 root@nginx ~]#cat /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
# root 指定網(wǎng)站數(shù)據(jù)的總目錄
root /data/nginx/html/pc;
# index 指定默認(rèn)主頁(yè)面, 默認(rèn)就是index和index.html
index index index.html;
}
- 找一個(gè)客戶端, 設(shè)置域名解析
10.0.0.86 pc.wang.org m.wang.org
- 重啟nginx
[22:46:30 root@nginx ~]#nginx -s reload
- 訪問測(cè)試
[22:53:01 root@client ~]#curl pc.wang.org
pc website
[22:53:02 root@client ~]#curl m.wang.org
mobile website
[22:53:05 root@client ~]#curl 10.0.0.86 # 通過ip訪問, 訪問的是默認(rèn)頁(yè)面
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
注意: 這里之所以通過ip訪問, 訪問的是主配置文件里的默認(rèn)站點(diǎn), 是因?yàn)? 默認(rèn)站點(diǎn)在主配置文件中的順序是排在我們定義include目錄之上的, 因此優(yōu)先級(jí)高, 通過ip訪問訪問的就是默認(rèn)站點(diǎn), 如果我們把include指令放在http語(yǔ)句塊里,server語(yǔ)句塊上面, 那么就比默認(rèn)站點(diǎn)的server語(yǔ)句塊優(yōu)先級(jí)高了, 這時(shí)候通過ip訪問訪問到的就是include定義的/apps/nginx/conf.d/目錄下的第一個(gè)配置文件定義的站點(diǎn)信息
- 修改主配置文件測(cè)試
[22:52:47 root@nginx ~]#vim /apps/nginx/conf/nginx.conf
http {
include /apps/nginx/conf.d/*.conf;
[23:01:20 root@nginx ~]#nginx -s reload
[23:03:00 root@nginx ~]#ls /apps/nginx/conf.d/
mobile.conf pc.conf
[22:54:21 root@client ~]#curl 10.0.0.238
mobile website # 訪問到的是mobile, 因?yàn)樵赾onf.d目錄排在前面
- 將主配置文件配置恢復(fù), 把include放在最下方
[23:06:37 root@nginx ~]#vim /apps/nginx/conf/nginx.conf
...
#}
include /apps/nginx/conf.d/*.conf;
}
[23:06:32 root@nginx ~]#nginx -s reload
此時(shí), 一個(gè)nginx服務(wù)器上, 有三個(gè)站點(diǎn)
10.0.0.86 - Nginx默認(rèn)頁(yè)面
pc.wang.org
mobile.wang.org
補(bǔ)充:
include指令的位置, 只是決定了通過ip訪問時(shí), 訪問的是默認(rèn)站點(diǎn), 還是虛擬主機(jī)站點(diǎn)
并不會(huì)真正影響對(duì)于默認(rèn)站點(diǎn)的訪問, 默認(rèn)站點(diǎn)本身也就是一個(gè)虛擬主機(jī), 因此, 也是可以通過在其server語(yǔ)句塊中定義server_name來(lái)訪問, 默認(rèn)的server_name是localhost
一般include指令放在后面, 不要影響默認(rèn)站點(diǎn)設(shè)置
2.4.2 root 與 alias指令
- root: 指定web站點(diǎn)的家目錄
- root可以放在server語(yǔ)句塊用來(lái)指定虛擬主機(jī)站點(diǎn)的家目錄, 也就是在磁盤目錄的起始位置
- 也可以放在location語(yǔ)句塊, 配合location語(yǔ)句塊(location /URL)來(lái)自定義某個(gè)URL的磁盤目錄起始位置
- 如果在location語(yǔ)句塊中定義了root, 那么訪問location 后定義的URL, 實(shí)際訪問的是root+location
- 在定義location語(yǔ)句塊的時(shí)候, 磁盤文件的絕對(duì)路徑等于root+location
示例1:
[21:29:24 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
root /data/nginx/html/pc;
index index index.html;
location /about { # 只定義location URL, root還是用站點(diǎn)的默認(rèn)root
}
}
# 此時(shí), 訪問pc.wang.org/about, 實(shí)際訪問的是磁盤上,/data/nginx/html/pc/about目錄下的默認(rèn)文件, 因?yàn)? 該about目錄還沒有創(chuàng)建, 因此, 訪問會(huì)出現(xiàn)404報(bào)錯(cuò)
[21:28:35 root@CentOS-8-5 ~]#curl pc.wang.org/about
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
# 在服務(wù)器上創(chuàng)建about目錄, 并添加默認(rèn)index.html頁(yè)面
[21:32:29 root@nginx ~]#echo /data/nginx/html/pc/about > /data/nginx/html/pc/about/index.html
# 再次測(cè)試訪問
[21:32:50 root@CentOS-8-5 ~]#curl pc.wang.org/about -L # curl瀏覽器需要加-L禁止跳轉(zhuǎn)
/data/nginx/html/pc/about
[23:22:10 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
# root 指定網(wǎng)站數(shù)據(jù)的總目錄
root /data/nginx/html/pc;
# index 指定默認(rèn)主頁(yè)面, 默認(rèn)就是index和index.html
index index index.html;
location /about { # 這時(shí), 如果從瀏覽器訪問pc.wang.org/about, 那么nginx會(huì)到/opt/html/about目錄下, 去找默認(rèn)頁(yè)面
root /opt/html; # 在location語(yǔ)句塊定義了root, 那么就限定了這個(gè)location的根是從哪開始. 如果在location中沒有定義root, 那么就用server語(yǔ)句塊中定義的root, 這時(shí)訪問pc.wang.org/about, 實(shí)際訪問的是/data/nginx/html/pc/about目錄下的默認(rèn)文件
}
}
示例2:
[21:32:37 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
root /data/nginx/html/pc;
index index index.html;
location /about {
root /opt/html; # 給location單獨(dú)定義了root, 那么訪問pc.wang.org/about時(shí), 訪問的就是/opt/html/about目錄下的默認(rèn)文件
}
}
[23:26:44 root@nginx ~]#mkdir -pv /opt/html/about
mkdir: created directory '/opt/html'
mkdir: created directory '/opt/html/about'
[23:26:50 root@nginx ~]#echo "about page" > /opt/html/about/index.html
[23:27:03 root@nginx ~]#nginx -s reload
[23:27:35 root@client ~]#curl pc.wang.org/about
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
[23:27:38 root@client ~]#curl pc.wang.org/about -L
about page
[23:27:43 root@client ~]#curl pc.wang.org/about/ # 通過curl去訪問時(shí), 需要用'/'補(bǔ)全路徑, 否則會(huì)自動(dòng)跳轉(zhuǎn), 在瀏覽器訪問不用, 瀏覽器會(huì)自動(dòng)補(bǔ)全'/'
about page
[23:27:59 root@client ~]#curl pc.wang.org # 主站點(diǎn)還是正常訪問, 因?yàn)閞oot /data/nginx/html/pc; 是配置在server語(yǔ)句塊里的
pc website
- alias: 定義路徑別名
- 會(huì)把訪問的路徑, 重新定義到其指定的路徑, 是文檔映射的另一種機(jī)制
- alias只能用在location語(yǔ)句塊
示例:
[23:44:01 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
# root 指定網(wǎng)站數(shù)據(jù)的總目錄
root /data/nginx/html/pc;
# index 指定默認(rèn)主頁(yè)面, 默認(rèn)就是index和index.html
index index index.html;
location /about { # 這時(shí), 訪問pc.wang.org/about實(shí)際訪問的是pc.wang.org/opt/html, 也就是磁盤opt/html目錄下的默認(rèn)文件, 而非root目錄下的/opt/html
alias /opt/html;
}
}
[23:44:15 root@nginx ~]#echo "/opt/html/index.html" > /opt/html/index.html
[23:45:27 root@nginx ~]#nginx -s reload
[23:46:05 root@client ~]#curl pc.wang.org/about/
/opt/html/index.html
注意: 利用alias時(shí), 如果location的URL最后有'/'補(bǔ)全, 那么alias的URL最后也必須有"/"補(bǔ)全, 否則訪問會(huì)報(bào)錯(cuò)403
示例:
[21:44:10 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
root /data/nginx/html/pc;
index index index.html;
location /about/ {
alias /opt/html;
}
}
nginx -s reload
[21:44:14 root@CentOS-8-5 ~]#curl pc.wang.org/about/
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
2.4.3 location詳細(xì)使用
- 在一個(gè)server中l(wèi)ocation配置段可以存在多個(gè), 用于實(shí)現(xiàn)從URI到文件系統(tǒng)的路徑映射, nginx會(huì)根據(jù)用戶請(qǐng)求的URI(也就是域名后的路徑)來(lái)檢查定義的所有的location, 按一定的優(yōu)先級(jí)別找出一個(gè)最佳匹配, 而后應(yīng)用該localtion中的設(shè)置
語(yǔ)法規(guī)則:
location [ = | ~ | ~* | ^~ ] URI { ... }
= # 用于標(biāo)準(zhǔn)uri前, 需要請(qǐng)求字符串與uri精確匹配, 大小寫敏感, 如果匹配成功就立即停止向下匹配, 并立即處理請(qǐng)求
比如: 定義location = /index.html, 那么用戶就必須訪問/index.html才會(huì)匹配
^~ # 用于標(biāo)準(zhǔn)uri前, 表示包含正則表達(dá)式, 并且匹配以指定的正則表達(dá)式開頭, 對(duì)uri的最左邊部分做匹配檢查, 不區(qū)分字符大小寫
比如: 定義location ^~ /static, 那么用戶只要訪問/static開頭的uri都是可以匹配的, /static1, /static2...
不帶符號(hào) # 匹配起始于此uri的所有的uri, 不區(qū)分大小寫
比如: location /static, 用戶訪問任何起始于/static的路徑都可以匹配, /static/a.css可以匹配
~ # 用于標(biāo)準(zhǔn)uri前, 表示包含正則表達(dá)式, 并且區(qū)分大小寫
比如: 定義location ~ /static, 那么只要訪問的路徑, 包含static字符串即可, /images/static123, 滿足條件, 因?yàn)榘藄tatic字符串, 不過 ~ 是區(qū)分大小寫的, 如果/images/STATIC123那就不能匹配了
~* # 用于標(biāo)準(zhǔn)uri前, 表示包含正則表達(dá)式, 并且不區(qū)分大小寫
比如: 定義location ~* /static, 那么只要訪問的路徑, 包含static字符串即可, /images/static123,滿足條件, 而且, ~* 是不區(qū)分大小寫的, 訪問/images/statiC123, 也會(huì)被匹配
\ # 用于標(biāo)準(zhǔn)uri前, 表示包含正則表達(dá)式并且轉(zhuǎn)義字符. 可以將 . * ? 等轉(zhuǎn)義為普通符號(hào)
# 匹配優(yōu)先級(jí)從高到低:
=, ^~, ~|~*(哪個(gè)location在前, 哪個(gè)生效) , 不帶符號(hào)
2.4.3.1 匹配案例-精確匹配 =
在server部分使用location配置一個(gè)web界面, 例如: 當(dāng)訪問nginx服務(wù)器的/logo.jpg的時(shí)候, 要顯示指定的html文件的內(nèi)容
精確匹配一般用于組織的logo等相對(duì)固定的URL, 匹配優(yōu)先級(jí)最高
范例: 精確匹配logo
[01:06:10 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
location / {
root /data/nginx/html/pc;
}
location = /logo.jpg {
# 必須精確訪問pc.wang.org/logo.jpg, 才會(huì)匹配, 一旦匹配成功, 就會(huì)到/data/nginx/images下去找logo.jpg
root /data/nginx/images;
index index.html;
}
}
[01:14:33 root@nginx ~]#mkdir -pv /data/nginx/images
mkdir: created directory '/data/nginx/images'
[01:16:26 root@nginx ~]#ls /data/nginx/images
logo.jpg
[01:16:56 root@nginx ~]#nginx -s reload
測(cè)試訪問:
-
區(qū)分大小寫
圖片.png 如果只訪問pc.wang.org, 那么會(huì)走第一個(gè)location /, 正常訪問站點(diǎn)家目錄
2.4.3.2 區(qū)分大小寫 ~
- ~ 實(shí)現(xiàn)區(qū)分大小寫的模糊匹配, 以下范例中, 如果訪問的uri中包含大寫字母的JPG, 則以下location匹配Ax.JPG不成功, 因?yàn)?~ 區(qū)分大小寫, 那么當(dāng)用戶的請(qǐng)求被執(zhí)行匹配時(shí)發(fā)現(xiàn)location中定義的是小寫的jpg, 則匹配失敗, 即要么繼續(xù)匹配其他的location(如果有), 要么報(bào)錯(cuò)給客戶端
[01:16:57 root@nginx ~]#mkdir -pv /data/nginx/html/image
mkdir: created directory '/data/nginx/html/image'
[01:35:01 root@nginx ~]#ls /data/nginx/html/image
Ax.jpg
[01:32:18 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
location / {
root /data/nginx/html/pc;
}
# 匹配大寫字母A開頭, 后面跟一個(gè)或0個(gè)字符的.jpg文件
location ~ /A.?\.jpg {
root /data/nginx/html/image;
index index.html;
}
}
- 此時(shí), 如果把/data/nginx/html/image下的Ax.jpg文件, 移動(dòng)到 /data/nginx/html/pc目錄下, 那么用戶訪問pc.wang.org/Ax.jpg時(shí), 也會(huì)出現(xiàn)404報(bào)錯(cuò), 因?yàn)? 當(dāng)訪問pc.wang.org/Ax.jpg是符合location ~ /A.?.jpg模式的, 那么就會(huì)在其root( root /data/nginx/html/image )下尋找Ax.jpg文件, 如果找不到就會(huì)報(bào)錯(cuò)404, 而不會(huì)去其他的location再匹配. 也就是如果匹配到了某個(gè)location, 那么即使該location的root下沒有要找的文件, 也不會(huì)去別的location再進(jìn)行匹配
[15:46:42 root@nginx /data/nginx/html/image]#mv Ax.jpg /data/nginx/html/pc/
2.4.3.3 不區(qū)分大小寫
~* 用來(lái)對(duì)用戶請(qǐng)求的uri做模糊匹配, uri中無(wú)論都是大寫, 都是小寫或者大小寫混合, 此模式都會(huì)匹配, 通常使用此模式匹配用戶request中的靜態(tài)資源并繼續(xù)做下一步操作, 此方式使用較多
注意: 此方式中, 對(duì)于Linux文件系統(tǒng)上的文件仍然是區(qū)分大小寫的, 如果磁盤文件不存在, 仍然會(huì)報(bào)404, 也就是說(shuō), 一但匹配成功了, 那么Linux上必須有用戶訪問的文件才行.
[01:38:13 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
location / {
root /data/nginx/html/pc;
}
location ~* /A.?\.jpg {
root /data/nginx/html/image;
index index.html;
}
}
[01:59:14 root@nginx ~]#nginx -s reload
準(zhǔn)備兩個(gè)圖片文件
[02:02:48 root@nginx /data/nginx/html/image]#ls
ax.jpg Ax.jpg
訪問Ax.jpg
訪問ax.jpg
訪問不同的文件, 結(jié)果不同, 說(shuō)明雖然匹配時(shí)不區(qū)分大小寫, 但是一旦匹配成功, 落到Linux目錄里查找文件就是區(qū)分大小了, 因?yàn)長(zhǎng)inux文件系統(tǒng)區(qū)分大小寫
2.4.3.4 URI開始
- ^~ 只要是訪問以定義的uri起始的文件, 都會(huì)匹配, 不區(qū)分大小寫
[02:12:03 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
location / {
root /data/nginx/html/pc;
}
location ^~ /image { # 這時(shí)只要訪問的uri是以/image開始的就可以匹配, /images1/a.jpg,/image2/b.jpg,/image/jpg/c.jpg都會(huì)匹配
root /data/nginx/html/image; # 注意, 因?yàn)槎x了root, 那么要訪問的文件, 一定要在 /data/nginx/html/image目錄下存在才行, 否則404
index index.html;
}
}
[02:12:58 root@nginx ~]#nginx -s reload
# /data/nginx/html/image/image下創(chuàng)建一個(gè)c.jpg文件
[02:13:01 root@nginx ~]#mkdir /data/nginx/html/image/image
[02:16:27 root@nginx ~]#ls /data/nginx/html/image/image/
c.jpg
測(cè)試訪問:
示例:
用戶訪問pc.wang.org/image1/jpg/d.jpg, 此時(shí)/image1/jpg/d.jpg符合^~ /image, 因此會(huì)去/data/nginx/html/image/image1/jpg的目錄下, 查找d.jpg文件
[15:59:58 root@nginx /data/nginx/html/image]#mkdir -pv /data/nginx/html/image/image1/jpg
mkdir: created directory '/data/nginx/html/image/image1'
mkdir: created directory '/data/nginx/html/image/image1/jpg'
[16:02:18 root@nginx /data/nginx/html/image]#cd /data/nginx/html/image/image1/jpg
[16:02:45 root@nginx /data/nginx/html/image/image1/jpg]#rz -E
rz waiting to receive.
[16:02:47 root@nginx /data/nginx/html/image/image1/jpg]#ls
d.jpg
補(bǔ)充示例:
location /api-py {
alias /data/nginx/api-py;
index index.html
#這時(shí)訪問pc.wang.org/api-py, 實(shí)際訪問的是/data/nginx/api-py路徑下的頁(yè)面, 因?yàn)檫@里是別名, 別名就是url和磁盤文件的映射. 而訪問/api-py, 因?yàn)榉蟣ocation 不帶 URI, 即用戶訪問任何起始于/api-py的文件, 都匹配, 所以該條location會(huì)匹配
location /api-py {
root /data/nginx/api-py;
index index.html
#這時(shí)訪問pc.wang.org/api-py, 實(shí)際訪問的是/data/nginx/api-py/api-py, 因?yàn)槭莚oot, 那么訪問時(shí)的真實(shí)路徑是root+location
}
2.4.3.5 文件名后綴
[02:16:31 root@nginx ~]#mkdir /data/nginx/static
[02:39:06 root@nginx ~]#ls /data/nginx/static/
d.jpg
[02:39:09 root@nginx ~]#vim /apps/nginx/conf.d/pc.conf
server {
listen 80;
server_name pc.wang.org;
location / {
root /data/nginx/html/pc;
}
location ~* \.(gif|jpg|jpeg)$ { # 靜態(tài)頁(yè)面, 只要是以定義的格式結(jié)尾的文件, 就都轉(zhuǎn)到相應(yīng)的目錄
root /data/nginx/static;
index index.html;
}
}
[02:40:57 root@nginx ~]#nginx -s reload
2.4.3.6 優(yōu)先級(jí)
location = > location ^~ 路徑 > location ~,~* 正則順序(看誰(shuí)寫在前面) > location 完整路徑 > location部分路徑 > 不帶符號(hào) /
2.4.3.7 生產(chǎn)使用案例
# 直接匹配網(wǎng)站的根, 會(huì)加速Nginx訪問處理, 因?yàn)橐话憔W(wǎng)站的主頁(yè)面都是訪問量最大的
location = / {
...;
}
location / {
...;
}
# 靜態(tài)資源配置方法1
location ^~ /static {
...;
}
# 靜態(tài)資源配置方法2
location ~* \.(gif|jpg|...)$ {
...;
}
# 多應(yīng)用配置
location ~* /app1 {
...;
}
location ~* /app2 {
...;
}
補(bǔ)充: location = / 和 location /的特殊情況
server {
listen 80;
server_name pc.wang.org;
root /data/nginx/html/pc1;
index index index.html;
location = / {
root /data/nginx/html/pc2;
}
location / {
root /data/nginx/html/pc3;
}
}
[17:22:34 root@nginx ~]#nginx -s reload
[17:22:37 root@nginx ~]#mkdir /data/nginx/html/pc1
[17:23:07 root@nginx ~]#mkdir /data/nginx/html/pc2
[17:23:08 root@nginx ~]#mkdir /data/nginx/html/pc3
[17:23:09 root@nginx ~]#echo /data/nginx/html/pc1 > /data/nginx/html/pc1/index.html
[17:23:28 root@nginx ~]#echo /data/nginx/html/pc2 > /data/nginx/html/pc2/index.html
[17:23:33 root@nginx ~]#echo /data/nginx/html/pc3 > /data/nginx/html/pc3/index.html
當(dāng) = / 和 / 同時(shí)存在, 并且location的URL后沒有接文件名, 如果用戶訪問'/', 那么location / 會(huì)生效
訪問pc.wang.org, location / 生效
server {
listen 80;
server_name pc.wang.org;
root /data/nginx/html/pc1;
index index index.html;
location = /index.html {
root /data/nginx/html/pc2;
}
location /index.html {
root /data/nginx/html/pc3;
}
}
~
# 如果location的URL接了文件名, 那么=號(hào)生效
[17:31:20 root@nginx ~]#curl pc.wang.org/index.html
/data/nginx/html/pc2
匹配規(guī)則中有的是不區(qū)分大小的, 但是實(shí)際落到磁盤文件, 還是區(qū)分大小寫的
定義在location中的root的優(yōu)先級(jí)是比server中的root優(yōu)先級(jí)高的
2.4.5 Nginx四層訪問控制
- 訪問控制基于模塊ngx_http_access_module實(shí)現(xiàn), 可以通過匹配客戶端源ip地址進(jìn)行限制
- 如果能在防火墻設(shè)備控制, 最好不要在nginx配置, 可以更好的節(jié)約資源
# deny
location = / {
root /data/nginx/html/pc;
index index.html;
deny all;
}
[12:42:39 root@nginx ~]#nginx -s reload
此時(shí)任何人都無(wú)法訪問
[12:10:23 root@client ~]#curl pc.wang.org
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.18.0</center>
</body>
</html>
只允許10.0.0.86訪問
location / {
root /data/nginx/html/pc;
allow 10.0.0.86; # 允許規(guī)則需要放在deny前面
deny all;
}
[18:01:54 root@nginx ~]#curl pc.wang.org
pc website
2.4.6 Nginx賬戶認(rèn)證功能
- 有ngx_http_auth_basic_module模塊提供此功能
創(chuàng)建允許登錄賬號(hào)
yum -y install httpd-tools #提供htpasswd工具
[12:46:40 root@nginx ~]#htpasswd -cb /apps/nginx/conf/.htpasswd user1 123456 # -c創(chuàng)建文件, 多次-c會(huì)覆蓋源文件
Adding password for user user1
[12:47:00 root@nginx ~]#htpasswd -b /apps/nginx/conf/.htpasswd user2 123456
Adding password for user user2
[12:47:10 root@nginx ~]#tail /apps/nginx/conf/.htpasswd
user1:$apr1$NTDtA42B$yO.tjrHVn/j2vUqesJty81
user2:$apr1$d6BI7W.D$vXhfMwKpOocEIjApwEt0F/
配置nginx
location = /login {
root /data/nginx/html/pc;
index index.html;
auth_basic "login password";
auth_basic_user_file /apps/nginx/conf/.htpasswd;
}
[12:48:28 root@nginx ~]#nginx -s reload
curl http://user1:123456@pc.wang.org/login/ # 這里URL要補(bǔ)全/, 否則會(huì)提示401, 需要認(rèn)證
2.4.7 自定義錯(cuò)誤日志
- 默認(rèn), logs/access.log和error.log會(huì)記錄所有虛擬主機(jī)的日志
- access.log記錄訪問成功和失敗的日志
- error.log記錄訪問失敗的日志
- 可以針對(duì)不同的虛擬主機(jī), 設(shè)置獨(dú)立的日志, 也就是每個(gè)網(wǎng)站, 一個(gè)獨(dú)立的訪問和錯(cuò)誤日志
案例: 給pc.wang.org配置獨(dú)立的錯(cuò)誤日志
server {
listen 80;
server_name pc.wang.org;
error_page 500 502 503 504 404 /error.html; # 將這些報(bào)錯(cuò)都轉(zhuǎn)到/error.html下
error_log /data/nginx/logs/pc_wang_org_error.log; # 定義該虛擬主機(jī)的錯(cuò)誤日志路徑
location = /error.html { # 指定錯(cuò)誤頁(yè)面位置
root /data/nginx/html/pc;
}
}
[12:55:09 root@nginx ~]#mkdir /data/nginx/logs
[18:12:39 root@nginx ~]#nginx -s reload
#定義錯(cuò)誤頁(yè)面
[13:10:48 root@nginx ~]#vim /data/nginx/html/pc/error.html
error.html
[13:11:29 root@nginx ~]#tail /data/nginx/logs/pc_wang_org_error.log
2021/01/07 13:09:21 [error] 1578#0: *43 open() "/apps/nginx/html/dasdasd" failed (2: No such file or directory), client: 10.0.0.1, server: pc.wang.org, request: "GET /dasdasd HTTP/1.1", host: "pc.wang.org"
2.4.8 自定義錯(cuò)誤頁(yè)面
范例: 如果出現(xiàn)404, 就跳轉(zhuǎn)到/index.html, 實(shí)現(xiàn)只要用戶訪問的頁(yè)面不存在, 就跳轉(zhuǎn)到網(wǎng)站默認(rèn)頁(yè)面. 不過訪問記錄還是會(huì)被記錄到錯(cuò)誤日志. 并且返回給客戶端的狀態(tài)碼是404
server {
listen 80;
server_name pc.wang.org;
error_page 404 /index.html; # 404跳轉(zhuǎn)到/index.html
error_log /data/nginx/logs/pc_wang_org_error.log; # error_log /data/nginx/logs/pc_wang_org_error.log debug; 也可以調(diào)整記錄的日志級(jí)別
location = /index.html {
root /data/nginx/html/pc;
}
}
范例: 404通過302跳轉(zhuǎn)到主頁(yè)面, 5xx錯(cuò)誤, 轉(zhuǎn)到/50x.html
error_page 404 =302 /index.html; # 404返回302狀態(tài)碼
error_page 500 502 503 504 /50x.html
location = /50x.html {
}
2.4.9 長(zhǎng)連接配置
- 斷開條件: 連接時(shí)長(zhǎng), 或請(qǐng)求次數(shù)
keepalive_timeout timeout [header_timeout]; # 設(shè)定保持連接的超時(shí)時(shí)長(zhǎng), 0表示禁止長(zhǎng)連接, 默認(rèn)為75s, 通常配置在http字段, 作為站點(diǎn)全局設(shè)置
keepalive_requests number; # 在一次長(zhǎng)連接上, 所允許請(qǐng)求的資源的最大數(shù)量, 默認(rèn)為100次, 建議適當(dāng)調(diào)大, 比如: 500
范例:
keepalive_requests 3; # 單次連接, 最多請(qǐng)求3從就會(huì)斷開連接
keepalive_time 65 60; # 開啟長(zhǎng)連接后, 返回客戶端的會(huì)話保持時(shí)間為60s, 單次長(zhǎng)連接累計(jì)請(qǐng)求達(dá)到指定次數(shù)請(qǐng)求或65秒就會(huì)被斷開. 后面的60為發(fā)送給客戶端的應(yīng)答報(bào)文頭部中顯示的超時(shí)時(shí)間設(shè)置為60s, 如果不設(shè)置, 客戶端將不顯示超時(shí)時(shí)間. 65為服務(wù)器真正的斷開時(shí)間, 而60是瀏覽器顯示的斷開時(shí)間
響應(yīng)報(bào)文頭部: Keep-ALive:timeout=60 # 設(shè)置為60后, 瀏覽器收到的服務(wù)器響應(yīng)報(bào)文提示超時(shí)時(shí)間是60秒
Connection:close # 如果不設(shè)置長(zhǎng)連接, 那么瀏覽器收到的響應(yīng)報(bào)文就會(huì)顯示close
2.4.10 nginx作為下載服務(wù)器配置
ngx_http_autoindex_module 模塊處理下載請(qǐng)求, 并生成目錄列表, 可以作為下載服務(wù)器配置使用
默認(rèn)情況下, 一個(gè)路徑下面如果沒有index.html默認(rèn)頁(yè)面, 那么是不允許訪問的, 會(huì)報(bào)錯(cuò)403, 而nginx作為下載服務(wù)器時(shí), 目錄是可以沒有index.html的
范例: 配置下載服務(wù)器
- 先創(chuàng)建目錄和文件
[13:59:34 root@nginx ~]#mkdir /data/nginx/html/pc/download
[13:59:54 root@nginx ~]#touch /data/nginx/html/pc/download/file{1..5}.txt
[14:00:01 root@nginx ~]#mkdir /data/nginx/html/pc/download/ios
[14:00:11 root@nginx ~]#dd if=/dev/zero of=/data/nginx/html/pc/download/ios/ubuntu.iso
594313+0 records in
594313+0 records out
304288256 bytes (304 MB, 290 MiB) copied, 5.03828 s, 60.4 MB/s
- 編輯配置文件
location /download {
autoindex on;
autoindex_exact_size on; # on顯示精確大小, off顯示模糊大小
autoindex_localtime on; # on顯示當(dāng)?shù)貢r(shí)間, off顯示格林威治時(shí)間
limit_rate 1024k; # 下載限速
root /data/nginx/html/pc;
}
- 測(cè)試下載
- 此時(shí), 對(duì)于一些文本文件, 會(huì)直接在瀏覽器打開, 需要做額外的配置實(shí)現(xiàn)下載
location /download {
autoindex on;
if ($request_filename ~* ^.*?\.(txt|doc|pdf|rar|gz|zip|docx|exe|xlsx|ppt|pptx)$){
add_header Content-Disposition: 'attachment;';
}
autoindex_exact_size on;
autoindex_localtime on;
limit_rate 1024k;
root /data/nginx/html/pc;
}