Nginx基礎

一、基本原理
1.linux上安裝nginx
https://www.cnblogs.com/hdnav/p/7941165.html
2.如果正常啓動後無法訪問,那有可能是linux系統防火牆開啓着
3.nginx支持高併發的原因(架構) :
(1)架構圖
在這裏插入圖片描述
(2)主進程:
Nginx啓動後會生成兩種進程,一種是主進程(master),一種是工作進程(worker),工作進程是主進程的子進程 主進程不負責網絡通信,只是管理worker進程,主要做三件事:
i.加載配置;ii.啓動workers;iii.非停重啓即./nginx -s reload

至少兩個進程
在這裏插入圖片描述
(3)worker進程
i.每個worker進程中只有一個主線程,採用的是異步非阻塞的方式處理請求,要處理請求就是建立連接,接收發送數據,其實就是讀寫事件,如果是阻塞調用,那事件沒準備好,線程就得一直等待,對於單線程,如果網絡事件越來越多,那可能很多都沒準備好,cpu就空餘了出來,使用率上不去;
(3)nginx的做法是採用異步非阻塞事件驅動模型,同時監控很多事件,單線程在請求之間不斷地切換而已,切換也是因爲異步事件未準備好,而主動讓出的。這裏的切換是沒有任何代價,因爲實際上是循環處理多個準備好的事件,好處是:不用創建很多線程佔用內存資源,不用線程間上下文切換,併發再多也不用擔心切換問題,只是會多佔用一點內存而已;.多進程單線程的工作方式;參考:https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale/
(4)worker的數量跟cpu核數一般相等,一個worker能夠同時處理成百上千同時活躍的連接數(原因如3所描述)
(5)更新配置升級時 主線程指揮worker做兩件事:
i.重新加載配置文件,並配置一組新的worker(進程號跟之前的完全不同),新的worker會馬上開始工作
ii.指示舊的工作進程正常退出 ,工作進程停止接受新連接,但是會直到http發送數據完畢,一旦所有連接都關閉,則工作進程就退出

4.nginx常用命令

nginx -c /usr/local/nginx/conf/nginx.conf  ,-c指定配置文件路徑,如果不加則默認路徑 
nginx -s reload 重新加載配置文件
nginx -t 測試配置文件
nginx -s stop 停止nginx
nginx -V 顯示nginx版本和配置參數

參考 https://mp.weixin.qq.com/s/55poBxwC6LxZ4jecSAxuyA
5.nginx從容停止

ps -ef |grep nginx
kill -QUIT  nginx主進程號

6.nginx平滑重啓
(1)nginx -s reload 需要一定的nginx版本支持
(2)kill -HUP 主進程號 通過信號量平滑重啓
(3)ng平滑啓動的過程:
i.向master發送HUP信號
ii.master收到信號之後校驗語法
iii.創建新的worker進程來處理新的連接
iv.向之前的進程發送關閉監聽的命令,之前的老進程會繼續處理已經接收的請求,不再接收新的連接,處理完請求後關閉
7.驚羣效應
accept驚羣效應:以多進程爲例,在主進程創建socket描述符listenfd後,子進程能夠繼承該描述符,那當主進程 創建了socket後,子進程會監聽同一個端口,即都會調用accept()阻塞,當該端口接收到請求時,所有子進程都會被喚醒, 但競爭資源的情況下分最終只有一個子進程會處理請求,其他的子進程又會回到阻塞狀態太,這中間進程狀態的切換資源白白浪費,cpu佔用會瞬間升高
8.nginx中對驚羣效應的解決
在繼承socket描述符之前先競爭互斥鎖,搶到互斥鎖的最終會確定處理請求,其他的子進程依然保持阻塞狀態
9.信號控制 :通過kill 命令 向master進程發送信號

    TERM, INT 快速關閉
    QUIT 從容關閉
    HUP 平滑重啓,重新加載配置文件
    USR1 重新打開日誌文件,在切割日誌時用途較大
    USR2 平滑升級可執行程序
    WINCH 從容關閉工作進程

二、基本配置
完整配置示例

#運行用戶
#user  nobody;
# multiple workers works !工作進程
# 官網給的設置建議:最佳值取決於許多因素,包括(但不限於)CPU內核數,存儲數據的硬盤驅動器數以及加載模式。如有疑問,將其設置爲可用的CPU內核數將是一個不錯的開始
worker_processes  1;

#全局錯誤日誌及pid文件
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid指令 指定一個pid文件記錄nginx的主進程,默認是logs文件夾內
pid       logs/ nginx.pid;

#工作模式及連接數上限
events {
   #epoll是多路複用IO中的一種方式
   #use epoll
#單個後臺work process最大的併發連接數
#併發總數(最大客戶端連接數)= worker_processes 和 worker_connections 的乘積<=系統可操作的最大文件數
#worker_connections與內存大小有關係
#併發受IO約束,因此最大的併發數小於最大可打開的文件數,一般一G能打開10w文件
#如何查看系統能打開的文件句柄數:cat /proc/sys/fs/file-max 
#綜上:connections的值要根據worker_processes(一般等於CPU核數)和系統能操作的最大文件句柄數(VALUE)調整 使得
#connection*processes約等於最大VALUE
    worker_connections  32768;
    # max value 32768, nginx recycling connections+registry optimization = 
    #   this.value * 20 = max concurrent connections currently tested with one worker
    #   C1000K should be possible depending there is enough ram/cpu power
    # multi_accept on;
}


http {
    #include      /nginx/conf/naxsi_core.rules;
    #設置mime類型,由mime.type決定
    include       mime.types;
    default_type  application/octet-stream;
#設置日誌格式
    log_format  main  '$remote_addr $remote_port - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

#指定nginx是否調用sendfile函數來輸出文件(?)
    sendfile        on;
    #tcp_nopush     on;

    server_names_hash_bucket_size 128;

## Start: Timeouts 連接超時時間  ##
    client_body_timeout   30;
    client_header_timeout 30;
    keepalive_timeout     100;
    send_timeout          30;
    keepalive_requests    30;
## End: Timeouts ##
#開啓gzip壓縮
    #gzip  on;
#設置虛擬主機配置
   # server {
    #    listen       80;
     #   server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        ## Caching Static Files, put before first location
        #location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        #    expires 14d;
        #    add_header Vary Accept-Encoding;
        #}

# For Naxsi remove the single # line for learn mode, or the ## lines for full WAF mode
      #  location / {
            #include    /nginx/conf/mysite.rules; # see also http block naxsi include line
            ##SecRulesEnabled;
        	  ##DeniedUrl "/RequestDenied";
	          ##CheckRule "$SQL >= 8" BLOCK;
	          ##CheckRule "$RFI >= 8" BLOCK;
	          ##CheckRule "$TRAVERSAL >= 4" BLOCK;
	          ##CheckRule "$XSS >= 8" BLOCK;
       #     root   html;
        #    index  index.html index.htm;
       # }

# For Naxsi remove the ## lines for full WAF mode, redirect location block used by naxsi
        ##location /RequestDenied {
        ##    return 412;
        ##}

## Lua examples !
#         location /robots.txt {
#           rewrite_by_lua '
#             if ngx.var.http_host ~= "localhost" then
#               return ngx.exec("/robots_disallow.txt");
#             end
#           ';
#         }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
       # error_page   500 502 503 504  /50x.html;
       # location = /50x.html {
        #    root   html;
       # }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000; # single backend process
        #    fastcgi_pass   myLoadBalancer; # or multiple, see example above
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
   # }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #虛擬主機1
    server {
        listen       8030;
#主機名多個時 直接空格分開;
##格式1 全名稱
##格式2 *.server2.com
##格式3 nginx.server2.*
##正則表達式配置時要加~,eg:server_name ~ ^www\.\d+\.com$
##以上幾種匹配的優先級依次降低   
#NGINX虛擬主機方式有三種:基於域名、基於端口、基於IP
#1)基於端口,即監聽的端口不一樣時,則是以端口爲準(以往的配置)
#2)基於域名的配置,即當兩個虛擬主機都監聽80端口(即端口號一樣),這是則會根據配置的域名不同,請求不同server
#3)基於ip配置server_name 沒試過 不常用
    server_name    nginx.server1.com; #監聽域名,這裏的域名在windows的host裏要映射一下ip地址

  #location /{   
 #       proxy_pass http://serverswitch;
#	}
  location  / {
proxy_pass http://serverswitch;
#定義服務器默認網站根路徑的位置,相對路徑,相對於nginx根路徑
        root   html; #這個意思是說在nginx跟路徑下需要創建一個html目錄
               index index.html; #默認跳轉的路徑,這裏index.html就會在nginx根路徑/html下尋找
            }
}


    #    ssl                  on;
    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_timeout  5m;

    #    ssl_prefer_server_ciphers On;
    #    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    #    ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:ECDH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!eNULL:!MD5:!DSS:!EXP:!ADH:!LOW:!MEDIUM;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
	
		upstream serverswitch { #upstream的命名不能有下劃線,否則到RS中400錯誤
   server 127.0.0.1:8070 weight=5;
    server 127.0.0.1:8080 weight=5;
 server 127.0.0.1:8060 weight=5;
	keepalive 10;
	}
#虛擬主機2配置
 server {
    listen       8040;        #監聽8040端口
error_log logs/8040error.error error;
#主機名多個時 直接空格分開;
#格式1 全名稱
#格式2 *.server2.com
#格式3 nginx.server2.*
#正則表達式配置時要加~,eg:server_name ~ ^www\.\d+\.com$
#以上幾種匹配的優先級依次降低	
    server_name   localhost nginx.server2.com  *.server2.com; #監聽域名
    location  /{  
	root html;
	index index.html; 
        proxy_pass http://serverswitch;  
     }  
   # error_page   500 502 503 504  /50x.html;#錯誤頁
    location /test/ {
	rewrite  ^/(.*)  /test2.js  break;

	# proxy_pass http://serverswitch;
	#定義服務器默認網站根路徑的位置,相對路徑,相對於nginx根路徑
       root  html; #這個意思是說在nginx跟路徑下需要創建一個html目錄  
	 index index.html; #默認跳轉的路徑
    }
    location /test2.js {  #測試last和break區別用
	if ( $server_port = 8030 ) {
		return 404;
	}
     #  default_type application/json;
     return  http://www.qq.com;
    }
#配置nginx的狀態監控  
  # location  /nginx_status {
#stub_status on;
#access_log on;
 #  }


# #設定本虛擬主機的訪問日誌,main是上面定義的格式
       access_log  logs/nginx.access.log  main;

 }
#設置禁止訪問的資源
	#location ~/.ht{
	#deny all
	#} 
}


10.nginx虛擬主機配置
(1)虛擬主機:虛擬主機,就是把一臺物理服務器劃分成多個"虛擬"的服務器,每一個虛擬主機都可以有獨立的域名和獨立的目錄;體現在nginx.conf配置中就是多個server;爲nginx提供了在同一臺服務器,同一組nginx進程運行多個網站的功能,虛擬主機從外部訪問的角度來看,跟獨立的物理主機沒有任何區別
(2)主機名的配置以及轉發路徑配置見配置文件註釋
11.設置參考官網文檔
http://nginx.org/en/docs/beginners_guide.html
12.日誌配置與切割
(1)訪問日誌揭露客戶端訪問nginx的每個請求,可以看到用戶地域來源、跳轉來源、使用終端、某個URL訪問量等相關信息
(2)指令主要有兩條,log_format 設置日誌格式,access_log用來指定日誌文件的存放格式、路徑和緩存大小
(3)log_format配置解釋見上面配置文件,允許的變量有:

日誌格式允許包含的變量註釋,如下所示

$remote_addr, $http_x_forwarded_for 記錄客戶端IP地址

$remote_user 記錄客戶端用戶名稱

$request 記錄請求的URL和HTTP協議

$status 記錄請求狀態

$body_bytes_sent 發送給客戶端的字節數,不包括響應頭的大小; 該變量與Apache模塊mod_log_config裏的“%B”參數兼容。

$bytes_sent 發送給客戶端的總字節數。

$connection 連接的序列號。

$connection_requests 當前通過一個連接獲得的請求數量。

$msec 日誌寫入時間。單位爲秒,精度是毫秒。

$pipe 如果請求是通過HTTP流水線(pipelined)發送,pipe值爲“p”,否則爲“.”。

$http_referer 記錄從哪個頁面鏈接訪問過來的

$http_user_agent 記錄客戶端瀏覽器相關信息

$request_length 請求的長度(包括請求行,請求頭和請求正文)。

$request_time 請求處理時間,單位爲秒,精度毫秒; 從讀入客戶端的第一個字節開始,直到把最後一個字符發送給客戶端後進行日誌寫入爲止。

$time_iso8601 ISO86——01標準格式下的本地時間。

$time_local 通用日誌格式下的本地時間。

(4)access_log 設置路徑,見配置文件
access_log path(存放路徑) [format(自定義日誌格式名稱) [buffer=size | off]],這個屬性可以放在某個server中,每個server配置自己單獨的日誌
(5)日誌切割,其實就是類似於log4j的每隔一旦時間定時備份舊日誌文件
i.總體方法步驟;mv將原本的日誌重新命令,然後Kill USR1向nginx主進程發命令,重新生成一個日誌文件,使用crontab -e生成定時任務執行腳本
ii.sh腳本爲:

#!/bin/bash
echo 開始執行腳本$0
date=`date +%Y-%m-%d_%H:%M:%S`
path=/usr/local/nginx/logs
mv ${path}/server1.log  ${path}/${date}_server1.log
#發送kill -USR1信號給Nginx的主進程號,讓Nginx重新生成一個新的日誌文件
kill -USR1 `cat ${path}/nginx.pid`
echo 腳本$0執行結束===

iii.定時任務:執行上述腳本

crontab  -e
25 21 * * * /bin/bash /home/shtest/nginx_log_config.sh

13.壓縮輸出配置
(1)壓縮的原因是如果不壓縮,大量的前臺返回會佔用很多帶寬,導致傳輸和響應速度下降
(2)nginx具體配置如上所示,基本就是上面的配置,圖片和視頻一般不壓縮,太耗cpu,解壓效果也不穩定
(3)壓縮前後對比,主要由壓縮比控制
在這裏插入圖片描述
在這裏插入圖片描述
(4)判斷網站是否有壓縮 查看response head,有gzip標誌則意味着有壓縮
在這裏插入圖片描述
三、負載均衡策略
1.什麼是負載均衡?
在存在提供多個相同服務的服務器情況下,即集羣環境中,負載均衡設備比如nginx在大量請求訪問來臨時,根據配置的負載均衡算法,將流量
均衡的分配給後臺的服務器,防止在總體能力有結餘的情況下發生某臺服務器因請求過多而導致響應變慢,甚至宕機;在存在負載均衡的情況下,對
客戶端而言,RS(實際服務器)的地址即是負載均衡設備的虛擬IP地址,RS對於客戶端是不可見且爲止的
2.什麼是反向代理和正向代理?
正向代理的過程,它隱藏了真實的請求客戶端,服務端不知道真實的客戶端是誰,客戶端請求的服務都被代理服務器代替來請求,某些科學上網工具扮演的就是典型的正向代理角色。用瀏覽器訪問狗哥時,被殘忍的block,於是你可以在鍋外搭一臺server,讓proxy幫我去請求狗哥,代理把請求返回的相應結構再返回給我。
反向代理是代理的服務端,正向代理是代理的客戶端
3.nginx負載均衡的方式
參考 https://mp.weixin.qq.com/s/EdmQQEXn2AGxu91g_uDYSA
(1)輪詢(默認)
請求按照時間順序逐一分發到配置的後端真實的服務器上,如果有down掉則剔除
i.配置

	
		upstream serverswitch {
   server 127.0.0.1:8070; 
    server 127.0.0.1:8080; 
 server 127.0.0.1:8060 ;
	}

ii.測試結果
在這裏插入圖片描述
直接kill掉8080的進程之後:
在這裏插入圖片描述
(2)按照權重分配
使用場景:weight和服務器被訪問的機率成正比,用於解決後端服務器性能不均的情況
測試結果:
在這裏插入圖片描述
(3)ip_hash,對客戶端ip進行hash,以後只要是同一個ip的訪問都定位到一個後臺服務器上,這樣能避免session無法共享的問題出現
i.配置

                upstream serverswitch {
   server 127.0.0.1:8070 ;
    server 127.0.0.1:8080 ;
 server 127.0.0.1:8060  ;
ip_hash; //ip_hash 
        }

ii.測試:當改配置並熱重啓後會發現後面來自同一個ip的請求都會被轉發到同一個後臺服務器上
在這裏插入圖片描述
iii.ip_hash的負載均衡方式有侷限性要求nginx必須爲最前端的服務器,同時後端必須直接連接真是服務器,不能有其他代理機器
如果不是最前端,那進行hash的ip始終是同一個,即代理機前面的代理機,那所有的請求最終都會請求到同一個服務器上,失去了負載均衡的作用;
如果後面不是真實的服務器,那經過hash的同一個ip會因爲後面的代理機配置的負載均衡方式的不同而導致無法始終訪問到同一個服務器
(4)fair模式,第三方模塊,一般正常下載了nginx之後,還要再另外下載
按後端服務器的響應時間來分配請求,響應時間短的優先分配

upstream backserver {
    server server1;
    server server2;
    fair;
}

(5)url_hash 通過將url進行hash之後一般請求固定的RS,適用於服務器做了緩存的場景,不太理解
配置:
在這裏插入圖片描述
效果跟ip hash 有點像,都是同一個url請求同一個服務器
4.關於每個RS設備狀態的配置
(1)down 標記該RS暫時不參與負載均衡
配置

 upstream serverswitch {
         #  hash $request_uri;
           server 127.0.0.1:8070  down;
           server 127.0.0.1:8080  backup;
           server 127.0.0.1:8060  ;
        }

測試結果:此時少了一臺down掉的服務器
在這裏插入圖片描述
(2)backup
官網上的解釋:只有當非backup的RS不可用時,纔會使用該RS,配置類似於down,效果也類似
在這裏插入圖片描述
(3)weight=number,默認都是1,設置訪問頻率
(4)max_conns=number
限制number到代理服務器的同時活動連接的最大數量(1.11.5)。默認值爲零,表示沒有限制。如果服務器組未駐留在共享內存中,則此限制在每個工作進程中均有效。
(5)max_fails=number,未測試,來自官網說明
請求失敗的次數,默認情況下,未成功嘗試的次數設置爲1,當超過最大次數時,則返回 proxy_next_upstream, fastcgi_next_upstream, uwsgi_next_upstream, scgi_next_upstream, memcached_next_upstream和 grpc_next_upstream 指令定義。
(6)fail_timeout=time
在指定次數的不成功嘗試與服務器通信的時間內應該碰巧認爲服務器不可用;
以及服務器將被視爲不可用的時間段。默認情況下,該參數設置爲10秒,會暫停服務
(7)官網 參考http://nginx.org/en/docs/http/ngx_http_upstream_module.html#server
5.nginx的作用和優勢
在這裏插入圖片描述
6. Location配置
ps:兩種404的區別
在這裏插入圖片描述
在這裏插入圖片描述
(1)四種可選擇標識符
i.= 精確匹配 要求請求的字符串和配置的uri嚴格匹配,匹配後則返回
eg:location = /test/ {} 請求爲 http://192.168.1.108:8040/test/50x.html報apach的404
該精確匹配只能訪問個默認的主頁了,因爲路徑後面不能加別的,否則訪問不到
ii.~表示區分大小寫的正則匹配
eg:

location  ~ /inner/{} //只要路徑中出現inner就能匹配進去,
location ~ /[A-Za-z]nner{} // 請求:http://192.168.1.108:8040/test/Anner/ 可以匹配
location ~  /inner/.+\.(gif|css|png|js)$ {}  //匹配路徑中含有inner以及結尾必須是那幾個的請求   http://192.168.1.108:8040/test/inner/1.js 能進去  
http://192.168.1.108:8040/test/inner/.js  進不去,因爲.js前面要求至少一個字符

iii. ~ 不區分大小寫的正則匹配*
location ~* /inner/ {} 請求 :http://192.168.1.108:8040/tesA/INNer/ 可以匹配 匹配成功後立即結束
iv. ^~ 不進行正則,只匹配以關鍵字開頭的uri,大小寫敏感
location ^~ /inner/ {} 請求:http://192.168.1.108:8040/inner/50.html 可以進
http://192.168.1.108:8040/Inner/ 不能匹配
v 普通匹配

location  /inner/ {  請求:http://192.168.1.108:8040/inner/test/50.html 可以匹配
http://192.168.1.108:8040/test/inner/50.html 無法匹配
  # 與location順序無關
  # 若完全匹配成功,就不在繼續匹配,否則還會進行正則匹配
}

(2)結合標識符,匹配順序如下

  1. =精確匹配>^~頭字符匹配 >正則表達式 >前綴匹配, location ~ /test/{} //正則
location  /test/{} 和 location ^~/test/{}不能同時存在 nginx檢查不通過
location ^~/test/test{} 頭字符匹配
location /test/{} 前綴匹配
eg:location ~/{}  和 location /{}  這第一個是正則,第二個是前綴,同時存在的話只會進第一個正則,因爲正則>前綴

2)正則表達式都能匹配則按location配置的順序進行,匹配成功後結束匹配
3)正則沒匹配到,而前綴匹配匹配到的話,則使用前綴匹配,先匹配正則,匹配完****後沒有成功則配前綴,匹配到則進前綴
4)都是前綴匹配,則匹配最長爲原則

location /{} 和location /test/{} 這兩個,請求爲host/test/時 進第二個,因爲第二個前綴比第一個長 

(3)root和alias配置,alias暫時沒成功實驗出
(4)備註
備註;root test/; 這個表示nginx的主目錄下的test/文件夾裏找
root /test/;這個表示從linux服務器根路徑下找test文件夾中的文件
index index.html ;表示默認主頁爲index.html
備註:location = /test/inner/{} 匹配後面一定要加上最後的斜槓,即最後一個斜槓必須有,否則請求進不來
ps:配置爲root時 location中的路徑會算到真實物理路徑中去
location = /test/inner/{root html;} 這種最終找的是 nginx/html/test/inner中的文件
如果轉發到RS的請求,那麼location的路徑會算到真實請求路徑中去
location = /cluster1/{ proxy_pass http://serverswitch;root html;}後臺請求的根路徑就是cluster1
ps:location配置代理轉發同時也配置nginx目錄,那對於同一個(請求路徑上啊完全相同)資源會先在RS上尋找,找到則直接返回,找不到纔會去nginx指定的目錄下去尋找
(5)nginx前後端分離,ajax請求後端時仍可以寫相對路徑,因爲仍是同一臺服務器,/斜槓開始的就表示只到端口號,即根路徑
location ~/test/{}
請求前端文件:

<script src="/test/js/test.js"></script> //在html頁面請求js時路徑也要滿足location的配置,才能請求到

請求後端:

$(document).ready(function(){
        $.ajax({
        type: "GET",
        url: "/cluster1/cluster",  //相當於http://192.168.43.152:8040/cluster1/cluster,這個根路徑是相對於nginx根路徑而言的
        success: function(data) {
		alert("request success")
            //    $("#get_data").html(data)
        },
        error: function() {
                alert("fail!!,請刷新再試!");
        }
        });
});

(5)實際使用時的配置至少有三個匹配規則定義

#直接匹配網站根,通過域名訪問網站首頁比較頻繁,使用這個會加速處理,官網如是說。
#這裏是直接轉發給後端應用服務器了,也可以是一個靜態首頁  
# 第一個必選規則  
location = / {  
    proxy_pass http://tomcat:8080/index  
}  

# 第二個必選規則是處理靜態文件請求,這是nginx作爲http服務器的強項  
# 有兩種配置模式,目錄匹配或後綴匹配,任選其一或搭配使用  
location ^~ /static/ {  
    root /webroot/static/;  
}  
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {  
    root /webroot/res/;  
}  

#第三個規則就是通用規則,用來轉發動態請求到後端應用服務器  
#非靜態文件請求就默認是動態請求,自己根據實際把握  
#畢竟目前的一些框架的流行,帶.php,.jsp後綴的情況很少了  
location / {  
    proxy_pass http://tomcat:8080/ 
}   

7.nginx的rewrite規則
(1)作用:總體作用就是重定向
i.場景一 網址換新域名後,舊的訪問跳轉到新域名上
ii.動態url僞裝成績靜態地址
(2)語法: rewrite ‘<regex’> <'replacement> flag
i.關鍵字rewrite 不可修改
ii.正則,即匹配的url模式,但凡符合該正則的url都會被重定向
iii.替代內容是當正則匹配成功之後,用來替換原本的url並跳轉的新地址
iv.flag標記:last和break的區別見下面,都能攔截來自客戶端的請求,然後重新發起替換之後的新請求;redirect 返回302臨時重定向,瀏覽器url會跳轉;permanent 返回301永久重定向,瀏覽器會跳轉url顯示;
v.301和302的區別 301永久重定向是響應會緩存,一般都使用301永久重定向符合url規定;302臨時重定向,響應不會緩存,除非設置catche-control,默認是不緩存的
(3) 案例:

  location /test/ {
rewrite  ^/(.*)  /test2/  break(或者last);
}
  location /test2/ { 
default_type application/json;  
return 200 '{"status":"success"}';
}
//如果是break/last,可以通過瀏覽器請求 http://192.168.43.152:8040/test/,網絡中顯示的是直接請求的http://192.168.43.152:8040/test/,頁面返回的是test2中的信息,不改url只改內容
//如果是redirect, 則瀏覽器網絡中查看能看到發起了兩個請求,第一個返回302,第二個200,頁面顯示test2內容,url發生重定向
//如果是permanent  則瀏覽器網絡中查看能看到發起了兩個請求,第一個返回301,第二個200,頁面顯示test2內容,url發生重定向

(4)rewrite只能放在server{},location{},if{}中
i.執行順序:先執行server中的rewrite,再執行匹配到的location,最後再執行匹配到的location中的rewrite
i.last一般寫在server和if中,break一般在location中
(5)if指令和內容如下
i.if指令的內容:表達式爲變量時,值爲空或者以0開頭,則爲fasle;
ii.使用=和!=比較值和內容大小;
iii. 正則表達式匹配,*不區分大小寫的匹配,!~區分大小寫的不匹配
iv.-f和!-f用來判斷是否存在文件;-d和!-d用來判斷是否存在目錄;-e和!-e用來判斷是否存在文件或目錄
v舉例:

location /test2/ { 
if ( $server_port = 8030 ) { //此處的if後面一定要有空格,變量左右也要有空格,rewrite的語法要求非常嚴格
return 200 'dfd';
}
  return 404; // 請求urlhttp://192.168.43.152:8040/test2/,頁面會顯示404
}

(6)nginx全局變量
下面是可以用作if判斷的全局變量

$args#這個變量等於請求行中的參數,同$query_string;$content_length :請求頭中的Content-length字段。
$content_type :請求頭中的Content-Type字段。;$document_root :當前請求在root指令中指定的值。
$host :請求主機頭字段,否則爲服務器名稱。
$http_user_agent :客戶端agent信息;$http_cookie :客戶端cookie信息
$limit_rate :這個變量可以限制連接速率。;$request_method :客戶端請求的動作,通常爲GET或POST。
'$remote_addr :客戶端的IP地址。;$remote_port :客戶端的端口。
'$remote_user :已經經過Auth Basic Module驗證的用戶名。;$request_filename :當前請求的文件路徑,由root或alias指令與URI請求生成。
$scheme :HTTP方法(如http,https)。;$server_protocol :請求使用的協議,通常是HTTP/1.0或HTTP/1.1。
$server_addr :服務器地址,在完成一次系統調用後可以確定這個值。;$server_name :服務器名稱。
$server_port :請求到達服務器的端口號。;$request_uri :包含請求參數的原始URI,不包含主機名,如:”/foo/bar.php?arg=baz”。;$uri :不帶請求參數的當前URI,$uri不包含主機名,如”/foo/bar.html”。
$document_uri :與$uri相同。
(7)**return指令的用法**:
i.語法: return code [text];return code URL;return URL
ii.3xx系列響應碼,url定義了重定向的路徑; (1xx | 2xx | 4xx | 5xx) ["text"]需要定義返回的文本
iii.其他系列 如4xx系列 2xx系列,可以定義狀態碼加http標準文本進行正文返回,對於404,有些是瀏覽器已經定好了頁面
eg:return  http://www.qq.com ; // 這樣直接重定向,返回的狀態碼爲302,必須加請求協議,否則會當成返回碼處理,然後報錯
return 301  www.qq.com  //返回的狀態碼爲301
return 200 '{"status":"success"}'

iv.參考:https://hacpai.com/article/1543136511525
(9)last和break的區別
i.只在location中有區別,在server中沒區別,都可以進行重定向
ii.break能夠阻止進一步重定向發起新請求到location中,而last會進行重定向
eg:

 location /test/ {
rewrite  ^/(.*)  /index.html  break(last); 
   root  html; #這個意思是說在nginx跟路徑下需要創建一個html目錄  
 index index.html; #默認跳轉的路徑
    }
location /index.html {
if ( $server_port = 8030 ) {
return 404;
} 
break時請求  http://192.168.43.152:8040/test/ 會跳轉到root/test/index.html頁面,不會發起新的請求,進入後面的location
last時,請求同樣的則會跳轉並請求新的location /index.html.返回頁面404

iii.經測試,如果rewrite中是以下的配置,則break無法阻止發起新的請求匹配location
eg:

 location /test/ {
rewrite  ^/(.*)  /index  break; 
   root  html; #這個意思是說在nginx跟路徑下需要創建一個html目錄  
 index index.html; #默認跳轉的路徑
    }
location /index {
if ( $server_port = 8030 ) {
return 404;
} 
//請求的 http://192.168.43.152:8040/test/ 會重新匹配到location /index 返回404頁面

iv.總結 當rewrite替換的路徑是文件的話,break起效果,直接請求本location中對應的文件,如上述第一個例子;如果是路徑,則break跟last效果一樣,目前測試的結論,未必準確
v.區別參考:https://blog.csdn.net/qq_37369726/article/details/102805695
(8)參考https://mp.weixin.qq.com/s/w_wuwdEzx5HPST0fsB5Dyg
ps:upstream的命名不能有下劃線,否則到RS中400錯誤,類似其他的location等也不能有下劃線

發佈了86 篇原創文章 · 獲贊 5 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章