九醉蚁、應(yīng)用級緩存
A.緩存簡介
1.先從緩存中讀取數(shù)據(jù)黔龟,如果沒有氏身,再從慢速設(shè)備上讀取實(shí)際數(shù)據(jù)并同步到緩存
2.經(jīng)常讀取的數(shù)據(jù)、頻繁訪問的數(shù)據(jù)陷虎、熱點(diǎn)數(shù)據(jù)、I/O瓶頸數(shù)據(jù)凿掂、計(jì)算昂貴的數(shù)據(jù)、符合5分鐘法則和局部性原理的數(shù)據(jù)都可以緩存
B.緩存命中率
1.緩存命中率=從緩存中讀取次數(shù)/【總讀取次數(shù)(從緩存中讀取次數(shù)+從慢速設(shè)備上讀取次數(shù))】
C.緩存回收策略
1.基于空間惨恭,指緩存設(shè)置了存儲空間
2.基于容量萝究,指緩存設(shè)置了最大大小
3.基于時(shí)間
* TTL(Time To Live)存活期帆竹,即緩存數(shù)據(jù)從創(chuàng)建開始直到到期的一個(gè)時(shí)間段
* TTI(Time To Idle)空閑期,即緩存數(shù)據(jù)多久沒被訪問后移除緩存的時(shí)間
4.基于Java對象引用
5.回收算法
* FIFO(First In First Out)先進(jìn)先出算法
* LRU(Least Recently Used)最近最少使用算法
* LFU(Least Frequently Used)最不常用算法
D.Java緩存類型
1.堆緩存秒紧、堆外緩存、磁盤緩存叙淌、分布式緩存、
E.應(yīng)用級緩存示例
1.三個(gè)名詞
* SoR(system-of-record):記錄系統(tǒng)茂洒,即實(shí)際存儲原始數(shù)據(jù)的系統(tǒng)
* Cache:緩存,是SoR的快照數(shù)據(jù)
* 回源:即回到數(shù)據(jù)源頭獲取數(shù)據(jù)
2.Cache-Aside,即業(yè)務(wù)代碼圍繞著Cache寫,是由業(yè)務(wù)代碼直接維護(hù)緩存
* 讀場景块饺,先從緩存獲取數(shù)據(jù),如果沒有命中淮腾,則回源到SoR并將源數(shù)據(jù)放入緩存
* 寫場景洲押,先將數(shù)據(jù)寫入SoR杈帐,寫入成功后立即將數(shù)據(jù)同步寫入緩存
3.Cache-As-SoR,把Cache看作SoR站叼,所以操作都是對Cache進(jìn)行,然后Cache再委托給SoR進(jìn)行真實(shí)的讀寫
* read-through翔试,業(yè)務(wù)代碼首先調(diào)用Cache,如果Cache不命中由Cache回源到SoR,而不是業(yè)務(wù)代碼(即由Cache讀SoR)
* write-through怔球,稱為穿透寫模式/直寫模式,業(yè)務(wù)代碼首先調(diào)用Cache寫數(shù)據(jù)担汤,然后由Cache負(fù)責(zé)寫緩存和寫SoR,而不是由業(yè)務(wù)代碼
* write-behind率碾,也叫write-back审编,稱為回寫模式,是異步寫勘究,可以實(shí)現(xiàn)批量寫、合并寫、延時(shí)和限流
* copy-pattern超棺,copy-on-read(讀時(shí)復(fù)制)和copy-on-write(寫時(shí)復(fù)制)
F.性能測試
十、HTTP緩存
A.簡介
1.瀏覽器緩存是指當(dāng)我們使用瀏覽器訪問一些網(wǎng)站頁面或者HTTP服務(wù)時(shí)氧苍,根據(jù)服務(wù)器端返回的緩存設(shè)置響應(yīng)頭將響應(yīng)內(nèi)容緩存到瀏覽器,下次可以直接使用緩存內(nèi)容或者僅需要去服務(wù)器端驗(yàn)證內(nèi)容是否過期即可
B.HTTP緩存
1.Last-Modified:表示文檔的最后修改時(shí)間
2.Expires:表示文檔在瀏覽器中的過期時(shí)間
3.Cache-Control,表示瀏覽器緩存控制
4.from cache麸俘,從A頁面跳轉(zhuǎn)到A頁面或者從A頁面中轉(zhuǎn)到B頁面時(shí)
5.Age逞泄,一般用于緩存代理層(如CDN)各谚,表示此內(nèi)容在緩存代理層從創(chuàng)建到現(xiàn)在生存了多長時(shí)間
6.Vary赴穗,一般用于緩存代理層(如CDN),用于通知緩存服務(wù)器對于相同URL有著不同版本的響應(yīng)甸赃,比如壓縮版本和非壓縮版本
7.via,一般用于代理層(如CDN),表示訪問到最終內(nèi)容前經(jīng)過了哪些代理層稍计,用的什么協(xié)議,代理層是否緩存命中等
8.ETag裕循,用于發(fā)送到服務(wù)器端進(jìn)行內(nèi)容變更驗(yàn)證的臣嚣,而Catch-Control是用于控制緩存時(shí)間的(瀏覽器、代理層等)
C.HttpClient客戶端緩存
1.通過職責(zé)鏈模式來支持可插拔的組件結(jié)構(gòu)剥哑,客戶端緩存就是通過該模式實(shí)現(xiàn)的
D.Nginx HTTP緩存設(shè)置
1.Nginx提供了expires、etag株婴、if-modified-since指令來實(shí)現(xiàn)
E.Nginx代理層緩存
F.一些經(jīng)驗(yàn)
1.只緩存200狀態(tài)碼的響應(yīng)怎虫,像302等要根據(jù)實(shí)際場景決定
2.有些頁面不需要強(qiáng)一致,可以進(jìn)行幾秒的緩存
3.JS/CSS/image等一些內(nèi)容緩存時(shí)間可以設(shè)置為很久
4.假設(shè)商品詳情頁異步加載的一些數(shù)據(jù)困介,使用last-modified進(jìn)行過期控制大审,而服務(wù)器端做了邏輯修改,但內(nèi)容還是沒有修改的座哩,即內(nèi)容的最后修改時(shí)間沒變
5.商品詳情頁異步加載的一些數(shù)據(jù)徒扶,可以考慮更長時(shí)間的緩存
6.服務(wù)器端考慮使用tmpfs內(nèi)存文件系統(tǒng)緩存、SSD緩存根穷,使用服務(wù)器端負(fù)載均衡算法致性哈希來提升緩存命中率
7.緩存key要合理設(shè)計(jì)
8.AB測試/個(gè)性化需求時(shí)姜骡,一般會在響應(yīng)頭中添加源服務(wù)器信息导坟,但要考慮服務(wù)器端緩存
9.為了便于查找問題,一般會在響應(yīng)頭中添加源服務(wù)器信息
十一圈澈、多級緩存
A.多級緩存介紹
1.是指在整個(gè)系統(tǒng)架構(gòu)的不同系統(tǒng)層級進(jìn)行數(shù)據(jù)緩存惫周,以提升訪問效率
B.如何緩存數(shù)據(jù)
1.過期與不過期
* 不過期緩存場景,對于長尾訪問的數(shù)據(jù)康栈、大多數(shù)數(shù)據(jù)訪問頻率都很高的場景递递,或者是緩存空間足夠,都可以考慮不過期緩存啥么,比如用戶漾狼、分類、商品饥臂、價(jià)格逊躁、訂單等
* 過期緩存,如采用懶加載隅熙,一般用于緩存其他系統(tǒng)的數(shù)據(jù)(無法訂閱變更消息稽煤,或者成本很高)、緩存空間有限囚戚、低頻熱點(diǎn)緩存等場景
2.維度化緩存與增量緩存:將數(shù)據(jù)進(jìn)行維度化并增量更新(只更新變的部分)
3.大Value緩存:可以使用多線程實(shí)現(xiàn)的緩存酵熙,如Memcached來緩存大Value,Reids不合適
4.熱點(diǎn)緩存:一是使用更多的從緩存驰坊,二是在客戶端所有的應(yīng)用/代理層本地存儲一份避免訪問遠(yuǎn)程緩存
C.分布式緩存與應(yīng)用負(fù)載均衡
1.緩存分布式:一般采用分片實(shí)現(xiàn)匾二,即將數(shù)據(jù)分散到多個(gè)實(shí)例或多臺服務(wù)器,算法一般采用取模和一致性哈希
2.應(yīng)用負(fù)載均衡:一般采用輪詢和一致性哈希
3.根據(jù)實(shí)際情況動態(tài)選擇使用哪種算法
* 負(fù)載較低時(shí)拳芙,使用一致性哈希
* 熱點(diǎn)請求降級一致性哈希為輪詢察藐,或者如果請求數(shù)據(jù)有規(guī)律,則可考慮帶權(quán)重的一致性哈希
* 將熱點(diǎn)數(shù)據(jù)推送到接入層Nginx舟扎,直接響應(yīng)給用戶
D.熱點(diǎn)數(shù)據(jù)與更新緩存
1.單機(jī)全量緩存+主從:所有緩存都存儲在應(yīng)用本機(jī)分飞,回源之后會把數(shù)據(jù)更新到主Redis集群,然后通過主從模式復(fù)制到其他從Redis集群睹限,緩存的更新可以采用懶加載或者訂閱消息進(jìn)行同步
2.分布式緩存+應(yīng)用本地?zé)狳c(diǎn):需要在Nginx+Lua應(yīng)用中進(jìn)行應(yīng)用緩存來減少Redis集群的訪問沖擊譬猫,即首先查詢應(yīng)用本地緩存,如果命中羡疗,則直接緩存染服,如果沒有命中,則接著查詢Redis集群叨恨、回源到Tomcat柳刮,然后將數(shù)據(jù)緩存到應(yīng)用本地
3.實(shí)時(shí)熱點(diǎn)發(fā)現(xiàn)系統(tǒng):配合kafka或flume、storm等大數(shù)據(jù)工具
E.更新緩存與原子性
1.更新數(shù)據(jù)時(shí)使用更新時(shí)間戳或者版本對比
2.使用如canal訂閱數(shù)據(jù)庫binlog
3.將更新請求按照相應(yīng)的規(guī)則分期到多個(gè)隊(duì)列,然后每個(gè)隊(duì)列進(jìn)行單線程更新诚亚,更新時(shí)摘取最新的數(shù)據(jù)保存
4.用分布式鎖,在更新之前獲取相關(guān)的鎖
F.緩存崩潰與快速修復(fù)
1.取模:采用主從機(jī)制來避免實(shí)例壞了的問題
2.一致性哈希:主從機(jī)制午乓、降級機(jī)制
十二站宗、連接池線程池詳解
1.連接池如數(shù)據(jù)庫連接池、Redis連接池益愈、HTTP連接池梢灭,通過復(fù)用TCP連接來減少創(chuàng)建和釋放連接的時(shí)間來提升性能
2.線程池也是類似的,通過復(fù)用線程提升性能
3.池化可以使用Apache commons-pool 2來實(shí)現(xiàn)
A.數(shù)據(jù)庫連接池
1.數(shù)據(jù)庫連接池有很多實(shí)現(xiàn)蒸其,如C3P0敏释、DBCP、Druid等
2.如果并發(fā)量大建議:幾個(gè)池大小設(shè)置為一樣摸袁,禁用關(guān)閉孤兒連接钥顽,禁用定時(shí)器
3.如果并發(fā)量不大建議:可以按需設(shè)置池大小,禁用關(guān)閉孤兒連接靠汁,啟用定時(shí)器(注意MySQL空閑連接8小時(shí)自動斷開)
4.要注意網(wǎng)絡(luò)阻塞/不穩(wěn)定時(shí)的級聯(lián)效應(yīng)蜂大,即有熔斷和快速失敗機(jī)制
5.等待超時(shí)應(yīng)該盡可能小點(diǎn)(除非很有必要)
B.HttpClient連接池
1.須要注意:
* 在開啟長連接時(shí)才是真正的連接池
* JVM在停止或重啟時(shí),記得關(guān)閉連接池釋放連接
* HttpClient是線程安全的蝶怔,不要每次使用創(chuàng)建一個(gè)
* 如果連接池配置得比較大奶浦,則可以考慮創(chuàng)建多個(gè)HttpClient實(shí)例,而不是使用一個(gè)HttpClient實(shí)例
* 使用連接池時(shí)踢星,要盡快消費(fèi)響應(yīng)體并釋放連接到連接池澳叉,不要保持太久
C.線程池
1.每個(gè)線程都需要一個(gè)內(nèi)存棧,用于存儲如局部變量沐悦、操作棧等信息成洗,可以通過-Xss參數(shù)來調(diào)整每個(gè)線程棧大小
2.線程池一般配合隊(duì)列一起工作,使用線程池限制并發(fā)處理任務(wù)的數(shù)量
3.當(dāng)任務(wù)超過隊(duì)列大小時(shí)藏否,通過一定的拒絕策略來處理泌枪,這樣可以保護(hù)系統(tǒng)免受大流量而導(dǎo)致崩潰
4.線程池一般有核心線程池大小和線程池最大大小配置,當(dāng)線程池中的線程空閑一段時(shí)間將會被回收秕岛,而核心線程池中的線程不會被回收
5.Java提供了ExecutorService的三種實(shí)現(xiàn)
* ThreadPoolExecutor:標(biāo)準(zhǔn)線程池
* ScheduledThreadPoolExecutor:支持延遲任務(wù)的線程池
* ForkJoinPool:類似于ThreadPoolExecutor碌燕,但是使用work-stealing(任務(wù)竊取)模式
十三继薛、異步并發(fā)實(shí)戰(zhàn)
1.聚合數(shù)據(jù)數(shù)據(jù)需要調(diào)用多個(gè)其他服務(wù)獲取數(shù)據(jù)修壕、拼裝數(shù)據(jù)/模板,然后返回給前端遏考,聚合數(shù)據(jù)來源主要有依賴系統(tǒng)/服務(wù)慈鸠、緩存、數(shù)據(jù)庫等
2.系統(tǒng)之間的調(diào)用可以通過如HTTP接口調(diào)用(如HttpClient)灌具、SOA服務(wù)調(diào)用(如dubbo青团、thrift)等實(shí)現(xiàn)
3.通過異步并發(fā)并不能使響應(yīng)變得更快譬巫,更多是為了提升吞吐量、對請求更細(xì)粒度控制督笆,或是通過多依賴服務(wù)并發(fā)調(diào)用降低服務(wù)響應(yīng)時(shí)間
4.異步是針對CPU和IO的芦昔,當(dāng)IO沒有就緒時(shí)要讓出CPU來處理其他任務(wù),這才是異步
A.同步阻塞調(diào)用
1.即串行調(diào)用娃肿,響應(yīng)時(shí)間為所有依賴服務(wù)的響應(yīng)時(shí)間總和
B.異步Future
1.線程池配合Future實(shí)現(xiàn)咕缎,但是阻塞主請求線程,高并發(fā)時(shí)依然會造成線程數(shù)過多料扰、CPU上下文切換
C.異步Callback
1.通過回調(diào)機(jī)制實(shí)現(xiàn)凭豪,即首先發(fā)出網(wǎng)絡(luò)請求,當(dāng)網(wǎng)絡(luò)返回時(shí)回調(diào)相關(guān)方法
2.這種機(jī)制并不能提升性能晒杈,而是為了支撐大量并發(fā)連接或者提升吞吐量
D.異步編排CompletableFuture
1.可以對多個(gè)異步處理進(jìn)行編排嫂伞,實(shí)現(xiàn)更復(fù)雜的異步處理,其內(nèi)部使用ForkJoinPool實(shí)現(xiàn)異步處理
E.異步Web服務(wù)實(shí)現(xiàn)
1.借助Servlet3拯钻、CompletableFuture實(shí)現(xiàn)異步Web服務(wù)
F.請求緩存
1.一個(gè)服務(wù)需要多交查詢時(shí)(如一個(gè)商品需要重復(fù)調(diào)用多次商品接口)末早,可以使用異步多線程查詢
E.請求合并
1.CompletableFuture必須提前構(gòu)造好批量查詢,而Hystrix支持將多個(gè)單個(gè)請求黯然失色為單個(gè)批量請求说庭,即可以按照單個(gè)命令來請求然磷,但是,實(shí)際是以批量請求模式執(zhí)行
十四刊驴、如何擴(kuò)容
1.分而治之的思想來解決問題:
* 嘗試通過簡單擴(kuò)容來解決
* 如果簡單擴(kuò)容搞不定姿搜,就需要水平拆分和垂直拆分?jǐn)?shù)據(jù)/應(yīng)用來提升系統(tǒng)的伸縮性,即通過擴(kuò)容提升系統(tǒng)負(fù)載能力
* 如果通過水平拆分/垂直拆分還是搞不定捆憎,那就需要根據(jù)現(xiàn)有系統(tǒng)特性舅柜,從架構(gòu)層面進(jìn)行重構(gòu)甚至是重新設(shè)計(jì),即推倒重來
2.對于系統(tǒng)設(shè)計(jì)躲惰,理想的情況下應(yīng)支持線性擴(kuò)容和彈性擴(kuò)容
A.單體應(yīng)用垂直擴(kuò)容
1.如果能通過硬件快速解決致份,而且成本不高,應(yīng)該首先通過硬件擴(kuò)容來解決問題
2.硬件擴(kuò)容包括升級現(xiàn)有服務(wù)器
B.單體應(yīng)用水平擴(kuò)容
1.單體應(yīng)用水平擴(kuò)容是通過部署更多的鏡像來實(shí)現(xiàn)的础拨,應(yīng)用提供統(tǒng)一入口氮块,此時(shí)就需要負(fù)載均衡機(jī)制來實(shí)現(xiàn)
2.如果用戶會話數(shù)據(jù)分散在應(yīng)用系統(tǒng),就需要在負(fù)載均衡器開啟會話黏滯特性
3.如果數(shù)據(jù)庫的瓶頸是讀造成的诡宗,可以通過主從數(shù)據(jù)庫架構(gòu)將讀的流量分散到更多的從服務(wù)器上
C.應(yīng)用拆分
1.按照業(yè)務(wù)將一個(gè)大系統(tǒng)拆分為多個(gè)子系統(tǒng)滔蝉,要進(jìn)行業(yè)務(wù)代碼解耦,將功能分離到不同系統(tǒng)上塔沃,拆分后系統(tǒng)之間是物理隔離的蝠引,應(yīng)用層面原來是直接進(jìn)程內(nèi)方法調(diào)用,現(xiàn)在需要改成遠(yuǎn)程方法調(diào)用,如WebService螃概、RMI等矫夯,SOA方向等
2.服務(wù)化后,服務(wù)提供者可以根據(jù)當(dāng)前網(wǎng)站狀況隨時(shí)擴(kuò)容吊洼,通過服務(wù)注冊中心训貌,服務(wù)消費(fèi)者不需要進(jìn)行任何配置的更改,如Dubbo
3.可以使用MyCat/Corbar這種數(shù)據(jù)庫中間件提升連接數(shù)
4.所有應(yīng)用只調(diào)用讀/寫服務(wù)中間件融蹂,由讀/寫服務(wù)中間件訪問數(shù)據(jù)庫,減少整體的連接數(shù)弄企,然后通過MQ異構(gòu)數(shù)據(jù)超燃,從而不訪問有瓶頸的數(shù)據(jù)庫
5.可以將緩存/限流/防刷從各應(yīng)用系統(tǒng)中拆出來,放到單獨(dú)系統(tǒng)實(shí)現(xiàn)拘领,即接入層
D.數(shù)據(jù)庫拆分
1.按照業(yè)務(wù)維度進(jìn)行垂直拆分意乓,目的是解決多個(gè)表之間的IO競爭、單機(jī)容量問題等约素,拆分后會出現(xiàn)join查詢不行了届良,要解決跨庫join,分布式事務(wù)等問題
2.跨庫join可以考慮通過如全局表圣猎、ES搜索等異構(gòu)數(shù)據(jù)機(jī)制來實(shí)現(xiàn)
3.分庫分表是一種水平數(shù)據(jù)拆分士葫,會按照如ID、用戶送悔、時(shí)間等維度進(jìn)行數(shù)據(jù)拆分慢显,拆分算法可以是取模、哈希欠啤、區(qū)間荚藻、或者使用數(shù)據(jù)路由表等,也會導(dǎo)致跨庫/表join洁段、排序分頁应狱、自增ID、分布式事務(wù)等問題
4.對于跨庫/表join和排序分頁祠丝,可以對所有表進(jìn)行掃描然后做聚合疾呻,或者生成全局表、進(jìn)行查詢維度的數(shù)據(jù)異構(gòu)写半,再或者將數(shù)據(jù)同步到ES搜索
5.自增ID問題可以通過不同表罐韩、不同增長步長或分布式ID生成器解決
6.分布式事務(wù)可以考慮事務(wù)表、補(bǔ)償機(jī)制(執(zhí)行/回滾)污朽、TCC模式(預(yù)占/確認(rèn)/取消)散吵、Sagas模式(拆分事務(wù)+補(bǔ)償機(jī)制),業(yè)務(wù)應(yīng)盡量設(shè)計(jì)為最終一致性,而不是強(qiáng)一致性
7.對于一些特殊數(shù)據(jù)矾睦,可以考慮NoSQL晦款,讀流量多可以考慮Redis進(jìn)行數(shù)據(jù)緩存
8.部署多個(gè)Redis實(shí)例,通過Twemproxy并使用一致性哈希算法進(jìn)行分片枚冗,先通過HaProxy進(jìn)行Twemproxy的負(fù)載均衡缓溅,然后通過內(nèi)網(wǎng)域名進(jìn)行訪問
E.數(shù)據(jù)庫分庫分表示例
1.主要關(guān)心幾個(gè)問題:
* 是否需要在應(yīng)用層做改造來支持分庫分表,即是在應(yīng)用層進(jìn)行支持赁温,還是通過中間件層呢坛怪?
* 如果需要應(yīng)用層做支持,那么分庫分表的算法是什么股囊?
* 分庫分表后统舀,join是否支持携取,排序分頁是否支持巷蚪,事務(wù)是否支持
2.中間件層
* 好處是對應(yīng)用透明穗熬,就像查單庫一樣去查詢中間件層,可以支持多種編程語言内狗,可以減少應(yīng)用的總數(shù)據(jù)庫連接數(shù)
* 缺點(diǎn)是除了維護(hù)中間件外怪嫌,還要考慮中間件的HA/負(fù)載均衡等,增加了部署和維護(hù)的困難
* 開源中間件有Atlas柳沙、Cobar岩灭、Mycat等
3.分庫分表策略
* 取模:按照數(shù)值型主鍵取模來進(jìn)行分庫分表,也可以按照字符串主鍵哈希取模赂鲤,優(yōu)點(diǎn)是數(shù)據(jù)熱點(diǎn)分散川背,缺點(diǎn)是按照非主鍵維度進(jìn)行查詢時(shí)需要跨庫跨表查詢,擴(kuò)容需要建立新集群并進(jìn)行數(shù)據(jù)遷移
* 分區(qū):可按照時(shí)間分區(qū)蛤袒、范圍分區(qū)進(jìn)行分庫分表熄云,缺點(diǎn)是存在熱點(diǎn),但是易于水平擴(kuò)展妙真,能避免數(shù)據(jù)遷移缴允,也可以取模+分區(qū)組合使用
F.數(shù)據(jù)異構(gòu)
1.主要按照不同查詢維度建立表結(jié)構(gòu),這樣就可以按照這種不同維度進(jìn)行查詢珍德,有查詢維度異構(gòu)练般、聚合數(shù)據(jù)異構(gòu)等
2.在數(shù)據(jù)量和訪問量雙高時(shí)使用數(shù)據(jù)異構(gòu)是非常有效的,但增加了架構(gòu)的復(fù)雜度锈候,可以通過訂閱MQ或者binlog并解析實(shí)現(xiàn)
3.查詢維度異構(gòu):異構(gòu)數(shù)據(jù)主要存儲數(shù)據(jù)之間的關(guān)系薄料,然后通過查詢源庫查詢實(shí)際數(shù)據(jù),有時(shí)可以通過數(shù)據(jù)冗余存儲來減少源庫查詢或者提升查詢性能
4.聚合數(shù)據(jù)異構(gòu):將數(shù)據(jù)聚合后異構(gòu)存儲到KV存儲集群(如存儲JSON)泵琳,這樣只需要一次查詢就能得到所有的展示數(shù)據(jù)
G.任務(wù)系統(tǒng)擴(kuò)容
1.Elastic-Job
十五摄职、隊(duì)列術(shù)
1.隊(duì)列誊役,在數(shù)據(jù)結(jié)構(gòu)中是一種線性表,從一端插入數(shù)據(jù)谷市,然后從另一端刪除數(shù)據(jù)
2.保證最終一致性蛔垢,不需要強(qiáng)一致性,可以考慮隊(duì)列處理迫悠,需要考慮消息處理的有序性如何保證鹏漆、是否能重復(fù)消費(fèi)及如何保證重復(fù)消費(fèi)的冪等性
3.經(jīng)常使用隊(duì)列進(jìn)行異步處理、系統(tǒng)解耦创泄、數(shù)據(jù)同步艺玲、流量削峰、擴(kuò)展性鞠抑、緩沖等
A.應(yīng)用場景
1.異步處理:發(fā)送郵件饭聚、積分等,緩存過期時(shí)異步更新緩存碍拆、寫日志等若治,通過異步處理慨蓝,可以提升主流程響應(yīng)速度感混,而主流程/非重要處理可以集中處理,還可以將任務(wù)聚合批量處理礼烈,可以使用消息隊(duì)列/任務(wù)隊(duì)列來進(jìn)行異步處理
2.系統(tǒng)解耦:如下單后通知生產(chǎn)配貨系統(tǒng)弧满、發(fā)票系統(tǒng)等,業(yè)務(wù)不需要實(shí)時(shí)處理此熬、不需要強(qiáng)一致庭呜,只需要保證最終一致性即可,可能通過消息隊(duì)列/任務(wù)隊(duì)列進(jìn)行系統(tǒng)解耦
3.數(shù)據(jù)同步:如MySQL同步到Redis犀忱、或機(jī)房同步募谎、主從同步等,可以考慮使用databus阴汇、canal数冬、otter等,使用數(shù)據(jù)總線隊(duì)列進(jìn)行數(shù)據(jù)同步的好處是可以保證數(shù)據(jù)修改的有序性
4.流量削峰:系統(tǒng)瓶頸一般在數(shù)據(jù)庫上搀庶,可以考慮使用隊(duì)列將變更請求暫時(shí)放入隊(duì)列拐纱,通過緩存+隊(duì)列暫存的方式將數(shù)據(jù)庫流量削峰,對于秒殺系統(tǒng)哥倔,可以使用隊(duì)列進(jìn)行排隊(duì)和限流
B.緩沖隊(duì)列
1.典型的如Log4j的日志緩沖區(qū)
2.通過緩沖區(qū)隊(duì)列可以實(shí)現(xiàn)批量處理秸架、異步處理和平滑流量
C.任務(wù)隊(duì)列
1.可以將一些不需要與主線程同步執(zhí)行的任務(wù)扔到任務(wù)隊(duì)列進(jìn)行異步處理
2.可以實(shí)現(xiàn)異步處理、任務(wù)分解/聚合處理
D.消息隊(duì)列
1.ActiveMQ咆蒿、Kafka东抹、Redis等
2.使用消息隊(duì)列存儲各業(yè)務(wù)數(shù)據(jù)蚂子,其他系統(tǒng)根據(jù)需要訂閱即可,常見的訂閱模式是:點(diǎn)對點(diǎn)(一個(gè)消息只有一個(gè)消費(fèi)者)府阀、發(fā)布訂閱(一個(gè)消息可以有多個(gè)消費(fèi)者)
3.雙寫模式缆镣,同時(shí)寫DB和MQ,然后異構(gòu)系統(tǒng)可以訂閱MQ進(jìn)行業(yè)務(wù)處理试浙,沒有事務(wù)保證
4.不要在事務(wù)中摻雜MQ董瞻、RPC等
5.訂閱數(shù)據(jù)庫日志機(jī)制來實(shí)現(xiàn)數(shù)據(jù)庫變更捕獲,生產(chǎn)系統(tǒng)只需要單寫DB田巴,然后通過Canal訂閱數(shù)據(jù)庫binlog實(shí)現(xiàn)數(shù)據(jù)庫數(shù)據(jù)變更捕獲钠糊,然后業(yè)務(wù)端訂閱Canal進(jìn)行業(yè)務(wù)處理,這種方式可以保證一致性
6.可以實(shí)現(xiàn)異步處理壹哺、系統(tǒng)解耦和數(shù)據(jù)異構(gòu)
E.請求隊(duì)列
1.在Web環(huán)境下對用戶請求排隊(duì)抄伍,可進(jìn)行:流量控制、請求分級管宵、請求隔離
2.一般用于前端入口
3.漏斗模型
F.數(shù)據(jù)總線隊(duì)列
1.如數(shù)據(jù)庫變更后需要同步數(shù)據(jù)到緩存截珍,或者需要將一個(gè)機(jī)房的數(shù)據(jù)同步到另一個(gè)機(jī)房,只是數(shù)據(jù)維度的同步
2.可以保證數(shù)據(jù)的有序性
3.Canal箩朴、databusotter岗喉、kettle
G.混合隊(duì)列
H.其他隊(duì)列
1.優(yōu)先級隊(duì)列:優(yōu)先處理緊急任務(wù),考慮對隊(duì)列進(jìn)行分級
2.副本隊(duì)列:系統(tǒng)重構(gòu)或上新功能時(shí)炸庞,考慮副本隊(duì)列钱床,當(dāng)業(yè)務(wù)出現(xiàn)問題時(shí),可以對這些消息進(jìn)行回放
3.鏡像隊(duì)列:在訂閱量達(dá)到極限時(shí)埠居,使用鏡像隊(duì)列解決
4.隊(duì)列并發(fā)數(shù):不是增大隊(duì)列并發(fā)連接數(shù)消費(fèi)能力也隨著增加查牌,也不會因?yàn)樵黾恿讼M(fèi)服務(wù)器消費(fèi),并發(fā)能力也隨之增加滥壕,需要根據(jù)實(shí)際情況來設(shè)置合理的并發(fā)連接數(shù)
5.推送拉戎窖铡:消息體內(nèi)容不是越全越好,需要根據(jù)業(yè)務(wù)設(shè)計(jì)消息體绎橘,根據(jù)實(shí)際情況決定是使用推送方式(將系統(tǒng)需要的所有信息推送過去)還是使用拉取方式(只推送ID)
I.Disruptor+Redis隊(duì)列
J.下單系統(tǒng)水平可擴(kuò)展架構(gòu)
1.如果把訂單放入緩沖隊(duì)列胁孙,然后能迅速同步到訂單中心,就可以把下單邏輯和操作訂單邏輯分開金踪,用戶下單只操作緩沖表浊洞,而操作訂單只操作訂單表
2.整體流程
* 用戶提交訂單后,調(diào)用訂單號生成服務(wù)胡岔,然后結(jié)算服務(wù)會進(jìn)行一些業(yè)務(wù)處理法希,最后調(diào)用 下單服務(wù)提交訂單
* 下單服務(wù)將訂單寫入訂單緩沖表,下單服務(wù)和訂單緩存表可以水平擴(kuò)展靶瘸。寫入緩沖表成功后苫亦,將訂單寫入緩存毛肋,從而前端用戶可以查看到當(dāng)前訂單。如果下單服務(wù)有問題屋剑,則可以考慮直接降級將訂單寫入訂單中心
* 接著緩沖同步Worker輪詢這些緩沖表
* 同步Wroker將訂單同步到訂單中心润匙,如果訂單中心數(shù)據(jù)有變更,則更新訂單緩存
K.基于Canal實(shí)現(xiàn)數(shù)據(jù)異構(gòu)
1.訂閱數(shù)據(jù)庫binlog日志唉匾,模擬數(shù)據(jù)庫的主從同步機(jī)制孕讳,然后解析變更日志將數(shù)據(jù)異構(gòu),也能保證數(shù)據(jù)一致性
2.可以進(jìn)行訂單列表異構(gòu)巍膘、商家維度異構(gòu)厂财、ES搜索異構(gòu)、訂單緩存異構(gòu)等
3.Canal架構(gòu)
十六峡懈、構(gòu)建需求響應(yīng)式億級商品詳情頁
1.數(shù)據(jù)閉環(huán)璃饱,即數(shù)據(jù)的自我管理,或者說是數(shù)據(jù)都在自己的系統(tǒng)里維護(hù)肪康,不依賴于任何其他系統(tǒng)荚恶,包括:
* 數(shù)據(jù)異構(gòu)
* 數(shù)據(jù)原子化
* 數(shù)據(jù)聚合,將多個(gè)原子數(shù)據(jù)聚合為一個(gè)大JSON數(shù)據(jù)
* 數(shù)據(jù)存儲
2.數(shù)據(jù)維度化磷支,數(shù)據(jù)按照維度和作用進(jìn)行維度化谒撼,可以分離存儲,進(jìn)行更有效地存儲和使用齐唆,如:
* 商品基本信息嗤栓,標(biāo)題冻河、擴(kuò)展屬性箍邮、特殊屬性、圖片等
* 商品介紹信息叨叙,商品維度商家模板锭弊、商品介紹等
* 非商品維度的其他信息,包括分類信息擂错、商家信息味滞、店鋪信息等
* 商品維度其他信息(異步加載),價(jià)格钮呀、促銷剑鞍、配送至等
3.拆分系統(tǒng)
4.Worker無狀態(tài)化+任務(wù)化
* 對數(shù)據(jù)異構(gòu)和數(shù)據(jù)同步Worker進(jìn)行無狀態(tài)化設(shè)計(jì),這樣可以水平擴(kuò)展
* 應(yīng)用雖然是無狀態(tài)化的爽醋,但是配置文件還是有狀態(tài)的蚁署,每個(gè)機(jī)房一套配置,這樣每個(gè)機(jī)房只讀取當(dāng)前機(jī)房數(shù)據(jù)
* 任務(wù)多隊(duì)列化蚂四,包括任務(wù)等待隊(duì)列光戈、任務(wù)排重隊(duì)列哪痰、本地任務(wù)隊(duì)列、失敗任務(wù)隊(duì)列
* 隊(duì)列優(yōu)先級化久妆,分為普通隊(duì)列晌杰、刷數(shù)據(jù)隊(duì)列、高優(yōu)先級隊(duì)列
* 任務(wù)副本隊(duì)列筷弦,當(dāng)上線后業(yè)務(wù)出現(xiàn)問題時(shí)肋演,修正邏輯可以回放,從而修復(fù)數(shù)據(jù)
* 在設(shè)計(jì)消息時(shí)烂琴,按照維度更新
5.異步化+并發(fā)化
* 使用消息異步化進(jìn)行系統(tǒng)解耦合惋啃,通過消息通知變更,然后再調(diào)用相應(yīng)接口獲取相關(guān)數(shù)據(jù)
* 緩存數(shù)據(jù)更新異步化监右,同步調(diào)用服務(wù)边灭,但異步更新緩存
* 讓可并行任務(wù)并發(fā)化,可以并發(fā)調(diào)用聚合
* 前端服務(wù)異步化/聚合健盒,可以對異步請求做合并
6.多級緩存化
* 瀏覽器緩存:頁面之間來回跳轉(zhuǎn)時(shí)走local cache绒瘦,打開頁面時(shí)使用Last-Modified去CDN驗(yàn)證是否過期
* CDN緩存:用戶去離自己最近的CDN節(jié)點(diǎn)拿數(shù)據(jù)
* 服務(wù)器端應(yīng)用本地緩存:Nginx+Lua架構(gòu),使用HttpLuaModule模塊的shared dict做本地緩存或內(nèi)存級Proxy Cache
7.動態(tài)化
* 數(shù)據(jù)獲取動態(tài)化:按維度獲取數(shù)據(jù)
* 模板渲染實(shí)時(shí)化:支持隨時(shí)變更模板需求
* 重啟應(yīng)用秒級化:使用Nginx+Lua架構(gòu)
* 需求上線快速化
8.彈性化:使用容器技術(shù)
9.降級開關(guān)
* 推送服務(wù)器推送降級開關(guān)扣癣,使開關(guān)集中化維護(hù)惰帽,然后通過推送機(jī)制推送到各個(gè)服務(wù)器
* 可降級的多級讀服務(wù)為前端數(shù)據(jù)集群->數(shù)據(jù)異構(gòu)集群->動態(tài)服務(wù)(調(diào)用依賴系統(tǒng))
10.多機(jī)房多活:應(yīng)用無狀態(tài),通過在配置文件中配置各自機(jī)房的數(shù)據(jù)集群來完成數(shù)據(jù)讀取
11.兩種壓測方案
* 線下壓測:Apache ab父虑、Apache Jmeter该酗,可以簡單壓測單機(jī)峰值吞吐量,但會存在熱點(diǎn)問題
* 線上壓測:可以使用Tcpcopy直接把線上流量導(dǎo)入到壓測服務(wù)器士嚎,可以壓測出機(jī)器的性能呜魄,或直接在頁面埋點(diǎn),讓用戶壓測
十七莱衩、京東商品詳情頁服務(wù)閉環(huán)實(shí)踐
A.為什么需要統(tǒng)一服務(wù)
1.在統(tǒng)一管理和監(jiān)控下爵嗅,出問題可以統(tǒng)一降級
2.可以把一些相關(guān)接口合并輸出,減少頁面的異步加載請求
3.一些前端邏輯后移到服務(wù)器端笨蚁,前端只做展示睹晒,不進(jìn)行邏輯處理
B.整體架構(gòu)
C.一些架構(gòu)思路和總結(jié)
1.兩種讀服務(wù)架構(gòu)
* 讀取分布式Redis數(shù)據(jù)架構(gòu)
* 讀取本地Redis數(shù)據(jù)架構(gòu)
2.本地緩存
* 使用Nginx共享字典作為本地緩存
* 采用維度化存儲緩存數(shù)據(jù),增量獲取失效緩存數(shù)據(jù)
* 使用一致性哈希和本地緩存可以提升命中率
3.多級緩存
4.統(tǒng)一入口/服務(wù)閉環(huán)
D.引入Nginx接入層
1.在設(shè)計(jì)系統(tǒng)時(shí)需要把一些邏輯盡可能前置括细,以此來減輕后端核心邏輯的壓力伪很,而且可以讓服務(wù)升級/服務(wù)降級非常方便地進(jìn)行切換
2.數(shù)據(jù)校驗(yàn)/過濾邏輯前置,請求進(jìn)入接入層后奋单,對參數(shù)進(jìn)行校驗(yàn)锉试,如果校驗(yàn)不合法,直接拒絕這次請求
3.緩存前置辱匿,緩存前置到接入層來進(jìn)行熱點(diǎn)數(shù)據(jù)的削峰键痛,配合一致性哈希也許可以提升緩存的命中率
4.業(yè)務(wù)邏輯前置炫彩,接入層實(shí)現(xiàn)一些業(yè)務(wù)邏輯,如果在高峰時(shí)出問題絮短,可以在這一層做一些邏輯升級
5.降級開關(guān)前置
6.A/B測試江兢,可以在Lua中根據(jù)請求的信息調(diào)用不同的服務(wù),或者通過upstream分組
7.灰度發(fā)布/流量切換
8.監(jiān)控服務(wù)質(zhì)量丁频,記錄status杉允、request_time、response_time來監(jiān)控服務(wù)質(zhì)量
9.限流席里,對大多數(shù)請求按照IP請求數(shù)限流叔磷,對于登錄用戶按照用戶限流,對于讀取緩存的請求不進(jìn)行限流奖磁,只對打到后端系統(tǒng)的請求進(jìn)行限流
E.前端業(yè)務(wù)邏輯后置
1.前端JS應(yīng)該盡可能少寫業(yè)務(wù)邏輯和一些切換邏輯(CDN原因)
F.前端接口服務(wù)器端聚合
1.在接入層使用Lua協(xié)程機(jī)制并發(fā)調(diào)用多個(gè)相關(guān)服務(wù)改基,最后把這些服務(wù)進(jìn)行合并
G.服務(wù)隔離
1.目的是防止因?yàn)槟承┓?wù)抖動而造成整個(gè)應(yīng)用內(nèi)的所有服務(wù)不可用
2.應(yīng)用內(nèi)線程池隔離
3.部署/分組隔離,為不同的消費(fèi)方提供不同的分組咖为,相互間不影響
4.拆應(yīng)用隔離:如果一個(gè)服務(wù)調(diào)用量巨大秕狰,可以把這個(gè)服務(wù)單獨(dú)拆出去做成一個(gè)應(yīng)用
十八、使用OpenResty開發(fā)高性能Web應(yīng)用
A.OpenResty簡介
1.Nginx設(shè)計(jì)為一個(gè)主進(jìn)程多個(gè)工作進(jìn)程的工作模式躁染,每個(gè)進(jìn)程是單線程來處理多個(gè)連接鸣哀,而且每個(gè)工作進(jìn)程采用了非阻塞I/O來處理多個(gè)連接,從而減少了線程上下文切換吞彤,實(shí)現(xiàn)了公認(rèn)的高性能我衬、高并發(fā)
2.Lua是一種輕量級、可嵌入式的腳本語言饰恕,可以非常容易地嵌入到其他語言中使用挠羔,提供了協(xié)程并發(fā),即以同步調(diào)用的方式進(jìn)行異步執(zhí)行懂盐,從而實(shí)現(xiàn)并發(fā)褥赊,還提供了閉包機(jī)制糕档,函數(shù)可以作為First Class Value進(jìn)行參數(shù)傳遞莉恼,實(shí)現(xiàn)了標(biāo)記清除垃圾收集
3.ngx_lua將Lua嵌入到Nginx中,就是接收請求速那、參數(shù)解析俐银、功能處理、返回響應(yīng)這幾步的API
4.場景:
* Web應(yīng)用:進(jìn)行一些業(yè)務(wù)邏輯處理端仰,甚至進(jìn)行耗CPU的模板渲染捶惜,一般流程包括mysql/Reids/HTTP獲取數(shù)據(jù)、業(yè)務(wù)處理荔烧、產(chǎn)生JSON/XML/模板渲染內(nèi)容
* 接入網(wǎng)關(guān):實(shí)現(xiàn)如數(shù)據(jù)校驗(yàn)前置吱七、緩存前置汽久、數(shù)據(jù)過濾、API請求聚合踊餐、A/B測試景醇、灰度發(fā)布、降級吝岭、監(jiān)控等功能
* Web防火墻:可以進(jìn)行IP/URL/UserAgent/Referer黑名單三痰、限流等功能
* 緩存服務(wù)器:可以對響應(yīng)內(nèi)容進(jìn)行緩步,減少到達(dá)后端的請求窜管,從而提升性能
* 其他:如靜態(tài)資源服務(wù)器散劫、消息推送服務(wù)、縮略圖裁剪等
B.基于OpenResty的常用架構(gòu)模式
1.負(fù)載均衡
2.單機(jī)閉環(huán)
* 單機(jī)閉環(huán)即所有想要的數(shù)據(jù)都能從本服務(wù)器中直接獲取幕帆,在大多數(shù)時(shí)候無須通過網(wǎng)絡(luò)去其他服務(wù)器獲取
* 左一获搏,應(yīng)用誰也不依賴,例如Cookie白名單功能
* 中間失乾,讀取本機(jī)文件系統(tǒng)颜凯,如靜態(tài)資源合并,nginx-http-concat仗扬,nginx-lua-static-merger症概,頁面嵌套,Nginx自帶的SSI(Server Side Include)
* 右一早芭,讀取的本機(jī)的Redis彼城,或者Redis集群,或者如SSDB這種持久化存儲退个,或者其他存儲系統(tǒng)
* 都需要Wroker進(jìn)行數(shù)據(jù)推送募壕,為防止本機(jī)數(shù)據(jù)丟失,可采用
* 首先讀本機(jī)语盈,如果沒數(shù)據(jù)舱馅,則會回源到相應(yīng)的Web應(yīng)用,從數(shù)據(jù)源拉取原始數(shù)據(jù)進(jìn)行處理
3.分布式閉環(huán)
* 單機(jī)閉環(huán)兩個(gè)問題:數(shù)據(jù)不一致問題刀荒;存儲瓶頸問題
* 解決數(shù)據(jù)不一致的比較好的辦法是采用主從或者分布式集中存儲代嗤,遇到存儲瓶頸就需要進(jìn)行按照業(yè)務(wù)鍵進(jìn)行分片,將數(shù)據(jù)分散到多臺服務(wù)器中
4.接入網(wǎng)關(guān)
* 接入網(wǎng)關(guān)也叫接入層缠借,即接收到流量的入口
* 核心接入Nginx功能:動態(tài)負(fù)載均衡(balancer_by_lua干毅、upsync)、防DDoS攻擊限流泼返、非法請求過濾硝逢、請求聚合、請求頭過濾、緩存服務(wù)(Nginx Proxy Cache)
* 業(yè)務(wù)Nginx功能:緩存(Shared Dict/Nginx Proxy Cache->Redis->回源)渠鸽、業(yè)務(wù)邏輯叫乌、細(xì)粒度限流(lua-resty-limit-traffic)、降級徽缚、A/B測試和灰度發(fā)布综芥、服務(wù)質(zhì)量監(jiān)控
5.Web應(yīng)用
* 指頁面模板渲染類型應(yīng)用或者API服務(wù)類型應(yīng)用
C.如果使用OpenResty開發(fā)Web應(yīng)用
D.基于OpenResty的常用功能總結(jié)
1.適合開發(fā)業(yè)務(wù)邏輯單一、核心代碼行數(shù)較少的應(yīng)用猎拨,不適合業(yè)務(wù)邏輯復(fù)雜膀藐、功能繁多的業(yè)務(wù)型或者企業(yè)級應(yīng)用
2.包括:動態(tài)負(fù)載均衡、防火墻(DDoS红省、IP/URL/UserAgent/Referer黑名單额各、防盜鏈等)、限流吧恃、降級虾啦、A/B測試和灰度發(fā)布、多級緩存模式痕寓、服務(wù)器端請求聚合傲醉、服務(wù)質(zhì)量監(jiān)控
E.一些問題
1.在開發(fā)Nginx應(yīng)用時(shí),使用UTF-8編碼
2.GBK轉(zhuǎn)碼解碼時(shí)呻率,應(yīng)使用GB18030
3.cjson庫對于像\uab1這種錯(cuò)誤的unicode轉(zhuǎn)碼會失敗硬毕,可以使用純Lua編寫的dkjson
4.社區(qū)版Nginx不支持upstream的域名動態(tài)解析,可以考慮proxy_pass礼仗,然后配合resolver來實(shí)現(xiàn)吐咳,或者在Lua中進(jìn)行HTTP調(diào)用,如果DNS遇到性能瓶頸元践,可以考慮在本機(jī)部署如dnsmasq來緩存韭脊,或者考慮使用balancer_by_lua功能實(shí)現(xiàn)動態(tài)upstream
5.為響應(yīng)添加處理服務(wù)器IP的響應(yīng)頭,方便定位問題
6.根據(jù)業(yè)務(wù)設(shè)置合理的超時(shí)時(shí)間
7.運(yùn)行CDN的業(yè)務(wù)单旁,發(fā)生錯(cuò)誤時(shí)沪羔,不要給返回的500/503/302/301等非正常響應(yīng)設(shè)置緩存
十九、應(yīng)用數(shù)據(jù)靜態(tài)化架構(gòu)高性能單頁Web應(yīng)用
A.整體架構(gòu)
1.靜態(tài)化頁面的方案:直接將生成的靜態(tài)頁推送到相關(guān)服務(wù)器上即可象浑,需要考慮文件操作的原子化問題
2.動態(tài)化方案:CMS系統(tǒng)蔫饰、控制系統(tǒng)、前端展示系統(tǒng)
3.CMS系統(tǒng)
* 模板動態(tài)在CMS系統(tǒng)中維護(hù)
* 原始數(shù)據(jù)存儲到“元數(shù)據(jù)存儲MySQL”中即可
* 提供發(fā)布到“發(fā)布數(shù)據(jù)存儲Redis”的控制融柬,將CMS系統(tǒng)中的原始數(shù)據(jù)和模板數(shù)據(jù)組裝成聚合數(shù)據(jù)(JSON存儲)同步到“發(fā)布數(shù)據(jù)存儲Redis”
4.前端展示系統(tǒng)
* 獲取URL死嗦,使用URL作為Key從本機(jī)“發(fā)布數(shù)據(jù)存儲Redis”獲取數(shù)據(jù)
* 如果沒有數(shù)據(jù)或者異常,則從主“發(fā)布數(shù)據(jù)存儲Redis”獲取
* 如果也發(fā)生異常粒氧,直接調(diào)用CMS系統(tǒng)暴露的API,直接從元數(shù)據(jù)存儲MySQL中獲取數(shù)據(jù)
5.控制系統(tǒng)
* 版本降級节腐,使用URL和當(dāng)前版本的字段即可
* 灰度發(fā)布外盯,控制哪些URL需要灰度發(fā)布
B.數(shù)據(jù)和模板動態(tài)化
1.將數(shù)據(jù)和模板都進(jìn)行動態(tài)化存儲摘盆,這樣可以在CMS進(jìn)行數(shù)據(jù)和模板的變更,實(shí)現(xiàn)前端和后端開發(fā)人員的分離
2.模板和數(shù)據(jù)可以是一對多的關(guān)系
C.多版本機(jī)制
1.預(yù)發(fā)布版本饱苟,更容易讓測試人員在實(shí)際環(huán)境中進(jìn)行驗(yàn)證
2.灰度版本孩擂,只需要簡單的開關(guān)控制,就可以進(jìn)行A/B測試
3.正式版本箱熬,存儲多個(gè)歷史正式版本
D.異常問題
1.本機(jī)從“發(fā)布數(shù)據(jù)存儲Redis”和主"發(fā)布數(shù)據(jù)存儲Redis"都不能用了类垦,可以直接調(diào)用CMS系統(tǒng)暴露的HTTP服務(wù),直接從元數(shù)據(jù)存儲MySQL獲取數(shù)據(jù)
2.數(shù)據(jù)和模板獲取到了城须,但是渲染模板出錯(cuò)了蚤认,使用上一個(gè)版本的數(shù)據(jù)進(jìn)行渲染
3.數(shù)據(jù)和模板都沒問題,但是因?yàn)橐恍┦韬龈夥ィ秩境鰜淼捻撁驽e(cuò)亂了砰琢,或者有些區(qū)域出現(xiàn)了空白,可以根據(jù)自己的場景定義異常掃描庫良瞧,發(fā)警告給相關(guān)人員陪汽,并自動降級到上一個(gè)版本
二十、使用OpenResty開發(fā)Web服務(wù)
A.單DB架構(gòu)
1.DB+Cache/數(shù)據(jù)庫讀寫分離架構(gòu)
2.OpenResty+Local Redis+MySQL集群架構(gòu)
3.OpenResty+Redis集群+MySQL集群架構(gòu)
4.使用Twemproxy集群分片
二十一褥蚯、使用OpenResty開發(fā)商品詳情頁