前置知識章節:
1.介紹、安裝、hello world、location匹配 ✅
2.▶▶反向代理、負載均衡、緩存服務、靜態資源訪問✅
3.日誌管理、http限流、https配置,http_rewrite模塊,第三方模塊安裝,結語。✅html
💡代理有正向代理和反向代理
💡正向代理:
所謂的正向,就是以請求發起爲角度的,此時代理的是用戶發起的請求。
用戶A沒法訪問G網,但A能訪問B網,而B網能訪問G網。那麼若是A先經過訪問B網,B網幫他訪問G網,返回數據給他,那麼此時B網就做爲了一個代理服務器,並且是正向代理。此時A實際上是知道它要訪問G網的,G網並不知道是A訪問它的,因此此時是代理了A,正向代理。前端
💡反向代理:
相對於正向代理的代理用戶發起的請求,反向代理代理的是資源服務器的請求。
用戶A訪問B網的某個資源,但B網沒有,而後它發給C網,C網返回給B網,B網返回給C網。此時用戶A不知道它訪問的是C網,因此此時代理的是C網,反向代理。
場景通常是,A能訪問B,但不能訪問C,B能訪問C。咱們使用B這臺機來對外提供服務,讓關於C的請求都先通過B,B再請求C來返回結果。
反向代理有時候用在內網中,用來作請求轉發到內網,這樣必定程度的保護了內網的資源和利用上了內網的服務器。固然對於咱們業務來講,服務器有可能並非部署在內網中的,也能夠用在外網服務器代理上。java
💡反向代理是一個很是重要的功能,能夠說nginx你最經常使用的功能或許就是反向代理了,動靜分離、負載均衡和緩存有時候你可能用不上。nginx
咱們首先須要建立一個web服務端,因爲我是主攻java的,因此我這裏部署一個java的web服務器,並讓他監聽8081端口。(192.168.48.131是個人虛擬機的IP,nginx和這個java web服務端都部署在這裏。)
訪問一下這個要被代理的服務端的接口http://192.168.48.131:8081/user/list
,發現調用成功。
git
💡2.1 修改server:
由於此時是做爲一個代理服務器,因此咱們要新建一個server塊來充當代理服務器。
❓有人有點疑惑,上面的例子只配了location,咱們爲何要配server呢?
其實這裏是從業務需求來作區分的。由於咱們如今的目標是弄一個代理服務器,固然了你也能夠不建立,而後把下面的location放到以前的server下便可。何時是必須建立的呢?當server_name不同的時候,但這個也是須要你根據業務來判斷的,好比你本來使用80端口接收發過來的請求,而如今使用8080端口接收發過來的請求的時候就須要一個新的server_name。
這裏新建一個server其實也有介紹server_name的用法的意思。github
修改server_name:server_name是當前服務端監聽的地址的意思,
server_name支持幾種語法:web
server_name example.com www.example.com
*
只能使用在開頭或者結尾,不能使用在中間。當有多個匹配結果的時候,會選擇最長的匹配結果。server_name *.example.com www.example.*
server_name ~^www\d+\.example\.com$;
💡2.2 修改location
🔵proxy_pass
用於設置被代理服務器的地址,能夠是主機名稱(https://www.baidu.com
這樣的)、IP地址(域名加端口號)的形式。
🔵下面的這個location的意思是,若是請求路徑開頭是/api的,那麼都代理到proxy_pass指定的地址,好比訪問了/api/user/list
,那麼獲得的結果是http://localhost:8081/user/list
的結果。正則表達式
server { listen 8080; location /api/ { proxy_pass http://localhost:8081/; } }
🔵在lcoation都是location /api/
時,proxy_pass不一樣,請求的資源也是不同的:redis
proxy_pass http://localhost:8081;
:請求nginx主機IP:8080/api/user/list
,nginx會將該請求代理轉發到http://locahost:8081/api/user/list
。proxy_pass http://localhost:8081/;
:請求nginx主機IP:8080/api/user/list
,nginx會將該請求代理轉發到http://locahost:8081/user/list
。proxy_pass http://localhost:8081/test;
請求nginx主機IP:8080/api/user/list
,nginx會將該請求代理轉發到http://locahost:8081/testuser/list
。proxy_pass http://localhost:8081/test/;
請求nginx主機IP:8080/api/user/list
,nginx會將該請求代理轉發到http://locahost:8081/test/user/list
。在前面,我建立了一個8081的web服務端,並且http://nginx服務器IP:8081/user/list
是有一個接口的.
咱們試一下使用8080來代理一下這個8081這個服務端:
注意下面的這個server若是寫在default.conf的時候,是與其它server塊同級的。
後端
若是咱們可以經過8080來訪問到http://192.168.48.131:8081/user/list
這個接口,那麼就說明了咱們的反向代理成功了。此時發向8080端口的,以/api
開頭的請求都會代理到8081中。
負載均衡其實也算是基於反向代理的。
上面的反向代理提到一點反向代理能夠爲咱們的服務端進行代理,你有時候多是多個服務端提供同一功能的,爲了讓他們可以平攤壓力,那麼你可能須要負載均衡功能。
🔴準備負載均衡用的業務服務端,我這裏給的是一個java Spring Boot端的簡單代碼,我部署成多個服務端的時候,因爲端口不一樣,訪問info接口返回的數據也不一樣,這樣就能夠測試是否達到了負載均衡。
🔴部署服務端,使用--server.port
來部署到不一樣的端口,例如java -jar a-simple-web-0.0.2-SNAPSHOT.jar --server.port=8082
就把個人jar程序部署到了8082端口。
咱們這裏新建一個conf.d/loadbalance.conf
,因爲nginx.conf內部有一個include /etc/nginx/conf.d/*.conf;
能夠把conf.d下的配置文件都導入到nginx.conf的http塊中,因此咱們新建的這個conf也是能夠導入到nginx.conf中的。
訪問http://192.168.31.128:9001/user/info
,看是不是輪詢的分發請求,若是響應的時候返回了不一樣的端口,那麼就證實了是輪詢的分發請求。
💡默認輪詢負載均衡:在不指定負載均衡策略的時候,默認的策略是按順序給負載均衡服務端發送請求,而且一次順序中每一個服務端處理兩次請求,好比兩個服務端,那麼就是AABBAABB這樣循環下去。 若是服務端有宕機的,會從負載均衡順序中去除。等到宕機的服務端可用後,會在30S(好像是)以後加入到可用負載均衡服務端列表中。
💡加權輪詢負載均衡:在輪詢的基礎上加上權重的考慮,假如服務端A的權重是1,服務端B的權重是2,那麼6個請求中,服務端A會收到2個請求,服務端B會收到4個請求。
💡ip_hash負載均衡:每一個請求按ip的哈希結果分配到指定的負載服務端響應,(原理相似求餘數,把服務端排序以後,根據哈希處理再處理以後獲得的餘數來選取服務端),這樣同一個ip響應的服務端是固定的。能夠在必定程度解決服務端Session共享的問題。但這樣可能負載壓力就分配的不平均了。
語法例子:
upstream ip-hash { ip_hash; server localhost:8081; server localhost:8082; }
💡也可使用第三方模塊來負載均衡。但因爲咱們上面沒有講過第三方模塊,引入前置知識須要佔用大量篇幅,因此這裏只引出一下,有須要的自查吧。
上面介紹了使用weight參數來實現加權輪詢負載均衡,其實還有一些其餘的參數。
upstream web-server { server localhost:8081 max_fails=1 fail_timeout=10; server localhost:8082; server localhost:8083 backup; server localhost:8084 down; }
💡使用ip_hash時,不能使用weight和backup。
💡在瀏覽器訪問某個網站的資源的時候,會看瀏覽器是否緩存了這個數據。若是本地有這個緩存數據,那麼就會直接從本地中獲取了,不會再請求網絡了。這是客戶端緩存。nginx傳遞的響應的某些數據會影響瀏覽器是否緩存數據以及緩存多久。
💡除了客戶端緩存,還有一種代理緩存nginx的緩存是代理緩存,由於它實際上是將代理的服務端的結果緩存了。代理緩存使用ngx_http_proxy_module的指令來配置。
💡(除了這兩種,還有(後端)服務端緩存,也就是使用redis等技術進行的後端服務端緩存。)。
💡proxy_cache_path path
:用來定義緩存文件路徑。只能用在http塊。
語法:
proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
1
),兩層(1:2
),三層(1:2:2
)。目錄會根據請求URL地址的哈希結果來建立(從末尾開始截取,),假如哈希結果是9cad383e7b0ee3d1d4b7099aace20b3f
,那麼levels=1:2
表明第一層目錄爲長度爲一的字符f
,第二層是長度爲2的字符b3
。💡proxy_cache zone|off
:能夠用在http, server, location。zone是proxy_cache_path的keys_zone.
💡proxy_cache_valid [code...] time
:緩存過時週期,過時以後就不返回代理緩存了。 code是http狀態碼。
💡proxy_cache_key string
:配置緩存的標識,好比說請求不同的話那確定不返回一樣的代理緩存了,這就是是否返回同一個緩存的區分標識。默認值是proxy_cache_key $scheme$proxy_host$request_uri;
,能夠用在http, server, location。其餘例子:proxy_cache_key $scheme$proxy_host$uri$args;
下面來作一個實驗:嘗試使用nginx的代理緩存做爲代理的響應。
1.咱們新建一個後端接口。這個後端接口能在每一次訪問的時候都在控制檯打印出一個消息(下面是一個Spring Boot例子):
2.配置反向代理:
3.一開始先測試一下http://192.168.31.128/api/user/info
,看每一次訪問是否都向後端發起了請求,確實是每一次都發請求的:
4.而後配置代理緩存:
5.再次測試訪問http://192.168.31.128/api/user/info
是否每一次訪問都向後端發起了請求,結果應該是後端服務端只會打出一次,或者你能夠嘗試關閉後端服務端,而後訪問,若是仍是可以訪問,那麼應該是已經代理緩存成功了。
💡永久緩存:上面使用proxy_cache配置的實際上是臨時緩存。也就是說必定時間後會自動過時。若是你的數據在很長很長時間都不會過時,那麼能夠考慮使用proxy_store.
💡若是你想讓部分請求不要緩存,可使用proxy_no_cache [string...]
,string能夠是變量,若是存在某個string值不爲空也不爲0,那麼此請求不會被緩存。
💡緩存清理:incative配置會幫咱們清除過時的緩存文件,但還沒過時的不會清除,須要咱們手動清除(場景是好比說你更新了大量數據,此時緩存中的數據不少都錯誤了,此時須要清除全部緩存。),若是你須要清除的話,那麼一種方法是手動定義一個Linux腳原本清除緩存;一種方法是使用模塊nginx-cache-purge。這些因爲篇幅問題,不講述。
瀏覽器是怎麼判斷緩存是否須要使用本地緩存以及緩存是否過時的呢?它經過響應頭中的expire
,cache-control
,Last-Modified
,Etag
等頭信息來判斷的。
expire
,Cache-control(max-age)
,若是有本地緩存,那麼會使用expire來判斷是否過時,不過時,直接使用本地緩存,本地過時以後,再進行遠程校驗。Thu, 02 Jul 2020 01:05:03 GMT
,若是校驗時間不一致,那麼不使用本地緩存,一致則使用本地緩存。"5efd32bf-3fa8e"
,若是校驗時間不一致,那麼不使用本地緩存,一致則使用本地緩存。Etag與Last-Modified的區別是,Etag更精確,因此會優先判斷Etag,而後再判斷Last-Modified。❗瀏覽器緩存機制你能夠本身瞭解一下:博客園-HTTP緩存機制。
💡Expire
expires [modified] time;
expires modified +24h;
就表明修改後24小時內不過時。expires 24h;
24天不過時,expires 30d;
30天不過時,expires -1;
表明永不過時測試以前咱們先要提幾點:
F5刷新
和Ctrl+F5刷新
就無效,此時測試應該使用在連接欄按回車發請求來測試。expires可用於什麼狀況能夠參考博客園-HTTP緩存機制。1.咱們先在/usr/share/nginx/html
下面存儲一張圖片,後面會經過訪問這種圖片,來測試客戶端緩存。
2.咱們一開始先不要配置expires:
server { listen 80; server_name 127.0.0.1; location / { root /usr/share/nginx/html; } }
3.屢次訪問一下http://192.168.31.128/a.jpg
看看nginx的訪問日誌/var/log/nginx/access.log
是否有添加
此時要多留意每次請求的響應碼,應當有如下幾個狀況:
4.加了expires以後看看,咱們簡單的使用兩分鐘看看。
server { listen 80; server_name 127.0.0.1; location / { expires 2m; root /usr/share/nginx/html; } }
5.屢次訪問一下http://192.168.31.128/a.jpg
看看nginx的訪問日誌是否有添加
💡nginx能夠對外接收靜態資源訪問的請求。
💡在上面的location的內容的時候,其實有講到返回文件資源的知識。
好比location ~* \.(gif|jpg|jpeg)$
匹配任何以.gif、.jpg 或 .jpeg 結尾的請求,而後你發的請求匹配成功的時候,會使用root+location獲得的路徑的資源做爲響應。其實這些也就是靜態資源了,因此其實也能夠經過nginx來達到靜態資源的訪問。
💡在先後端分離以後,前端做爲靜態資源訪問,應該部署到哪裏呢?由於咱們此時是不該該把前端靜態資源部署到後端服務器上的。那麼這時候放到nginx服務端上也是能夠的。利用nginx的靜態資源訪問做爲前端的服務端。
💡或者你也能夠把nginx做爲文件資源訪問的服務端。