<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          億級流量網(wǎng)站構(gòu)架核心技術(shù)

          共 6505字,需瀏覽 14分鐘

           ·

          2021-09-19 15:04

          高并發(fā)原則

          • 無狀態(tài)

          • 拆分

            • 系統(tǒng)維度:根據(jù)系統(tǒng)功能/業(yè)務(wù)進行拆分

            • 功能維度:對一個系統(tǒng)進行功能再拆分

            • 讀寫維度:根據(jù)讀寫比例進行拆分

            • AOP維度:根據(jù)訪問特征

            • 模塊維度:比如按照基礎(chǔ)或代碼維護特征進行拆分

          • 服務(wù)化:進程內(nèi)服務(wù) -> 單機遠程服務(wù) -> 集群手動注冊服務(wù) -> 自動注冊和發(fā)現(xiàn)服務(wù) -> 服務(wù)的分組/隔離/路由 -> 服務(wù)治理(限流/黑白名單等)

          • 消息隊列:服務(wù)解耦、異步處理、流量削峰/緩沖等

            • 消息隊列進行多個鏡像復(fù)制

            • 重試功能、防重、(冪等性)

            • 失敗處理、日志、報警

            • 大流量緩沖:一般是犧牲強一致性,而保證最終一致性

            • 數(shù)據(jù)校對:數(shù)據(jù)校對與修正來保證數(shù)據(jù)的一致性和完整性

          • 數(shù)據(jù)異構(gòu):形成數(shù)據(jù)閉環(huán),任何依賴系統(tǒng)出問題了,還是能正常工作,只是更新會有積壓,但不影響前端展示

            • 數(shù)據(jù)異構(gòu):通過如MQ接受數(shù)據(jù)變更,然后原子化存儲到合適的存儲引擎,如Redis等。目的是把數(shù)據(jù)從多個數(shù)據(jù)源拿過來

            • 數(shù)據(jù)聚合:可選的,目的是把這些數(shù)據(jù)做聚合,前端可以一個調(diào)用拿到全部數(shù)據(jù),該步驟一般存儲在KV存儲中

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

          • 緩存銀彈

            • 使用接入層提供的緩存機制:對于沒CDN緩存的應(yīng)用來說,可以考慮使用如Nginx搭建一層接入層,可以考慮以下機制:

            • 使用應(yīng)用層提供的緩存機制:使用Tomcat時可以使用堆內(nèi)緩存/堆外緩存;local redis cache在應(yīng)用所在服務(wù)器上部署一組redis,應(yīng)用直接讀取本機Redis數(shù)據(jù),多機之間使用主從機制同步數(shù)據(jù)

            • 使用分布式緩存:數(shù)據(jù)量太大,使用分片機制將流量分散到多臺,或直接使用分布式緩存實現(xiàn)。常見分片機制是一致性哈希

            • 靜態(tài)化/偽靜態(tài)化,使用服務(wù)器操作系統(tǒng)提供的緩存機制

            • URL重寫:將URL按照指定的順序或格式重寫,去除隨機數(shù)

            • 一致性哈希:按照指定的參數(shù)做一致性哈希,從而保證相同數(shù)據(jù)落到一臺服務(wù)器上

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

            • proxy_cache_lock:使用Lock機制,將多個回源合并為一個,以減少回源量,并設(shè)置相應(yīng)的Lock超時時間

            • shared_dict:如果架構(gòu)使用nginx+lux實現(xiàn),,可考慮使用Lua shared_dict進行cache,最大好處是reload緩存不會丟失

            • 對于托底(或兜底,指降級后顯示的)數(shù)據(jù)或異常數(shù)據(jù),不應(yīng)該讓其緩存,否則用戶會很長一段時間內(nèi)看到這些數(shù)據(jù)

            • 使用代理服務(wù)器(含CDN):一般有兩種機制:推送機制(當(dāng)內(nèi)容變更后主動推送到CDN邊緣節(jié)點),拉取機制(先訪問邊緣節(jié)點,當(dāng)沒有內(nèi)容時,回源到源服務(wù)器拿到內(nèi)容并存儲到節(jié)點上)。使用CDN需要考慮URL的設(shè)計,比如不能有隨機數(shù),否則每次都穿透CDN回源到源服務(wù)器;對于爬蟲,可以返回過期數(shù)據(jù)而不選擇回源

            • 使用鏡像服務(wù)器,使用P2P技術(shù)

            • 使用瀏覽器緩存:設(shè)置請求過期時間,對應(yīng)相應(yīng)頭Expires, Cache-control進行控制,適合于實時性不敏感數(shù)據(jù)

            • 客戶端應(yīng)用緩存:提前將內(nèi)容發(fā)到客戶端進行緩存

            • 客戶端:

            • 客戶端網(wǎng)絡(luò):代理服務(wù)器開啟緩存

            • 廣域網(wǎng):

            • 源站及源站網(wǎng)絡(luò):

          • 并發(fā)化

          • 方式

            • 應(yīng)用級緩存:緩存回收策略(空間/容量/時間),緩存回收算法(FIFO/LRU/LFU),java堆/java堆外/磁盤緩存,Guava/Ehcache/MapDB,緩存使用模式(Cache-Asize/Cache-As-SoR/Copy Pattern)

            • HTTP緩存:瀏覽器緩存,HttpClient客戶端緩存,nginx代理層緩存

            • 多級緩存:分布式緩存,熱點數(shù)據(jù)與更新緩存,更新緩存與原子性,緩存崩潰與快速修復(fù)

            • 池化:數(shù)據(jù)庫連接池,F(xiàn)ttpClient連接池,線程池

            • 異步并發(fā):同步阻塞調(diào)用,異步Future,異步CallBack,異步編排CompletableFuture,請求緩存,請求合并

            • 擴容:單體應(yīng)用垂直擴容,單體應(yīng)用水平擴容,應(yīng)用拆分,數(shù)據(jù)庫拆分(水平/垂直),使用sharding-jdbc分庫分表/讀寫分離,數(shù)據(jù)異構(gòu),任務(wù)系統(tǒng)擴容(Elastic-Job)

            • 隊列:異步處理/系統(tǒng)解耦/數(shù)據(jù)同步/流量削峰,緩沖隊列/任務(wù)隊列/消息隊列/請求隊列/數(shù)據(jù)總線隊列,Disruptor+Redis隊列,基于Canal實現(xiàn)數(shù)據(jù)異構(gòu)

          高可用原則

          • 負載均衡:負載均衡算法、失敗重試機制、健康檢查機制、動態(tài)負載均衡

          • 降級

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

            • 可降級的多級讀服務(wù):比如服務(wù)調(diào)用降級為只讀本地緩存、只讀分布式緩存、只讀默認降級數(shù)據(jù)

            • 開關(guān)前置化:如架構(gòu)師nginx+tomcat,將開關(guān)前置到nginx接入層,請求流量不回源后端tomcat或只小部分流量回源

            • 業(yè)務(wù)降級

            • 降級預(yù)案、自動降級/開關(guān)降級、讀服務(wù)/寫服務(wù)降級、多級降級、配置中心、使用Hystrix降級、使用Hystrix熔斷

          • 限流:

            • 惡意請求流量只訪問到cache

            • 對于穿透到后端的流量可以考慮使用nginx的limit模塊處理

            • 對于惡意IP可以使用nginx deny進行屏蔽

            • 限流算法、應(yīng)用級限流、分布式限流、接入層限流

          • 隔離:進程線程隔離、集群/機房隔離、讀寫隔離、動靜隔離、爬蟲/熱點隔離、使用Hystrix隔離、基于Servlet3的請求隔離

          • 超時與重試:代理層超時與重試、Web容器超時、中間件客戶端超時與重試、數(shù)據(jù)庫客戶端超時、NOSQL客戶端超時、業(yè)務(wù)超時、前端AJAX超時

          • 切流量:

            • DNS:切換機房入口

            • HttpDNS:主要APP場景下,在客戶端分配好流量入口,繞過運營商LocalDNS并實現(xiàn)更精準(zhǔn)流量調(diào)度

            • LVS/HaProxy:切換故障的nginx接入層

            • Nginx:切換故障的應(yīng)用層

          • 可回滾:版本化的目的是實現(xiàn)可審計可追溯,并且可回滾。如果程序或數(shù)據(jù)出錯時,如果有版本化機制,那就可以通過回滾恢復(fù)到最近一個正確的版本,比如事務(wù)回滾、代碼庫回滾、部署版本回滾、數(shù)據(jù)版本回滾、靜態(tài)資源版本回滾等。

          • 壓測與預(yù)案:系統(tǒng)壓測、系統(tǒng)優(yōu)化與容災(zāi)、應(yīng)急預(yù)案、

            • 監(jiān)控報警:服務(wù)器/系統(tǒng)/JVM/接口監(jiān)控、監(jiān)控時間段、報警閥值、通知方式

          業(yè)務(wù)設(shè)計原則

          • 防重設(shè)計:防重key、防重表

          • 冪等設(shè)計

          • 流程可定義:關(guān)聯(lián)、可復(fù)用流程,個性化流程

          • 狀態(tài)與狀態(tài)機

            • 比如訂單交易,會有正向狀態(tài)(待付款/待發(fā)貨/已發(fā)貨/完成)與逆向狀態(tài)(取消/退款),正向狀態(tài)與逆向狀態(tài)根據(jù)系統(tǒng)特征決定要不要分離存儲。狀態(tài)設(shè)計時應(yīng)有狀態(tài)軌跡,方便跟蹤訂單軌跡并記錄相關(guān)日志,萬一出問題時可回溯問題。

            • 比如訂單狀態(tài)的變遷(待支付->待發(fā)貨->已發(fā)貨->完成)。要考慮要不要使用狀態(tài)機來驅(qū)動狀態(tài)的變更和后續(xù)流程節(jié)點操作,尤其當(dāng)狀態(tài)很多的時候使用狀態(tài)機能更好地控制狀態(tài)遷移

            • 考慮并發(fā)狀態(tài)修改問題:一個訂單同時只能有一個修改、狀態(tài)變更的有序性、時間差

          • 后臺系統(tǒng)操作可反饋

          • 后臺系統(tǒng)審計化

          • 文檔和注釋

          • 備份

          負載均衡與反向代理

          四層負載均衡:首先DNS解析到LVS/F5,然后LVS/F5轉(zhuǎn)發(fā)給Nginx,再由Nginx轉(zhuǎn)發(fā)給后端Real Server

          兩層負載均衡是通過改寫報文的目標(biāo)MAC地址為上游服務(wù)器MAC地址,源IP和目標(biāo)IP地址是沒有改變的,負載均衡服務(wù)器和真實服務(wù)器共享同一個VIP,如LVS DR工作模式。
          四層負載均衡是根據(jù)端口將報文轉(zhuǎn)發(fā)到上游服務(wù)器(不同的IP地址+端口),如LVS NAT模式、HaProxy。
          七層負載均衡是根據(jù)端口號和應(yīng)用層協(xié)議如HTTP協(xié)議的主機名、URL,轉(zhuǎn)發(fā)報文到上游服務(wù)器(不同的IP地址+端口),如HaProxy、Nginx

          • 上游服務(wù)器配置:使用upstream server配置上游服務(wù)器

            • IP地址和端口

            • 權(quán)重

          • 負載均衡算法:

            • round-robin輪循

            • ip_hash

            • hash key [consistent]:對某一key進行哈希或使用一致性哈希算法

            • 哈希算法:根據(jù)請求uri進行負載均衡,可以使用nginx變量

            • least_conn

          • 失敗重試機制:配置當(dāng)超時或上游服務(wù)器不存活時,是否需要重試其他上游服務(wù)器

          • 服務(wù)器心跳檢查

            • TCP心跳檢查

            • HTTP心跳檢查

          隔離

          • 線程隔離:主要是指線程池隔離,實際使用時,會把請求分類,然后交給不同的線程池處理。當(dāng)一種業(yè)務(wù)的請求處理發(fā)生問題時,不會將故障擴散到其他線程池,從而保證其他服務(wù)可用。

          • 進程隔離:過渡方案,較好的解決方案是將系統(tǒng)拆分為多個子系統(tǒng)來實現(xiàn)物理隔離

          • 集群隔離

          • 機房隔離

          • 讀寫隔離:通過主從模式將讀和寫集群分離

          • 動靜隔離:動態(tài)內(nèi)容和靜態(tài)內(nèi)容隔離,一般應(yīng)將靜態(tài)資源放在CDN上

          • 爬蟲隔離:一種方法通過限流解決;另一種方法是在負載均衡層面將爬蟲路由到單獨集群,從而保證正常流量可用,爬蟲流量盡量可用

          • 熱點隔離:秒殺、搶購。讀熱點可用多級緩存,寫熱點可用緩存+隊列模式削峰

          • 資源隔離

          • 其他:

            • 環(huán)境隔離:測試環(huán)境、預(yù)發(fā)布環(huán)境/灰度環(huán)境、正式環(huán)境

            • 壓測隔離:真實數(shù)據(jù)、壓測數(shù)據(jù)

            • AB測試:不同用戶提供不同版本的服務(wù)

            • 查詢隔離:簡單、批量、復(fù)雜條件查詢分別路由到不同的集群

          Hystrix

          在一個分布式系統(tǒng)里,許多依賴不可避免的會調(diào)用失敗,比如超時、異常等,如何能夠保證在一個依賴出問題的情況下,不會導(dǎo)致整體服務(wù)失敗,這個就是Hystrix需要做的事情。Hystrix提供了熔斷、隔離、Fallback、cache、監(jiān)控等功能,能夠在一個、或多個依賴同時出現(xiàn)問題時保證系統(tǒng)依然可用。

          servlet3異步化模型:

          • 請求解析和業(yè)務(wù)處理線程池分離

          • 業(yè)務(wù)線程池隔離

          • 業(yè)務(wù)線程池監(jiān)控/運維/降級

          限流

          • 限流算法:令牌桶算法、漏桶算法

          • 應(yīng)用級限流:

            • 限流總并發(fā)/連接/請求數(shù)

            • 限制總資源數(shù)

            • 限流某個接口的總并發(fā)/請求數(shù)

            • 限流某個接口的時間窗請求數(shù):Guava

            • 平滑限流某個接口的請求數(shù):Guava RateLimiter

          • 分布式限流:redis+lua、 nginx+lua

          • 接入層線路:該層通常指請求流量的入口,主要目的為負載均衡、非法請求過濾、請求聚合、緩存、降級、限流、A/B測試、服務(wù)質(zhì)量監(jiān)控等

          • 節(jié)流:throttleFirst、throttleLast、throttleWithTimeout

          降級

          超時與重試機制

          回滾機制

          事務(wù)回滾:事務(wù)表、消息隊列、補償機制(執(zhí)行/回滾)、TCC模式(預(yù)占/確認/取消)、Sagas模式(拆分事務(wù)+補償機制)實現(xiàn)最終一致性

          壓測與預(yù)案

          應(yīng)用級緩存

          緩存回收策略:

          • 基于空間:到達存儲上限后按策略移除數(shù)據(jù)

          • 基于容量:設(shè)置最大大小,當(dāng)緩存條數(shù)超過時,按策略移除

          • 基于時間:TTL存活期、TTI空閑期

          • 基于Java對象引用:軟引用(適合做緩存,從而當(dāng)JVM堆內(nèi)存不足時也可以回收這些對象)、弱引用(相當(dāng)于軟引用,更短的生命周期)

          • 回收算法:FIFO先進先出、LRU最少使用、LFU最不常用

          堆緩存(Gauva Cache, Ehcache 3.x)、堆外緩存(Ehcache 3.x, MapDB 3.X)、磁盤緩存(Ehcache 3.x, MapDB 3.X)、分布式緩存(Redis, Ehcache 3.x + Terracotta server)、多級緩存

          緩存使用模板

          • 三個名詞:

            • SoR:記錄系統(tǒng),或者叫數(shù)據(jù)源

            • Cache:緩存,是SoR的快照數(shù)據(jù)

            • 回源:即回到數(shù)據(jù)源頭獲取數(shù)據(jù)

          • Cache-Aside:即業(yè)務(wù)代碼圍繞Cache寫,是由業(yè)務(wù)代碼直接維護緩存。適合用AOP模式去實現(xiàn)。

          • Cache-As-SoR:即把Cache看做SoR, 所有操作都是對Cache進行,然后Cache再委托給SoR進行真實的讀/寫。即代碼中只能看到Cache的操作,看不到關(guān)于SoR相關(guān)的代碼。- Read-Through:業(yè)務(wù)代碼首先調(diào)用Cache,如果Cache不命中,由Cache回源到SoR,而不是業(yè)務(wù)代碼。使用Read-Through模式,需要配置一個CacheLoader組件用來回源到SoR加載數(shù)據(jù) - Write-Through:被稱為穿透寫/直寫模式 ———— 業(yè)務(wù)代碼首先調(diào)用Cache寫數(shù)據(jù),然后由Cache負責(zé)寫緩存和寫SoR,而不是業(yè)務(wù)代碼。需要配置一個CacheLoaderWriter - Write-Behind:稱之為回寫模式,不同于Write-Through是同步寫SoR與Cache,Write-Behind是異步寫。異步之后可以實現(xiàn)批量寫、合并寫、延時和限流

          • Copy Pattern

            • Copy-On-Read在讀時復(fù)制

            • Copy-On-Write在寫時復(fù)制

          HTTP緩存

          HTTP緩存:

          1. 服務(wù)器端響應(yīng)Last-Modified會在下次請求時,將If-Modified-Since請求頭帶到服務(wù)器端進行文檔是否修改的驗證,如果沒有修改則返回304,瀏覽器可以直接使用緩存內(nèi)容

          2. Cache-Control:max-age和Expires用于決定瀏覽器端內(nèi)容緩存多久,即多久過期。過期后則刪除緩存重新從服務(wù)器端獲取最新的。另外可以用于from cache 場景

          3. HTTP/1.1規(guī)范定義的Cache-Control優(yōu)先級高于HTTP/1.0定義的Expires

          4. HTTP/1.1規(guī)范定義ETag為“被請求變量的實體值”,可簡單理解為文檔內(nèi)容摘要,ETag可用來判斷頁面內(nèi)容是否已經(jīng)被修改過了

          HttpClient客戶端緩存:

          • maxCacheEntries

          • maxObjectSize

          • asynchronousWorkersCore/asynchronousWorkersMax/revalidationQueueSize

          Nginx HTTP緩存設(shè)置:

          • expires

          • if-modified-since

          • nginx proxy_pass

          • Nginx代理層緩存:

            • HTTP模塊配置

            • proxy_cache配置

          多級緩存

          應(yīng)用Nginx本地緩存、分布式緩存、Tomcat堆緩存

          如何緩存數(shù)據(jù):

          • 過期與不過期:

            • 不過期緩存場景一般思路Cache-Aside模式,1.開啟事務(wù) 2.執(zhí)行SQL 3.提交事務(wù) 4.寫緩存

            • 過期緩存機制,如懶加載,一般用于緩存其他系統(tǒng)的數(shù)據(jù)、緩存空間有限、低頻熱點緩存等場景

          • 維度化緩存與增量緩存:只更新變的部分

          • 大Value緩存:多線程實現(xiàn)緩存、對Value壓縮、拆分Value為多個小Value

          • 熱點緩存:掛更多的從緩存,通過負載均衡機制讀取;客戶端所在應(yīng)用/代理層本地存儲一份

            • 單機全量緩存+主從

            • 分布式緩存+應(yīng)用本地緩存

          更新緩存與原子性:

          • 更新數(shù)據(jù)時使用更新時間戳或版本對比,如果使用Redis,則可以使用其單線程機制進行原子化更新

          • 使用如canal訂閱數(shù)據(jù)庫binlog

          • 將更新請求按照相應(yīng)的規(guī)則分散到多個隊列,然后每個隊列進行單線程更新,更新時拉取最新的數(shù)據(jù)保存

          • 用分布式鎖,在更新之前獲取相關(guān)的鎖

          連接池/線程池

          • 數(shù)據(jù)庫連接池:C3P0、DBCP、Druid等

          • HttpClient連接池

          • 線程池:

            • ThreadPoolExecutor:標(biāo)準(zhǔn)線程池

            • ScheduledThreadPoolExecutor:支持延遲任務(wù)的線程池

            • ForkJoinPool:類似于ThreadPoolExecutor,但使用work-stealing模式,會為線程池中每個線程創(chuàng)建一個隊列,從而用work-stealing(任務(wù)竊取)算法使得線程可以從其他線程隊列里竊取任務(wù)來執(zhí)行。

            • 提供ExecutorService三種實現(xiàn):

            • Executors創(chuàng)建簡單線程池

            • 根據(jù)任務(wù)列型是IO密集型還是CPU密集型、CPU核數(shù),來設(shè)置合理的線程池大小、隊列大小、拒絕策略,并進行壓測和不斷調(diào)優(yōu)來決定適合自己場景的參數(shù)

          • Tomcat線程池

          異步并發(fā)

          異步Web服務(wù)實現(xiàn):

          如何擴容

          隊列

          案例

          OpenResty

          souce: https://zhouj000.github.io/2018/06/25/coreTechnologyOfWebArchitecture-kaitao/

          喜歡,在看



          瀏覽 67
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  啪啪网站在线观看 | 午夜电影无码 | 人人操人人模 | 无码一区二区三区四区精 | 苍井空在线视频一区二区三区 |