主頁 > 軟體設計 > Nginx快取機制和性能優化

Nginx快取機制和性能優化

2021-11-03 08:01:16 軟體設計

目錄

Nginx快取機制介紹

Nginx快取機制的作用

nginx快取機制簡述

Nginx快取支持

快取使用

proxy_cache_path引數詳解

快取清除機制分析

被動快取清除

快取加載

主動清除快取

Nginx程式運行原理分析

Nginx作業模式

多行程處理模型

多行程處理模型優點

Nginx為何要采用多行程模式?

Worker行程遇到的問題

解決

Worker與CPU的系結

linux服務器引數調整

修改組態檔

調整內容

生效配置

Nginx常規調整


Nginx快取機制介紹

Nginx中如何使用快取,快取機制是怎么樣的,而且Nginx快取是不會像redis這些一樣有自己的記憶體管理機制,池化等,它會依據檔案系統進行快取

Nginx快取機制的作用

  • 快取能夠提升性能,學會Nginx中如何使用快取很重要,
  • Nginx作為靜態資源服務器,靜態資源變動頻率小,快取能夠加速訪問,
  • Nginx離用戶最近,啟用快取能更好的提高性能,結合Redis可以組成類似二級快取,

nginx快取機制簡述

Nginx中的快取
nginx中的快取是以檔案系統上的分層資料存盤的形式實作的,
快取Key是可配置的,并且可以使用不同的請求特定引數來控制進入快取的內容,
快取Key和快取元資料存盤在 共享記憶體段中,快取加載器、快取管理器和Worker行程可以訪問它 們,目前,除了作業系統的虛擬檔案系統機制所暗示的優化之外,沒有任何記憶體中的檔案快取,每個快取的回應都放在檔案系統上的不同檔案中,通過nginx配置指令控制指定層次結構(級別和命名細節),

nginx是沒做優化的,

快取放置內容程序:
當nginx從上游服務器讀取回應時,首先將內容寫入快取目錄結構之外的臨時檔案,
當nginx完成處理請求時,它會重命名臨時檔案并將其移動到快取目錄,如果用于代理的臨時檔案目錄位于另一個檔案系統上,則檔案將被復制,因此建議將臨時目錄和快取目錄保留在同一個檔案系統上,當需要顯式清除檔案時,從快取目錄結構中洗掉檔案也是非常安全的,
nginx有第三方擴展,可以遠程控制快取的內容,并計劃在主發行版中集成此功能

Nginx快取支持

Nginx中有非常強大的快取功能,針對后臺服務回傳的資料能夠進行快取,再次訪問時,無需從臺服務拿取結果,直接在nginx本地獲取即可,Nginx中針對fastcgi、http_proxy、scgi、ssl_session、ngx_http_uwsgi_module模塊提供了通用的快取功能,
file cache 檔案快取,
以http_proxy模塊為例來進行講解,觀察官網其他模塊,都相差不大,學會一個其他的也就學會了

在官網中api模塊 設定, 都有自己的默認值,可以根據需要設定,

快取使用

在組態檔中, 主要是在http指令塊中存在

包括代理快取配置,定義的配置

events {
	# 并發連接數
    worker_connections  1024;
}
http {
    # JAVA服務器集群
	upstream app_servers {
		server 127.0.0.1:8080;	
#		server 127.0.0.1:8081;
	}
	# 代理快取配置 - 定義配置
	proxy_cache_path "./cache_data/" levels=2:1:2 keys_zone=hot_information_cache:256m inactive=1d max_size=1000g;  
	proxy_cache_path "./cache_data/" levels=2:1:2 keys_zone=cache2:256m inactive=30s max_size=30g;  
	server {
		# 監聽80埠
		listen	80;
		location / {
            # 開啟快取
            proxy_cache hot_information_cache;
            # 快取JAVA應用回傳的指定狀態的資料,快取時間時1天       
            proxy_cache_valid 200 206 304 301 302 1d;
            # 請求的url就是快取的key(根據實際業務場景匹配)       
            proxy_cache_key $uri$is_args$args;      
            
            # 設定傳遞給上游服務的請求頭,Host為客戶端host,默認為$proxy_host
            proxy_set_header Host $http_host;
            # 如果快取中沒找到,再去請求后端服務器
            proxy_pass http://app_servers;
		}
		
		# 該指令在商業版本Nginx Plus支持,可以通過第三方模塊ngx_cache_purge來替代
		# 資源有變化的時候清除快取
		location ~ /purge(/.*) {
			#設定只允許指定的IP來清除快取
			allow all;
			# allow 127.0.0.1;
			# deny all ;
			proxy_cache_purge hot_information_cache $1;
		}
	}
}

levels表示目錄層級 3級,

后面對應的引數,包括proxy_cache_path 快取的路徑 和快取空間名、大小等配置,啟用快取proxy_cache 等,

proxy_cache_path 可以配置多個的,

keys_zone=cache2:256m 這里定義的是 空間名稱 和大小,

proxy_cache_valid 快取JAVA應用回傳的指定狀態的資料,快取時間時1天

proxy_cache_key 請求的url就是快取的key

proxy_set_header 設定傳遞給上游服務的請求頭,

通過這些指令 可以開啟快取,

proxy_cache_purge 進行對 資料進行清除,定義將請求視為快取清除請求的條件,如果字串引數的至少一個值不為空且不等于“0”,則移除具有相應高速快取鍵的高速快取條目 ,通過回傳204(無內容)回應來指示成功操作的結果,
對于快取來說,首先存在記憶體中,只有記憶體滿了,會存在磁盤中

proxy_cache_path引數詳解

level
用來定義快取的層級,可以定義1到3個層級,每個層級接收值1、2
use_temp_path
是否啟用快取臨時檔案,第一次回應的內容將寫入臨時檔案,后面才會重寫回來,使用網盤注意網路 IO的開銷,
keys_zone
定義在共享存盤區中存盤了所有活躍的Key和關于資料的資訊,存盤區名稱和大小由key_zone引數配置, 一個兆位元組的區域可以存盤大約8,000個Key
Inactive
不論資料新舊程度,在inactive指定的時間內未訪問的快取資料 將從快取中洗掉,

快取清除機制分析

對于記憶體和磁盤滿了,nginx如何清除的,以及會不會像redis去池化會不會有碎片化的處理,

快取自己有快取管理行程

被動快取清除

proxy_cache_path 指令的快取管理

proxy_cache_path 中可以通過以下指令來管理快取

  • max_size 指定快取大小,快取管理行程監控快取是否超過指定值,超過該大小則通過LRU演算法來 淘汰資料,一次迭代洗掉的資料通過下面的引數來指定,
  • manager_files 一次迭代程序中洗掉的項的數量,默認100個
  • manager_threshold 一次迭代操作的持續時間限制,默認200毫秒
  • manager_sleep 兩次迭代的間隔時間,默認50毫秒

快取加載

proxy_cache_path中可以通過以下引數來調整加載快取 Nginx啟動一分鐘后,快取加載行程被激活,存盤在檔案系統上先前快取的資料將被加載到 快取區中,整個加載是在迭代中完成的,一次加載

  • loader_files 一次迭代加載不超過指定數目的項,默認100,
  • loader_threshold 一次迭代操作的持續時間限制,默認200毫秒
  • loader_sleep 兩次迭代的間隔時間,默認50毫秒

主動清除快取

Nginx商業功能

proxy_cache_path中可以通過以下引數來調整主動清除快取

  • purger:on開啟快取清除行程,遍歷所有快取條目并洗掉匹配到的鍵的快取資料
  • purger_files 一次迭代程序中掃描的項的數量,默認10個
  • purger_threshold 一次迭代的持續時間,默認50毫秒
  • purger_sleep 兩次迭代的間隔時間,默認50毫秒
以上引數與proxy_cache_purge指令配合進行,
雖說只能在商業版的Nginx中使用,但是我們可以通過強大的第三方模塊來替代

該指令在商業版本Nginx Plus支持,可以通過第三方模塊ngx_cache_purge來替代

location ~ /purge(/.*) {
			#設定只允許指定的IP來清除快取
			allow all;
			# allow 127.0.0.1;
			# deny all ;
			proxy_cache_purge hot_information_cache $1;
		}

ngx_cache_purge是一個第三方的nginx快取主動清除模塊,集成方便,使用簡單,下面我們就來學習如何安裝使用它,本節內容基于第一課安裝的Nginx基礎進行,這里我們只是再編譯增加模塊,

Nginx快取主動清除插件ngx_cache_purge 提取碼:d8eq

Nginx程式運行原理分析

nginx在運行時,架構是怎么樣的,架構 作業模式;從行程來看有 master 和worker行程,

Nginx作業模式

Nginx在啟動時會以daemon形式在后臺運行,采用多行程+異步非阻塞IO事件模型來處理各種連接請求,多行程模型包括 一個master行程,多個worker行程,一般worker行程個數是根據服務器CPU核數來決定的,master行程負責管理Nginx本身和其他worker行程,
4個worker行程的父行程都是master行程,表明worker行程都是從父行程fork出來的,并且父行程的ppid為1,表示其為daemon行程,
Nginx中的Master、Worker兩種行程,
Master行程
負責加載配置、接收命令、監控子行程,Master行程也是可以關閉的
Worker行程
負責處理網路請求,Worker行程的個數由組態檔決定,一般和CPU個數相關(有利于行程切換),配置幾個就有幾個Worker行程,需要說明的是,在nginx多行程中,每個worker都是平等的,因此每個行程處理外部請求的
機會權重都是一致的,
按理來說 worker行程處理請求的機會是一樣的,

這個流程模型和netty上的網路模型,都是很像的,網路請求,

多行程處理模型

多行程模型的處理方式

  • 首先,master行程一開始就會根據我們的配置,來建立需 要listen的網路socket fd,然后fork出多個worker行程,
  • 其次,根據行程的特性,新建立的worker行程,也會和 master行程一樣,具有相同的設定,因此,其也會去監聽 相同ip埠的套接字socket fd,
  • 然后 ,多個worker行程監聽同樣設定的socket fd,當有 一個請求進來,所有的worker都會感知,
  • 最后 ,監聽成功的worker行程,讀取請求,決議處理,響 應資料回傳給客戶端,斷開連接,結束,因此,一個request請求,只需要worker行程就可以完成,

多行程處理模型優點

Nginx為何要采用多行程模式?

  • 行程之間是獨立的,當一個worker行程出現例外退出,其他worker行程不會受到影響;
  • 獨立行程也會避免一些不需要的鎖操作,這樣能提高處理效率,開發除錯也更容易,
單純的 多行程模型會導致連接并發數量降低 異步非阻塞IO模型 能解決這個問題,還能避
多執行緒背景關系切換導致 的性能損失,
多行程模型+異步非阻塞模型是一個非常好的選擇,
跟NIO、Netty執行緒模型思想一致,只不過一個是執行緒級、一個是行程級,

Worker行程遇到的問題

出現驚群效應
多個worker子行程監聽相同埠的設計,這樣多個子行程在accept建立新連接時會有爭搶,這會帶來 著名的“驚群”問題,子行程數量越多問題越明顯,這會造成系統性能下降,建立新連接時Nginx是如 何避免出現“驚群”現象的呢?
Worker行程負載不均衡
多個子行程爭搶處理一個新連接事件,最終只有一個worker子行程成功建立連接,隨后,它會一直處 理這個連接直到連接關閉,
如果有的子行程很“勤奮”,它們搶著建立并處理了大部分連接,而有的子行程則“運氣不好”,只 處理了少量連接,

解決

Nginx 的 Post佇列
將epoll 產生的事件分開,新連接事件的
  • ngx_posted_accept_events佇列優先執行,普通事件的
  • ngx_posted_events佇列最后執行

accept_mutex

Nginx采用了一個是否打開accept_mutex選項的值,控制worker行程是否需要去競爭鎖,打開accept_mutex鎖,能很好解決accept精確問題

ngx_accept_disabled
worker行程進行負債均衡閾的判斷值,處理的連接總數沒有達到7/8,不會搶accept鎖,達到時,則需要槍鎖,它解決了負載均衡的問題,

這是module中代碼,

Worker與CPU的系結

Worker行程跟CPU個數有關,但是如果多個Worker行程在同一個CPU上面爭奪資源也非常消耗性能,Nginx中有一個 worker_cpu_affinity 配置,能夠將worker系結到對應的CPU上面,
單個Worker行程處理的并發連接數配置

linux服務器引數調整

當TCP TIME_WAIT套接字數量經常達到兩、三萬,服務器很容易被拖死,需要減少Nginx服務器的TIME_WAIT套接字數量,
這個和netty對于服務器引數調整是一樣的,都是例如統同時保持TIME_WAIT套接字的最大數量,以及最大連接數等等,

修改組態檔

sudo vim /etc/sysctl.conf

調整內容

# 表示如果套接字由本端要求關閉,這個引數決定了它保持在FIN-WAIT-2狀態的時間,
# 由于某種原因服務端主動關閉連接,連接進入FIN_WAIT2狀態,該狀態是沒有超時的
# 如果客戶端不關閉,這個FIN_WAIT_2狀態將保持到系統重新啟動,越來越多的FIN_WAIT_2狀態會致使內核crash
net.ipv4.tcp_fin_timeout = 30
# 表示當keepalive起用的時候,TCP發送keepalive訊息的頻度,預設是2小時,改為20分鐘,
net.ipv4.tcp_keepalive_time = 1200
# 表示開啟SYN Cookies,當出現SYN等待佇列溢位時,啟用cookies來處理,
# 可防范少量SYN攻擊,默認為0,表示關閉;
net.ipv4.tcp_syncookies = 1
# 表示開啟重用,允許將TIME-WAIT sockets重新用于新的TCP連接,默認為0,表示關閉;
net.ipv4.tcp_tw_reuse = 1
# 表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認為0,表示關閉,
net.ipv4.tcp_tw_recycle = 1
# 表示用于向外連接的埠范圍,預設情況下很小:32768到61000,改為1024到65000,
net.ipv4.ip_local_port_range = 1024    65000
# 表示SYN佇列的長度,默認為1024,加大佇列長度為8192,可以容納更多等待連接的網路連接數,
net.ipv4.tcp_max_syn_backlog = 8192
# 表示系統同時保持TIME_WAIT套接字的最大數量,如果超過這個數字,TIME_WAIT套接字將立刻被清除并列印警告資訊,默認為180000,改為5000,對于Apache、Nginx等服務器,上幾行的引數可以很好地減少TIME_WAIT套接字數量,但是對于Squid,效果卻不大,此項引數可以控制TIME_WAIT套接字的最大數量,避免Squid服務器被大量的TIME_WAIT套接字拖死,
net.ipv4.tcp_max_tw_buckets = 5000

生效配置

sudo /sbin/sysctl -p

Nginx常規調整

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/345697.html

標籤:其他

上一篇:docker基本使用總結

下一篇:嵌入式編程之狀態機

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more