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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

构建亿级前端读服务

發(fā)布時(shí)間:2024/9/20 HTML 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 构建亿级前端读服务 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

從入職京東到現(xiàn)在,做讀服務(wù)已經(jīng)一年多的時(shí)間了,經(jīng)歷了各種億級到百億級的讀服務(wù);這段時(shí)間也進(jìn)行了一些新的讀服務(wù)架構(gòu)嘗試,從架構(gòu)到代碼的編寫,各個(gè)環(huán)節(jié)都進(jìn)行了反復(fù)嘗試,壓測并進(jìn)行調(diào)優(yōu),希望得到一個(gè)自己滿意的讀服務(wù)架構(gòu)。

?

一些設(shè)計(jì)原則

  • 無狀態(tài)
  • 數(shù)據(jù)閉環(huán)
  • 緩存銀彈
  • 并發(fā)化
  • 降級開關(guān)
  • 限流
  • 切流量
  • 其他

無狀態(tài)

如果設(shè)計(jì)的應(yīng)用是無狀態(tài)的,那么應(yīng)用就可以水平擴(kuò)展,當(dāng)然實(shí)際生產(chǎn)環(huán)境可能是這樣子的: 應(yīng)用無狀態(tài),配置文件有狀態(tài)。比如不同的機(jī)房需要讀取不同的數(shù)據(jù)源,此時(shí)就需要通過配置文件指定。

?

數(shù)據(jù)閉環(huán)

如果依賴的數(shù)據(jù)來源特別多,此時(shí)就可以考慮使用數(shù)據(jù)閉環(huán),基本步驟:

1、數(shù)據(jù)異構(gòu):通過如MQ機(jī)制接收數(shù)據(jù)變更,然后原子化存儲(chǔ)到合適的存儲(chǔ)引擎,如redis或持久化KV存儲(chǔ);

2、數(shù)據(jù)聚合:這步是可選的,數(shù)據(jù)異構(gòu)的目的是把數(shù)據(jù)從多個(gè)數(shù)據(jù)源拿過來,數(shù)據(jù)聚合目的是把這些數(shù)據(jù)做個(gè)聚合,這樣前端就可以一個(gè)調(diào)用拿到所有數(shù)據(jù),此步驟一般存儲(chǔ)到KV存儲(chǔ)中;

3、前端展示:前端通過一次或少量幾次調(diào)用拿到所需要的數(shù)據(jù)。

?

這種方式的好處就是數(shù)據(jù)的閉環(huán),任何依賴系統(tǒng)出問題了,還是能正常工作,只是更新會(huì)有積壓,但是不影響前端展示。

?

另外此處如果一次需要多個(gè)數(shù)據(jù),可以考慮使用Hash Tag機(jī)制將相關(guān)的數(shù)據(jù)聚合到一個(gè)實(shí)例,如在展示商品詳情頁時(shí)需要:商品基本信息:p:123:, 商品規(guī)格參數(shù):d:123:,此時(shí)就可以使用冒號(hào)中間的123作為數(shù)據(jù)分片key,這樣相同id的商品相關(guān)數(shù)據(jù)就在一個(gè)實(shí)例。

?

緩存銀彈

緩存對于讀服務(wù)來說可謂抗流量的銀彈。

?

瀏覽器端緩存

設(shè)置請求的過期時(shí)間,如響應(yīng)頭Expires、Cache-control進(jìn)行控制。這種機(jī)制適用于如對實(shí)時(shí)性不太敏感的數(shù)據(jù),如商品詳情頁框架、商家評分、評價(jià)、廣告詞等;但對于如價(jià)格、庫存等實(shí)時(shí)要求比較高的,就不能做瀏覽器端緩存。

?

CDN緩存

有些頁面/活動(dòng)頁/圖片等服務(wù)可以考慮將頁面/活動(dòng)頁/圖片推送到離用戶最近的CDN節(jié)點(diǎn)讓用戶能在離他最近的節(jié)點(diǎn)找到想要的數(shù)據(jù)。一般有兩種機(jī)制:推送機(jī)制(當(dāng)內(nèi)容變更后主動(dòng)推送到CDN邊緣節(jié)點(diǎn)),拉取機(jī)制(先訪問邊緣節(jié)點(diǎn),當(dāng)沒有內(nèi)容時(shí)回源到源服務(wù)器拿到內(nèi)容并存儲(chǔ)到節(jié)點(diǎn)上),兩種方式各有利弊。 使用CDN時(shí)要考慮URL的設(shè)計(jì),比如URL中不能有隨機(jī)數(shù),否則每次都穿透CDN,回源到源服務(wù)器,相當(dāng)于CDN沒有任何效果。對于爬蟲可以返回過期數(shù)據(jù)而選擇不回源。

?

接入層緩存

對于沒有CDN緩存的應(yīng)用來說,可以考慮使用如Nginx搭建一層接入層,該接入層可以考慮如下機(jī)制實(shí)現(xiàn):

1、URL重寫:將URL按照指定的順序或者格式重寫,去除隨機(jī)數(shù);

2、一致性哈希:按照指定的參數(shù)(如分類/商品編號(hào))做一致性Hash,從而保證相同數(shù)據(jù)落到一臺(tái)服務(wù)器上;

3、proxy_cache:使用內(nèi)存級/SSD級代理緩存來緩存內(nèi)容;

4、proxy_cache_lock:使用lock機(jī)制,將多個(gè)回源合并為一個(gè),減少回源量,并設(shè)置相應(yīng)的lock超時(shí)時(shí)間;

5、shared_dict:此處如果架構(gòu)使用了nginx+lua實(shí)現(xiàn),可以考慮使用lua shared_dict進(jìn)行cache,最大的好處就是reload緩存不丟失。

?

此處要注意,對于托底/異常數(shù)據(jù)不應(yīng)該讓其緩存,否則用戶會(huì)在很長一段時(shí)間看到這些數(shù)據(jù)。?

?

應(yīng)用層緩存

如我們使用Tomcat時(shí)可以使用堆內(nèi)緩存/堆外緩存,堆內(nèi)緩存的最大問題就是重啟時(shí)內(nèi)存中的緩存丟失,如果此時(shí)流量風(fēng)暴來臨可能沖垮應(yīng)用;還可以考慮使用local redis cache來代替堆外內(nèi)存;或者在接入層使用shared_dict來將緩存前置,減少風(fēng)暴。

?

分布式緩存

一種機(jī)制就是廢棄分布式緩存,改成應(yīng)用local redis cache,即在應(yīng)用所在服務(wù)器中部署一個(gè)redis,然后使用主從機(jī)制同步數(shù)據(jù)。如果數(shù)據(jù)量不大這種架構(gòu)是最優(yōu)的;如果數(shù)據(jù)量太大,單服務(wù)器存儲(chǔ)不了,還可以考慮分片機(jī)制將流量分散到多臺(tái);或者直接就是分布式緩存實(shí)現(xiàn)。常見的分片規(guī)則就是一致性哈希了。

?


如上圖就是我們一個(gè)應(yīng)用的架構(gòu):?

1、首先接入層讀取本地proxy cache / local cache;

2、如果不命中,會(huì)讀取分布式redis集群;

3、如果還不命中,會(huì)回源到tomcat,然后讀取堆內(nèi)cache;如果沒有,則直接調(diào)用依賴業(yè)務(wù)獲取數(shù)據(jù);然后異步化寫到redis集群;

?

因?yàn)槲覀兪褂昧薾ginx+lua,第二、三步可以使用lua-resty-lock非阻塞鎖減少峰值時(shí)的回源量;如果你的服務(wù)是用戶維度的,這種非阻塞鎖不會(huì)有什么大作用。

?

并發(fā)化

假設(shè)一個(gè)讀服務(wù)是需要如下數(shù)據(jù):

1、數(shù)據(jù)A ?10ms

2、數(shù)據(jù)B ?15ms

3、數(shù)據(jù)C ? 20ms

4、數(shù)據(jù)D ? 5ms

5、數(shù)據(jù)E ? 10ms

?

那么如果串行獲取那么需要:60ms;

?

而如果數(shù)據(jù)C依賴數(shù)據(jù)A和數(shù)據(jù)B、數(shù)據(jù)D誰也不依賴、數(shù)據(jù)E依賴數(shù)據(jù)C;那么我們可以這樣子來獲取數(shù)據(jù):

那么如果并發(fā)化獲取那么需要:30ms;能提升一倍的性能。

?

假設(shè)數(shù)據(jù)E還依賴數(shù)據(jù)F(5ms),而數(shù)據(jù)F是在數(shù)據(jù)E服務(wù)中獲取的,此時(shí)就可以考慮在此服務(wù)中在取數(shù)據(jù)A/B/D時(shí)預(yù)取數(shù)據(jù)F,那么整體性能就變?yōu)榱?#xff1a;25ms。

?

降級開關(guān)

對于一個(gè)讀服務(wù),很重要的一個(gè)設(shè)計(jì)就是降級開關(guān),在設(shè)計(jì)降級開關(guān)時(shí)主要如下思路:

1、開關(guān)集中化管理:通過推送機(jī)制把開關(guān)推送到各個(gè)應(yīng)用;

2、可降級的多級讀服務(wù):比如只讀本地緩存、只讀分布式緩存、或者只讀一個(gè)默認(rèn)的降級數(shù)據(jù);

3、開關(guān)前置化:如架構(gòu)是nginx--->tomcat,可以將開關(guān)前置到nginx接入層,在nginx層做開關(guān),請求不打到后端應(yīng)用。

?

限流

目的是防止惡意流量,惡意攻擊,可以考慮如下思路:

1、惡意流量只訪問cache;

2、對于穿透到后端應(yīng)用的可以考慮使用nginx的limit模塊處理;

3、對于惡意ip可以使用如nginx deny進(jìn)行屏蔽。

?

大部分時(shí)候是不進(jìn)行接入層限流的,而是限制流量穿透到后端薄弱的應(yīng)用層。

?

切流量

對于一個(gè)大型應(yīng)用,切流量是非常重要的,比如多機(jī)房有機(jī)房掛了、或者有機(jī)架掛了、或者有服務(wù)器掛了等都需要切流量,可以使用如下手段進(jìn)行切換:

1、DNS:切換機(jī)房入口;

2、LVS/HaProxy:切換故障的nginx接入層;

3、Nginx:切換故障的應(yīng)用層;

?

另外我們有些應(yīng)用為了更方便切換,還可以在nginx接入層做切換,通過nginx進(jìn)行一些流量切換,而沒有通過如LVS/HaProxy做切換。

?

?

其他

不需要cookie的應(yīng)用使用無狀態(tài)域名,如3.cn;

接入層請求頭過濾,只轉(zhuǎn)發(fā)有用的請求頭到后端應(yīng)用;

數(shù)據(jù)過濾邏輯前置,比如在接入層進(jìn)行請求參數(shù)的合法性過濾;

內(nèi)網(wǎng)設(shè)置合理的連接、讀、寫超時(shí)時(shí)間;

根據(jù)需要開啟gzip壓縮減少流量;

使用unix domain socket減少本機(jī)連接數(shù);

內(nèi)網(wǎng)考慮使用http長連接;

響應(yīng)請求時(shí),考慮響應(yīng)頭加上服務(wù)器ip等信息,方便調(diào)試。

?

我們處理的讀服務(wù)大部分都是KV的,因此抗流量的思路就是大量緩存;而且怎么讓緩存怎么更接近用戶,離用戶越近速度就越快。再一個(gè)點(diǎn)就是要考慮好降級方案,在異常情況下應(yīng)用不被拖垮拖死。我們系統(tǒng)大量使用了如nginx+lua+redis技術(shù),使用這些技術(shù)解決了我們很多讀服務(wù)問題。

?

來源:http://jinnianshilongnian.iteye.com/blog/2232271

總結(jié)

以上是生活随笔為你收集整理的构建亿级前端读服务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。