一、安裝
1、nginx安裝:
wget http://nginx.org/download/nginx-1.15.8.tar.gz
tar -zxvf nginx-1.15.8.tar.gz
cd nginx-1.15.8
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
#配置
#--prefix指定安裝目錄
#--with-http_ssl_module安裝https子產品
#creating objs/Makefile 代表編譯成功
make && make install
#make編譯
#make install安裝
2、echo安裝
先進入到nginx源碼目錄,如/usr/local/nginx-1.15.8
下載下傳:wget https://github.com/openresty/echo-nginx-module/archive/v0.61.tar.gz
解壓:tar -zxvf v0.61.tar.gz
配置:
./configure --add-module=/usr/local/nginx-1.15.8/echo-nginx-module-0.61 --with-http_ssl_module --with-debug
編譯&安裝:
make && make install
需要注意的是:如果在使用location中使用echo指令的話,需要将default_type的值指定為text/plain;
二、Location
在圖中,整個請求位址中包含“ip端口或域名”和“path路徑”兩個部分。其中nginx在路徑比對的時候,會把整個path去做比對。
1、空類型的比對
是指location就是一個“/”,如下圖
2、一般比對
是指除了精準比對之外的其它的比對。
在一般比對中,會按照最長的比對原則進行比對,什麼意思呢?
就是除了精準比對的location,隻要location們被path所包含,那麼這些location們是參與比對的,但是最後隻是取了長度上最長的那個location了。但是有一個要求,被比對中的所有的location的長度必須是小于請求路徑中域名端口後面的一段path。如圖:
但是需要注意的是,如果輸入的path和location都沒有比對中,并且存在一個空值的location,那麼還是會去比對這個空的,如下圖:
3、= 精準比對
當uri部分完全比對上了,才路由到該location中,并且直接傳回,哪怕後面存在其它的一些正則的location,也不會再去比對了。如圖:
但是需要注意的是:精準比對是不參與一般比對的,如下圖:
4、 ~ 不忽略大小的正則比對
比對規則如下圖:
5、~* 忽略大小寫的正則比對
它的比對規則同“~”
6、 ^~ 非正則比對
比對規則如下圖:
7、優先級:
優先級流程圖:
8、root(它不是指令,隻是起到一個聲明的作用,相當于java中的int、float.....等)
但是,如果上面圖中不寫 “root /xxx/xxx”的話,那麼nginx就是去找預設目錄,即“/usr/local/nginx/html”,如果是用自義的目錄,那麼就必須使用root 指定。在實際使用中最好使用絕對目錄,而少用相對目錄。
【注意】:root 後面跟的目錄要不要“/”都一樣
9、alias(它不是指令,隻是起到一個聲明的作用,相當于java中的int、float.....等)
10、反向代理: proxy_pass
需要注意的是:“/”是表示關閉的意思,可以從下面兩個圖了解。寫法如下:
如這個圖所示,圖中說明在這種情況下proxy_pass中後面有無“/”的差別
如這個圖如所示,圖中說明在這種情況下proxy_pass中後面有無“/”的差別
【注意】:此處“/”關閉與否,隻針對于ip+port而言的,如果ip+port後面跟了其它的東西(如127.0.0.1:8080/xxx),則有無“/”的效果是一樣的,而ip+port後面沒有跟其它的東西,則有無“/”的效果是不一樣的。
這裡總結一下:
如圖,一個請求位址是由圖中的幾個部分組成。
1、如果location的如下圖中:
那麼真正代理後的請求位址為http://ip:端口/path1/path2。為什麼是這樣呢?
因為在此處的proxy_pass的最後沒有寫“/”,也就是沒有關閉,是以就會把path1+path2拼接後一起代理到真實的伺服器了,即
http://127.0.0.1:8080/locationpath/otherpath?param=xxoo
2、如果location如下圖:
那麼真正代理後的請求位址為http://ip:端口/path2。為什麼是這樣呢?
因為在此處的proxy_pass的最後有寫“/”,也就是關閉,是以隻會把path2代理到真實的伺服器,即
http://127.0.0.1:8080/otherpath?param=xxoo
3、如圖location如下圖:
那麼真正代理後的請求位址為http://ip:端口/projectname/path2。為什麼是這樣呢?
因為在此處的proxy_pass的端口後有寫“/”,也就是關閉,是以隻會把path2代理到真實的伺服器。即
http://127.0.0.1:8080/projectname/otherpath?param=xxoo
11、upstream 負載均衡
如上面圖中所示,“ttt”相當于是對被負載的伺服器作統一管理而取的名稱,server指的是向nginx說明它是一個伺服器,weight是表示權重,也就是說在被反向代理的時候,nginx會去輪詢”ttt”裡面的伺服器,有2/3的命中“192.168.1.10:8080”這個伺服器,有1/3的命中“192.168.1.102:8080”這個伺服器。如果通路url為“www.enjoy_4/upstream_test/xxxx”,那麼最終發送後是http://192.168.1.10:8080/xxxx和http://192.168.1.102:8080/xxxx,如果不權重weight不指定的話,那麼就相當于是weight = 1,也就是說均勻的各一次。一個.conf檔案中可以有多個upstream配置
拓展一下,如下圖:
結合這兩張圖,可以了解為:将upstream(ttt)裡面指定的ip:port替換掉proxy_pass中指向的upstream(即上圖中的“ttt”)
12、rewrite
文法 :
rewrite regex replacement [flag]; 其中regex-正則,replacement-替換後面的結果, flag-處理的标志
flag=【break/last/redirect/permanent】
^/ 表示進入location後無論是什麼都是比對的。
如/xx.js,那麼這樣總是報錯的。
一個location中可以有多個rewrite
(1)redirect
permanent-也會和redirect一樣的效果,隻是一個是301重定向,一個是302重定向
(2)break;
如果rewrite後面沒有被break打斷的話,那麼就有機會觸發下一輪從上往下進行location的比對,也就是需要将目前的location走完,然後再去比對新的location了;但是使用last就會提前觸發下一輪從上往下進行location比對,也就是說不需要将目前的location走完,就去比對新的location了。
對break的有無總結:
有則直接被打斷,無論其後有沒有其它的rewrite,也不再去比對新的location了,若有root聲明,就會去root聲明的目錄下找資源;
無則不會被打斷,在目前的location中還是會依然自上往下走的,比如有在目前的location中寫了多行rewrite,并且這些reswrite後均沒 有break的話,則最後一行rewrite生效,若有root聲明,也不會去root聲明的目錄下找資源,而是離開目前的location,去新的location 中做比對。
流程圖如下:
還需要注意一點的是rewrite不僅可以寫在location裡面,還可以寫在location外面,也可以實作對域名作重定向。如下圖:
什麼意思呢? 也就是說如果請求位址為:http://sales.enjoy.com,最後會跳轉到https://sales.enjoy.com
13、index指令的執行時機
url 以 /結尾時,如:http://location.enjoy.com/static/,指的是一個目錄,nginx認為使用者沒有指定檔案, 是以會觸發index指令,找到頁面。
url 不是以 / 結尾,http://location.enjoy.com/static,認為它是個檔案,嘗試打開這個檔案,此時index指令不啟用,是以就會出現“301 Moved permanently”
14、執行階段
三、日志
四、其它知識要點
1、nginx内置變量
以下是常用的
$host:請求中的主機頭(Host)字段,如果請求中的主機頭不可用或者空,則為處理請求的server名稱
$http_HEADER : HTTP請求頭中的内容,HEADER為HTTP請求中的内容轉為小寫,
-變為_(破折号變為下劃線),例如:$http_user_agent(Uaer-Agent的值)
$remote_addr 用戶端的IP位址。
$remote_port 用戶端的端口。
$request_method 這個變量是用戶端請求的動作,通常為GET或POST。
$request_uri 這個變量等于包含一些用戶端請求參數的原始URI
$scheme 所用的協定,比如http或者是https
$server_name 伺服器名稱。
$request_filename 檔案名稱,對應的是url中的uri部分,如請求路徑為“http://www.enjoy.com/static/a.html”,那麼它對應的值就是“/static/a.html”。
$server_port 請求到達伺服器的端口号。
$server_protocol 請求使用的協定,通常是HTTP/1.0或HTTP/1.1。
$uri 請求中的目前URI(不帶請求參數,參數位于$args)
常量輸出,如下圖:
2、If指令
nginx中隻有if,沒有else和else if。
If可以寫在location之間,也可以寫在location之後,還可以在location内部。
靜态資源: location ~ /rex/.*\.(htm|js|css)$
域名校驗:if ( $http_origin ~ http://(.*).enjoy.com)
浏覽器校驗:if ($http_user_agent ~ Firefox)
具體用法如下圖:
3、跨域
解決跨域的辦法為在.conf檔案中加入以下内容,一個固定的寫法:
if ( $host ~ (.*).enjoy.com){
set $domain $1;##記錄二級域名值
}
#是否允許請求帶有驗證資訊
add_header Access-Control-Allow-Credentials true;
#允許跨域通路的域名,可以是一個域的清單,也可以是通配符*,也可以具體的幾個域名,使用空格連接配接
add_header Access-Control-Allow-Origin http://static.enjoy.com; #表示,隻要是從這個指定的域名過來的請求,都能跨域請求
#允許腳本通路的傳回頭
add_header Access-Control-Allow-Headers 'x-requested-with,content-type,Cache-Control,Pragma,Date,x-timestamp';
#允許使用的請求方法,以逗号隔開
add_header Access-Control-Allow-Methods 'POST,GET,OPTIONS,PUT,DELETE';
#允許自定義的頭部,以逗号隔開,大小寫不敏感
add_header Access-Control-Expose-Headers 'WWW-Authenticate,Server-Authorization';
#P3P支援跨域cookie操作
add_header P3P 'policyref="/w3c/p3p.xml", CP="NOI DSP PSAa OUR BUS IND ONL UNI COM NAV INT LOC"';
add_header test 1;
if ($request_method = 'OPTIONS') { ##OPTIONS類的請求,是跨域先驗請求
return 204; #204代表ok
}