nginx
爲方便在設置出錯時快速恢復,使用docker方式來配置nginx,下文所有命令針對docker方式。
簡單啓動
sudo docker run --name nginx_3000 -p 3000:80 -d nginx
可以在3000端口訪問nginx,如下圖:
nginx相關目錄
實際使用過程中,我們需要對nginx的轉發規則等選項進行配置。docker版本的各個配置文件默認所在路徑爲:
- 網頁root目錄:/usr/share/nginx/html
- nginx配置文件:/etc/nginx/nginx.conf
- 日誌文件目錄:/var/log/nginx
nginx主要命令
nginx stop #快速關機
nginx quit #優雅的關機
nginx reload #重新加載配置文件
nginx reopen #重新打開日誌文件
nginx -t #檢查配置,同時也是輸出配置文件所在位置
nginx -s reload #修改配置後重載
掛載文件啓動
docker啓動nginx後每次修改配置文件都得執行
docker exec nginx_3000 /bin/bash
進入容器的shell後進行操作,比較繁瑣,而且用vi編輯器修改內容多時不太方便,所以可以將網頁文件及配置文件從宿主機中掛載到nginx中,這樣可以方便在在宿主機中利用vscode進行修改。
首先先在宿主機中某一位置建立網頁、日誌和配置目錄
mkdir html
mkdir logs
mkdir conf
拷貝容器中nginx默認配置到宿主機剛纔新建的conf目錄中
docker cp nginx_3000:/etc/nginx/nginx.conf ./conf/
刪掉剛纔建立的nginx容器,重新建立帶目錄映射的容器,
docker run -d -p 80:80 --name nginx_zf -v ~/docker_file/nginx/html:/usr/share/nginx/html -v ~/docker_file/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v ~/docker_file/nginx/logs:/var/log/nginx nginx
其中各個配置項含義如下:
-d 後臺運行
-p 端口映射 3000宿主機端口 80 docker監聽端口
–name 指定容器名稱
-v 目錄映射 前者是宿主機路徑 後者是docker容器路徑 具體路徑根據自己情況設定
html爲網頁內容
conf 爲nginx配置
logs 爲 日誌
啓動成功後,我們就可以在宿主機中修改nginx的配置文件了,一般修改完成後,可以restart容器來生效配置,或者進入nginx容器,執行重載配置。
默認nginx配置文件內容/etc/nginx/nginx.conf
如下:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
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"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
注意文件中又引入了 /etc/nginx/conf.d/*.conf
文件,如下:
server {
listen 80;
listen [::]:80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
爲簡化操作,可以直接修改宿主機中的 nginx.conf
文件,不導入其他文件,現在以一個url轉發爲例修改宿主機的配置文件如下:
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
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"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
autoindex on;# 消除403報錯
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
# 訪問 localhost:端口號/test 轉發到 www.baidu.com
location /test {
proxy_pass http://www.baidu.com;
}
}
}
如果啓動後報403 可以在location上加上 autoindex on; 配置
配置文件解析
主要結構
... #全局塊
events { #events塊
...
}
http #http塊
{
... #http全局塊
server #server塊
{
... #server全局塊
location [PATTERN] #location塊
{
...
}
location [PATTERN]
{
...
}
}
server
{
...
}
... #http全局塊
}
- 1、全局塊:配置影響nginx全局的指令。一般有運行nginx服務器的用戶組,nginx進程pid存放路徑,日誌存放路徑,配置文件引入,允許生成worker process數等。
- 2、events塊:配置影響nginx服務器或與用戶的網絡連接。有每個進程的最大連接數,選取哪種事件驅動模型處理連接請求,是否允許同時接受多個網路連接,開啓多個網絡連接序列化等。
- 3、http塊:可以嵌套多個server,配置代理,緩存,日誌定義等絕大多數功能和第三方模塊的配置。如文件引入,mime-type定義,日誌自定義,是否使用sendfile傳輸文件,連接超時時間,單連接請求數等。
- 4、server塊:配置虛擬主機的相關參數,一個http中可以有多個server。
- 5、location塊:配置請求的路由,以及各種頁面的處理情況。主要修改都集中在這一塊。
舉例子
########### 每個指令必須有分號結束。#################
#user administrator administrators; #配置用戶或者組,默認爲nobody nobody。
#worker_processes 2; #允許生成的進程數,默認爲1
#pid /nginx/pid/nginx.pid; #指定nginx進程運行文件存放地址
error_log log/error.log debug; #制定日誌路徑,級別。這個設置可以放入全局塊,http塊,server塊,級別以此爲:debug|info|notice|warn|error|crit|alert|emerg
events {
accept_mutex on; #設置網路連接序列化,防止驚羣現象發生,默認爲on
multi_accept on; #設置一個進程是否同時接受多個網絡連接,默認爲off
#use epoll; #事件驅動模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
worker_connections 1024; #最大連接數,默認爲512
}
http {
include mime.types; #文件擴展名與文件類型映射表
default_type application/octet-stream; #默認文件類型,默認爲text/plain
#access_log off; #取消服務日誌
log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定義格式
access_log log/access.log myFormat; #combined爲日誌格式的默認值
sendfile on; #允許sendfile方式傳輸文件,默認爲off,可以在http塊,server塊,location塊。
sendfile_max_chunk 100k; #每個進程每次調用傳輸數量不能大於設定的值,默認爲0,即不設上限。
keepalive_timeout 65; #連接超時時間,默認爲75s,可以在http,server,location塊。
upstream mysvr {
server 127.0.0.1:7878;
server 192.168.10.121:3333 backup; #熱備
}
error_page 404 https://www.baidu.com; #錯誤頁
server {
keepalive_requests 120; #單連接請求上限次數。
listen 4545; #監聽端口
server_name 127.0.0.1; #監聽地址
location ~*^.+$ { #請求的url過濾,正則匹配,~爲區分大小寫,~*爲不區分大小寫。
#root path; #根目錄
#index vv.txt; #設置默認頁
proxy_pass http://mysvr; #請求轉向mysvr 定義的服務器列表
deny 127.0.0.1; #拒絕的ip
allow 172.18.5.54; #允許的ip
}
}
}
常用三個配置詳細解析
location
location [=|~|~*|^~|@] /uri/ {
...
}
- = : 表示精確匹配後面的url
- ~ : 表示正則匹配,但是區分大小寫
- ~* : 正則匹配,不區分大小寫
- ^~ : 表示普通字符匹配,如果該選項匹配,只匹配該選項,不匹配別的選項,一般用來匹配目錄
- @ : “@” 定義一個命名的 location,使用在內部定向時,例如 error_page
上述匹配規則的優先匹配順序:
- = 前綴的指令嚴格匹配這個查詢。如果找到,停止搜索;
- 所有剩下的常規字符串,最長的匹配。如果這個匹配使用 ^~ 前綴,搜索停止;
- 正則表達式,在配置文件中定義的順序;
- 如果第 3 條規則產生匹配的話,結果被使用。否則,使用第 2 條規則的結果。
if
用法:if (條件判斷) { 具體的rewrite規則 }
- 條件判斷語句由Nginx內置變量、邏輯判斷符號和目標字符串三部分組成。
- rewite規則見下方
rewrite
部分
常見邏輯判斷符號:
- = 等於
- != 不等於
- ~ 匹配 區分大小寫
- ~* 匹配 不區分大小寫
- !~ 不匹配 區分大小寫
- !~* 不匹配 不區分大小寫
!表示相反的意思,爲匹配符號,它右側爲正則表達式,區分大小寫,而*爲不區分大小寫匹配。
目標字符串可以是正則表達式,通常不用加引號,但表達式中有特殊符號時,比如空格、花括號、分號等,需要用單引號引起來。
常見Nginx內置變量:
- 1.$remote_addr 與 $http_x_forwarded_for 用以記錄客戶端的ip地址;
- 2.$remote_user :用來記錄客戶端用戶名稱;
- 3.$time_local : 用來記錄訪問時間與時區;
- 4.$request : 用來記錄請求的url與http協議;
- 5.$status : 用來記錄請求狀態;成功是200;
- 6.$body_bytes_s ent :記錄發送給客戶端文件主體內容大小;
- 7.$http_referer :用來記錄從那個頁面鏈接訪問過來的;
- 8.$http_user_agent :記錄客戶端瀏覽器的相關信息;
例子:
if ($http_user_agent ~ MSIE) //user_agent帶有MSIE字符的請求,直接返回403狀態碼 ,MSIE ->IE瀏覽器
{
return 403;
}
if ($request_method = POST) //當請求的方法爲POST時,直接返回405狀態碼
{
return 405; //在該示例中並未用到rewrite規則,if中支持用return指令,直接返回狀態碼
}
if(!-f $request_filename) //當請求的文件不存在,將會執行下面的rewrite規則,-f判斷是否爲文件,!-f判斷這個文件是否存在
{
rewrite 語句; #重要
}
rewrite
用法: rewrite [正則] [替換] 標誌位
rewrite是實現URL重寫的關鍵指令,根據regex(正則表達式)部分內容,重定向到replacement,結尾是flag標誌位
正則表達式匹配,與if
邏輯判斷相同,如下
- ~ 爲區分大小寫匹配
- ~* 爲不區分大小寫匹配
- !和!*分別爲區分大小寫不匹配及不區分大小寫不匹配
rewrite除正則匹配外,還支持對文件目錄判斷,有以下幾種:
- -f和!-f用來判斷是否存在文件
- -d和!-d用來判斷是否存在目錄
- -e和!-e用來判斷是否存在文件或目錄
- -x和!-x用來判斷文件是否可執行
flag標記分爲下面4仲:
- last :本條規則匹配完成後,繼續向下匹配新的location URI規則
- break :本條規則匹配完成即終止,不再匹配後面的任何規則
- redirect :返回302臨時重定向,瀏覽器地址會顯示跳轉後的URL地址
- permanent :返回301永久重定向,瀏覽器地址欄會顯示跳轉後的URL地址
使用last和break實現URI重寫,瀏覽器地址欄不變。而且兩者有細微差別,使用alias指令必須用last標記;使用proxy_pass指令時,需要使用break標記。Last標記在本條rewrite規則執行完畢後,會對其所在server{…}標籤重新發起請求,而break標記則在本條規則匹配完成後,終止匹配。
常用配置
反向代理後端api
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 10240;
}
http {
include /etc/nginx/mime.types;
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"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
#後端多實例集羣,可根據權重分配請求
upstream apiaddr{
server 192.168.31.101:8080 weight=5; #weight 爲權重
server 192.168.31.102:8080 weight=3;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
autoindex on;# 消除403報錯
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri /index.html;#加上該配置項,使能在react項目中手動在瀏覽器url欄手動輸入url。
}
# 反向代理配置
location /api/{
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://apiaddr/; #多實例 利用upstream來轉發
#proxy_pass http://192.168.31.101:8080/; #單實例直接指定後端api地址
#根據是否有跨域需求修改
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,DELETE,OPTIONS;
#也可以單獨 附加請求頭,根據需要修改
#proxy_set_header your-custome-header "myHeader";
#proxy_set_header X-NginX-Proxy true;
}
}
}
react 項目配置服務於爬蟲的頁面TDK
user nginx;
worker_processes auto;
#error_log /var/log/nginx/error.log warn;
#修改 日誌輸出等級 配合下方 rewrite_log on; 可以在errlog中查看rewrite轉發日誌,方便調試
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
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"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
gzip on;
server {
listen 80;#HTTP 的端口
server_name localhost; #域名
charset utf-8;
#access_log logs/host.access.log main;
#此處是開啓rewrite日誌,並且需要把nginx的錯誤日誌級別改爲notice
rewrite_log on;
# 前端頁面
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri /index.html;#加上了這個,就可以在url後面直接加路由上配置path了。
}
# 多個預先生成的 供爬取的 html頁面
# 1.商城首頁 /front/shoppingIndex
# 2.幫助中心 /front/help
# 3.商品列表 /front/goodsList
# 4.直接採購 /front/directbuy
# 5.優質供應商 /front/highQualitySupplier
# 6.快速採購 /front/rapidbuy
location ~ /front/(shoppingIndex|help|goodsList|directbuy|highQualitySupplier|rapidbuy)/?$ { #?表示0個或者1個/
root /usr/share/nginx/html;
index index.html;
try_files $uri /index.html;#加上了這個,就可以在url後面直接加路由上配置path了。
#設置一個 判斷是否爲爬蟲的 變量
set $isspider no; #默認不是爬蟲
#爬蟲判斷(谷歌、百度、360、微軟)
if ($http_user_agent ~* .*(Googlebot|Baiduspider|360Spider|bingbot).*){
set $isspider yes; #是爬蟲
}
#如果是爬蟲的話 則重寫到 front 文件夾中 的對應靜態html
if ($isspider = yes) {
rewrite ^(.*)$ $1.html break;
#permanent;
#rewrite ^(.*)$ /prerender/index3.html break;
}
}
error_page 404 /html/404.html;
# redirect server error pages to the static page /50x.html
#
error_page 502 503 /html/502.html;
error_page 500 504 /50x.html;
location = /50x.html {
root html;
}
}
}
參考鏈接:https://www.runoob.com/w3cnote/nginx-setup-intro.html