日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

聊聊微服务架构中的多级缓存设计

發布時間:2024/3/13 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 聊聊微服务架构中的多级缓存设计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

大家好,我是不才陳某~

今天我們來聊聊緩存這個話題,看看在微服務環境下如何設計有效的多級緩存架構。主要涉及三方面內容:

  • Web 應用的客戶端緩存;

  • 應用層靜態資源緩存;

  • 服務層多級緩存。

首先,咱們先講解微服務架構的多級緩存設計。

微服務架構中的多級緩存設計

提到緩存,想必每一位軟件工程師都不陌生,它是目前架構設計中提高性能最直接的方式。這里我們舉個例子:

Redis 緩存

假設應用程序將原始數據存儲在 MySQL 數據庫中。眾所周知 MySQL 數據庫會將數據存儲在硬盤以防止掉電丟失,但是受制于硬盤的物理設計,即便是目前性能最好的企業級 SSD 硬盤,也比內存的這種高速設備 IO 層面差一個數量級,而以淘寶、京東這種電商為代表的互聯網應用,都是典型的 “讀多寫少” 的場景,因此我們需要在設計上進行數據的讀寫分離,在數據寫入時直接落盤處理,而占比超過 90% 的數據讀取操作時則從以 Redis 為代表的內存 NoSQL 數據庫提取數據,利用內存的高吞吐瞬間完成數據提取,這里 Redis 的作用就是我們常說的緩存。

當然,緩存可不只有用內存替代硬盤這一種形式,在分布式架構下緩存在每一層都有自己的設計,下面咱們通過這個微服務的多級緩存架構圖為主線進行講解。

X 緩存多級緩存架構縱覽

這張圖從上到下包含四層,分別為:客戶端、應用層、服務層以及數據層。

客戶端緩存

X 商城客戶端為瀏覽器,在瀏覽器層面我們主要是對 HTML 中的圖片、CSS、JS、字體這些靜態資源進行緩存。

瀏覽器緩存

我們以百度 Logo 圖片為例,百度在 HTTP 通過 Expires 響應頭控制靜態圖片的有效期。Expires 代表過期時間。當前百度 Logo 的過期時間為 2031 年 2 月 8 日 9 時 26 分 31 秒。在這個時間段內,瀏覽器會將圖片以文件形式緩存在本地,再次訪問時會看到“from disk cache”的提示,關注公眾號:碼猿技術專欄,回復關鍵詞:1111 獲取阿里內部Java性能調優手冊!此時瀏覽器不再產生與服務器的實際請求,會從本地直接讀取緩存圖片。通過在瀏覽器端設置 Expires 可以在很大程度減少重復請求靜態資源帶來的帶寬損耗,這在高并發 Web 應用中是基礎而重要的設置。

應用層緩存

那 Expires 到底在哪里進行設置呢?對于瀏覽器來說它只是客戶端,只負責讀取Expires響應頭,對于 Expires 要在應用層,也就是 CDN 與 Nginx 中進行設置。

CDN 內容分發網絡

CDN 全稱是 Content Delivery Network,即內容分發網絡,是互聯網靜態資源分發的主要技術手段。

CDN 內容分發網絡

中國幅員遼闊,從北京到上海就有上千公里,如果大量的上海用戶同時要訪問千里之外的北京服務器的資源,這么長的通信必然帶來高延遲與更多不可控因素影響數據傳輸,如果有某種機制允許將北京的靜態文件緩存到上海的服務器,上海用戶自動就近訪問服務器獲取資源,這樣便可很大程度降低網絡延遲,進而提高系統的可用性。而剛才提到的分布式緩存技術就是我們常提到的CDN(內容分發網絡)。

對于廣域的互聯網應用,CDN 幾乎是必需的基礎設施,它有效解決了帶寬集中占用以及數據分發的問題。像 Web 頁面中的圖片、音視頻、CSS、JS 這些靜態資源,都可以通過 CDN 服務器就近獲取。

CDN 技術的核心是“智能 DNS”,智能 DNS 會根據用戶的 IP 地址自動確定就近訪問 CDN 節點,咱們以下圖為例:

CDN 執行流程

以某上海用戶的瀏覽器要訪問商城首頁廣告位的 banner.jpg 文件,瀏覽器通過服務商提供的智能 DNS 服務,將請求自動轉發到商城在上海地區準備的 CDN 服務器,上海 CDN 收到請求后首先檢查本機是否已緩存過 banner.jpg,如果文件已存在便直接將圖片數據返回給客戶端;如果沒有緩存過,則回源到北京的源數據節點,將 banner.jpg 文件抽取并緩存到上海服務器,最后上海 CDN 節點再將本機的 banner.jpg 返回給客戶端。對于 banner.jpg 來說,第一次訪問后上海 CDN 節點已緩存該文件,則之后的緩存有效期內所有后續訪問由上海 CDN 直接提供。與之類似的,商城應用可以在重要城市搭建 CDN 節點,這樣原本集中被發往北京服務器的請求就被分攤到 CDN 節點,這也直接降低了北京機房的帶寬壓力。

在互聯網應用中,因為 CDN 涉及多地域多節點組網,前期投入成本較高,更多的中小型軟件公司通常會選擇阿里云、騰訊云等大廠提供的 CDN 服務,通過按需付費的方式降低硬件成本。而這些服務商又會為 CDN 賦予額外的能力,比如阿里云、騰訊云 CDN 除了緩存文件之外,還提供了管理后臺能為響應賦予額外的響應頭。如下所示在阿里云 CDN 后臺,就額外設置了 Cache-Control 響應頭代表緩存有效期為 1 小時。這里我們額外提一下 Expires 與的 Cache-Control 的區別,Expires 是指定具體某個時間點緩存到期,而 Cache-Control 則代表緩存的有效期是多長時間。Expires 設置時間,Cache-Control 設置時長,根據業務場景不同可以使用不同的響應頭。

阿里云自定義響應頭

Nginx 緩存管理

說完 CDN,下面再來聊一下 Nginx。Nginx 是一款開源的、跨平臺的高性能 Web 服務器,它有著高性能,穩定性好,配置簡單,模塊結構化,資源消耗低的優點。同時支持反向代理、負載均衡、緩存的功能。Nginx 是 Web 應用架構中的常客,例如后端 Tomcat 集群便可通過增加 Nginx 前置做軟負載均衡,為應用提供高可用特性。

Nginx 代理服務器

在互聯網應用中,用戶分布在全國各地,對資源的響應速度與帶寬要求較高,因此部署 CDN 是十分有必要的。但在更多的企業應用中,其實大部分的企業用戶都分布在指定的辦公區域或者相對固定的場所,再加上并發用戶相對較少,其實并不需要額外部署 CDN 這種重量級解決方案。在架構中只需要部署 Nginx 服務器,利用 Nginx 自帶的靜態資源緩存與壓縮功能便可勝任大多數企業應用場景。

在 Nginx 中自帶將后端應用中圖片、CSS、JS 等靜態資源緩存功能,我們只需在 Nginx 的核心配置 nginx.conf 中增加下面的片段,便可對后端的靜態資源進行緩存,關鍵配置我已做好注釋,同學們可以直接使用。

#?設置緩存目錄 #?levels代表采用1:2也就是兩級目錄的形式保存緩存文件(靜態資源css、js) #?keys_zone定義緩存的名稱及內存的使用,名稱為babytun-cache?,在內存中開始100m交換空間 #?inactive=7d?如果某個緩存文件超過7天沒有被訪問,則刪除 #?max_size=20g;代表設置文件夾最大不能超過20g,超過后會自動將訪問頻度(命中率)最低的緩存文件刪除 proxy_cache_path?d:/nginx-cache?levels=1:2?keys_zone=babytun-cache:100m?inactive=7d?max_size=20g;#配置xmall后端服務器的權重負載均衡策略 upstream?xmall?{server?192.168.31.181?weight=5?max_fails=1?fail_timeout=3s;server?192.168.31.182?weight=2;server?192.168.31.183?weight=1;server?192.168.31.184?weight=2; }server?{#nginx通過80端口提供Web服務listen?80;#?開啟靜態資源緩存#?利用正則表達式匹配URL,匹配成功的則執行內部邏輯#?~*?代表URL匹配不區分大小寫location?~*?\.(gif|jpg|css|png|js|woff|html)(.*){#?配置代理轉發規則proxy_pass?http://xmall;proxy_set_header?Host?$host;proxy_set_header?X-Forwarded-For?$proxy_add_x_forwarded_for;proxy_cache?xmall-cache;#如果靜態資源響應狀態碼為200(成功)??302(暫時性重定向)時?緩存文件有效期1天proxy_cache_valid?200?302?24h;#301(永久性重定向)緩存保存5天proxy_cache_valid?301?5d;#其他情況proxy_cache_valid?any?5m;#設置瀏覽器端緩存過期時間90天expires?90d;}#使用xmall服務器池進行后端處理location?/{proxy_pass?http://xmall;?proxy_set_header?Host?$host;proxy_set_header?X-Forwarded-For?$proxy_add_x_forwarded_for;} }

增加上面配置后,每一次通過 Nginx 訪問應用中新的靜態文件時,在 Nginx 服務的緩存目錄便會生成緩存文件,在緩存有效期內該靜態資源的請求便不再送到后端服務器,而直接由 Nginx 讀取本地緩存并返回。

Nginx 本地緩存

服務層緩存

在前面無論是 CDN 還是 Nginx,都是對 Web 應用中的靜態資源文件進行緩存。但后端應用與服務更多的是訪問接口與數據,對于這些對象我們如何利用緩存技術進行性能優化呢?對于后端應用與服務的緩存可以按部署方式分為進程內緩存與分布式緩存服務。

進程內緩存

所謂進程內緩存,就是在應用中開辟的一塊內存空間,數據在運行時被載入這塊內存,通過本地內存的低延遲、高吞吐的特性提高程序的訪問速度。進程內緩存在眾多 Java 框架內都有廣泛應用,例如 Hibernate、Mybatis 框架的一二級緩存、Spring MVC 的頁面緩存都是進程內緩存的經典應用場景,這些進程內緩存在 Java 中也有著非常多優秀的開源實現,如 EhCache、Caffeine 都是代表性產品。

分布式緩存服務

與進程內相對的,就是需要獨立部署的分布式緩存服務。最常用的是基于 Redis 這種內存型 NoSQL 數據庫,對整體架構中的應用數據進行集中緩存。

在架構設計時,很多新架構師一聽到緩存,下意識認為增加 Redis 分布式緩存服務器就夠了,其實這是片面的做法。在緩存架構設計時,一定要按照由近到遠、由快到慢的順序進行逐級訪問。假設在電商進行商品秒殺活動時,如果沒有本地緩存,所有商品、訂單、物流的熱點數據都保存在 Redis 服務器中,每完成一筆訂單,都要額外增加若干次網絡通信,網絡通信本身就可能由于各種原因存在通信失敗的問題。即便是你能保證網絡 100% 可用,但 Redis 集群承擔了來自所有外部應用的訪問壓力,一旦突發流量超過 Redis 的負載上限,整體架構便面臨崩潰的風險。

Redis 緩存服務集群

因此在 Java 的應用端也要設計多級緩存,我們將進程內緩存與分布式緩存服務結合,有效分攤應用壓力。在 Java 應用層面,只有 EhCache 的緩存不存在時,再去 Redis 分布式緩存獲取,如果 Redis 也沒有此數據再去數據庫查詢,數據查詢成功后對 Redis 與 EhCahce 同時進行雙寫更新。這樣 Java 應用下一次再查詢相同數據時便直接從本地 EhCache 緩存提取,不再產生新的網絡通信,應用查詢性能得到顯著提高。

多級緩存設計

保障緩存一致性

但事無完美,當引入多級緩存后,我們又會遇到緩存數據一致性的挑戰,以下圖為例:

緩存一致性問題

我們都知道作為數據庫寫操作,是不通過緩存的。假設商品服務實例 1 將 1 號商品價格調整為 80 元,這會衍生一個新問題:如何主動向應用程序推送數據變更的消息來保證它們也能同步更新緩存呢?

相信此時你已經有了答案。沒錯,我們需要在當前架構中引入 MQ 消息隊列,利用 RocketMQ 的主動推送功能來向其他服務實例以及 Redis 緩存服務發起變更通知。

通過 RocketMQ 解決保證消息一致性

如上圖所示,在商品服務實例 1 對商品調價后,主動向 RocketMQ Broker 發送變更消息,Broker 將變更信息推送至其他實例與 Redis 集群,這些服務實例在收到變更消息后,在緩存中先刪除過期緩存,再創建新的數據,以此保證各實例數據一致。

看到這里你會發現,對于緩存來說,并沒有終極的解決方案。雖然多級緩存設計帶來了更好的應用性能,但也為了緩存一致性必須引入 MQ 增加了架構的復雜度。那到底多級緩存設計該如何取舍呢?在我看來,有三種情況特別適合引入多級緩存。

第一種情況,緩存的數據是穩定的。例如郵政編碼、地域區塊、歸檔的歷史數據這些信息適合通過多級緩存減小 Redis 與數據庫的壓力。

第二種情況,瞬時可能會產生極高并發的場景。例如春運購票、雙 11 零點秒殺、股市開盤交易等,瞬間的流量洪峰可能擊穿 Redis 緩存,產生流量雪崩。這時利用預熱的進程內緩存分攤流量,減少后端壓力是非常有必要的。

第三種情況,一定程度上允許數據不一致。例如某博客平臺中你修改了自我介紹這樣的非關鍵信息,此時在應用集群中其他節點緩存不一致也并不會帶來嚴重影響,對于這種情況我們采用T+1的方式在日終處理時保證緩存最終一致就可以了。

以上是我總結的三種適合服務層做多級緩存的場景。當然如果你們的應用并發量不大,在未來的1~2 年內利用 Redis 分布式緩存集群完全可以勝任應用性能要求,那自然就沒有必要設計多級緩存,我們要根據業務特點靈活調整架構。

小結

今天咱們介紹了在應用微服務架構下從客戶端到服務層,各層的緩存設計以及解決方案,講解了從瀏覽器的 Expires 響應頭到 CDN、Nginx 的靜態資源緩存,再到服務層針對數據的多級緩存,使你對微服務架構的緩存有了總體的了解。

最后說一句(別白嫖,求關注)

陳某每一篇文章都是精心輸出,如果這篇文章對你有所幫助,或者有所啟發的話,幫忙點贊、在看、轉發、收藏,你的支持就是我堅持下去的最大動力!

另外陳某的知識星球開通了,公眾號回復關鍵詞:知識星球 獲取限量30元優惠券加入只需89元,一頓飯錢,但是星球回饋的價值卻是巨大,目前更新了Spring全家桶實戰系列、億級數據分庫分表實戰、DDD微服務實戰專欄、我要進大廠、Spring,Mybatis等框架源碼、架構實戰22講等....每增加一個專欄價格將上漲20元

關注公眾號:【碼猿技術專欄】,公眾號內有超贊的粉絲福利,回復:加群,可以加入技術討論群,和大家一起討論技術,吹牛逼!

總結

以上是生活随笔為你收集整理的聊聊微服务架构中的多级缓存设计的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。