官术网_书友最值得收藏!

2.2 互聯(lián)網(wǎng)架構(gòu)的典型模式

2.2.1 分層

分層就是AKF擴展立方體中的水平擴展,將系統(tǒng)按水平方向分為多個層次,每層在應用中有專門的角色,各層之間相對獨立,以更松散的方式協(xié)同發(fā)揮作用。

分層架構(gòu)可以應用于一個子系統(tǒng)內(nèi)部,也可以應用于子系統(tǒng)之間。例如在一個子系統(tǒng)內(nèi)部,將一個應用分為MVC結(jié)構(gòu),即模型、視圖和控制器。在一個互聯(lián)網(wǎng)架構(gòu)中可以分為前端展現(xiàn)層、網(wǎng)關(guān)接入層、服務處理層、數(shù)據(jù)緩沖層、數(shù)據(jù)持久層等。

分層要求功能內(nèi)聚、邏輯清楚、邊界清晰,理想的層次是可替代、可插拔的。各層之間也是有序的,需要按約定的層次順序傳遞信息,避免跨層次調(diào)用以及反向調(diào)用。

分層降低了各層的依賴關(guān)系,功能更加內(nèi)聚,應用更加標準化,有利于功能復用,也有利于各層獨立維護、獨立擴展。系統(tǒng)規(guī)模越大優(yōu)勢越明顯。但從某一個具體調(diào)用過程看,分層結(jié)構(gòu)增加了服務調(diào)用消耗,降低了性能。同時分層導致了級聯(lián)修改,增加了系統(tǒng)復雜度,增加了開發(fā)維護成本。

分層思想尤其適用于對軟件整體結(jié)構(gòu)的梳理,通過水平拆分可以構(gòu)建出子系統(tǒng)的層次關(guān)系,形成系統(tǒng)整體架構(gòu)。一個較完整的大型企業(yè)互聯(lián)網(wǎng)架構(gòu)總體藍圖如圖2-1所示。

圖2-1 分布式系統(tǒng)分層模式實例

■ 企業(yè)業(yè)務架構(gòu)的基礎(chǔ)是搭建在企業(yè)數(shù)據(jù)中心或公有云基礎(chǔ)上的企業(yè)IT基礎(chǔ)設(shè)施,提供IaaS服務。基于歷史IT資產(chǎn)投資利用以及數(shù)據(jù)保密的需要,大型企業(yè)仍然側(cè)重于建設(shè)企業(yè)專有云,同時在部分領(lǐng)域使用公有云的能力,是一個混合云的架構(gòu)。而小微企業(yè)傾向于全部使用公有云。

■ 第二層是容器及基于容器的資源調(diào)度平臺。2014年1月Docker 1.0版本正式發(fā)布,2014年秋亞馬遜正式推出了彈性容器服務。Docker生態(tài)發(fā)展迅猛,目前已經(jīng)成為企業(yè)架構(gòu)的標準部件與核心基礎(chǔ)。

■ 第三層是企業(yè)基礎(chǔ)中間件服務層,通過整合成熟的中間件,并對部分中間件容器化,為企業(yè)提供基礎(chǔ)中間件服務能力。

■ 第四層是企業(yè)服務平臺,利用成熟的開源框架,搭建提供面向服務的系統(tǒng)架構(gòu),是企業(yè)交易的核心。

■ 第五層是企業(yè)自主搭建的技術(shù)體系,包括企業(yè)自研基礎(chǔ)技術(shù)體系、企業(yè)自有DevOps平臺、企業(yè)自有大數(shù)據(jù)服務平臺,它們與第三層和第四層共同組成了企業(yè)的PaaS服務平臺。

■ 第六層是企業(yè)將自研的典型業(yè)務系統(tǒng)封裝,提供標準服務的SaaS平臺。

■ 最頂層是企業(yè)定制化的業(yè)務系統(tǒng)。

2.2.2 分割

分割就是垂直擴展,是按照業(yè)務方向?qū)⒁粋€系統(tǒng)進行功能劃分。分層更多關(guān)注的是技術(shù)層面,而分割更多關(guān)注的是業(yè)務層面。如一個零售系統(tǒng)可以分為用戶服務、支付服務、訂單服務、商品服務等。

分割服務時,需要根據(jù)業(yè)務的復雜程度選擇分割的粒度。比如大型電商平臺用戶查看商品信息的頻次與其他業(yè)務相比調(diào)用頻率更高,此時可以將商品服務繼續(xù)細化,拆分為商品搜索服務、商品詳情服務。分割后,分析每個服務各自的業(yè)務場景,總結(jié)各自的技術(shù)進化路線。系統(tǒng)的切割不見得是一蹴而就、一次到底的,需要根據(jù)業(yè)務情況,逐漸進化。

通過將系統(tǒng)按功能分割,有利于分工協(xié)作,降低開發(fā)和部署過程中的沖突、合并等干擾,優(yōu)化團隊效率,也有利于隔離不同業(yè)務間的影響,按分割后的服務單獨定制優(yōu)化路線。但分割也帶來了系統(tǒng)的復雜性,需要對調(diào)用關(guān)系進行治理,需要引入Microservice、Servicemesh等服務治理框架。

在總體分層架構(gòu)的基礎(chǔ)上應用分割的辦法,可以形成企業(yè)的總體架構(gòu)圖,圖2-2是一個零售行業(yè)的整體架構(gòu)圖,展示了分割模式。

圖2-2 分布式系統(tǒng)分割模式實例

■ 在基礎(chǔ)中間件部分,搭建Redis集群、MySQL集群等中間件高可用架構(gòu)。

■ 在企業(yè)服務平臺部分,搭建微服務或服務網(wǎng)格的核心架構(gòu)。

■ 在基礎(chǔ)技術(shù)平臺部分,搭建單點登錄、計劃任務調(diào)度、監(jiān)控系統(tǒng)等系統(tǒng),在DevOps部分搭建Jenkins、自動化測試、代碼分析、bug管理等系統(tǒng),在大數(shù)據(jù)部分搭建ES、用戶畫像、推薦系統(tǒng)、風控系統(tǒng)等系統(tǒng)。

■ 在基礎(chǔ)業(yè)務服務部分提供會員、支付、驗證碼、營銷、訂單、評論等基礎(chǔ)業(yè)務服務。

2.2.3 分片

分片對應于擴展立方體的Z軸擴展,是將數(shù)據(jù)分配到不同的節(jié)點上進行分片存儲和計算。業(yè)務處理可以通過分層和分割解決擴展問題,傳統(tǒng)關(guān)系型數(shù)據(jù)庫就變成了下一個瓶頸。解決方法為提升硬件處理能力,或采用傳統(tǒng)的關(guān)系型數(shù)據(jù)庫提供的集群處理方案,如MySQL cluster,Oracle Rac等。這些集群處理方案都存在局限,隨節(jié)點數(shù)增加,總體性能提高,但單機性能下降,無法支持無限擴展,面對互聯(lián)網(wǎng)海量數(shù)據(jù)依然力有不逮。

為了解決傳統(tǒng)關(guān)系型數(shù)據(jù)庫的問題,產(chǎn)生了NoSQL數(shù)據(jù)庫,包括鍵值(key-value)存儲數(shù)據(jù)庫,典型代表如Redis;列存儲數(shù)據(jù)庫,典型代表如HBase;文檔型數(shù)據(jù)庫,典型代表如MongoDB;倒排索引數(shù)據(jù)庫,典型代表如ES;圖結(jié)構(gòu)數(shù)據(jù)庫,典型代表如Neo4j等。NoSQL數(shù)據(jù)庫是為大數(shù)據(jù)而生,結(jié)構(gòu)上天然支持數(shù)據(jù)分片擴展,如Redis cluster的slot,ES的shard index都是典型的分片結(jié)構(gòu)。

NoSQL數(shù)據(jù)庫是關(guān)系型數(shù)據(jù)庫的有效補充,但滿足ACID的關(guān)系型數(shù)據(jù)庫依然是系統(tǒng)架構(gòu)中必不可少的,為了解決關(guān)系型數(shù)據(jù)庫的擴展問題,可以采用分庫分表的辦法。分庫是指將原本在一個數(shù)據(jù)庫中的數(shù)據(jù),重新按業(yè)務歸類分布到不同的數(shù)據(jù)庫中,從而將壓力分散至不同的數(shù)據(jù)庫。比如將單一的零售系統(tǒng)的數(shù)據(jù)庫,拆分為用戶庫、商品庫、訂單庫等。分表是指將原本在一個數(shù)據(jù)表中的數(shù)據(jù),重新歸類分布到不同數(shù)據(jù)表中。分表無法緩解數(shù)據(jù)庫壓力,但有利于突破單表的數(shù)據(jù)存儲和查詢性能瓶頸,如將用戶數(shù)據(jù)表按用戶ID拆分成N張表,可以解決海量用戶的查詢問題。采用分表不分庫的辦法,可以避免分布式事務。

對數(shù)據(jù)庫分庫分表的同時配合使用多主多從的分片方式,可以有效避免數(shù)據(jù)單點,提升數(shù)據(jù)架構(gòu)的可用性。分庫分表一般需要配合系統(tǒng)分割,與服務的劃分相對應。

分庫分表提升了整體數(shù)據(jù)處理能力,但也帶來了數(shù)據(jù)路由、數(shù)據(jù)聚合、分布式事務等問題。一般需要采用ShardingSphere、mycat等中間件屏蔽數(shù)據(jù)分片帶來的復雜性。

在典型的應用場景中,對數(shù)據(jù)ACID要求高的繼續(xù)使用關(guān)系型數(shù)據(jù)庫,并進行分庫分表處理,同時結(jié)合NoSQL數(shù)據(jù)庫,發(fā)揮NoSQL數(shù)據(jù)庫的特長。例如,針對海量數(shù)據(jù),可以先在MySQL上進行分庫/分表,然后通過ShardingSphere分庫分表中間件完成數(shù)據(jù)CRUD管理,最后將數(shù)據(jù)同步到Redis和HBase中,在Redis中進行數(shù)據(jù)熱點緩存,在HBase中進行大表存儲,當查詢時可以使用Redis或HBase進行查詢,避免對關(guān)系型數(shù)據(jù)庫分片數(shù)據(jù)的Join查詢。

針對海量圖片和視頻文件的存儲處理,一般可以使用Fastdfs等分布式文件存儲系統(tǒng)或OSS分布式對象存儲系統(tǒng)來進行管理。

2.2.4 緩存

緩存是將數(shù)據(jù)放在距離使用者最近的位置的一種方式,通過緩存可以減少系統(tǒng)交互,降低系統(tǒng)I/O。緩存的主要方式包括CDN緩存、前端緩存(瀏覽器緩存、App緩存)、反向代理緩存、應用端緩存、分布式緩存。

(1)CDN緩存,CDN(內(nèi)容分發(fā)網(wǎng)絡(luò),Content Delivery Network)是由分布在不同地理區(qū)域的節(jié)點組成的分布式網(wǎng)絡(luò),可以將源站內(nèi)容分發(fā)至最接近用戶的節(jié)點,當分布在各地的用戶請求訪問和獲取網(wǎng)站內(nèi)容時,無需訪問主站,系統(tǒng)自動調(diào)用離終端用戶最近的CDN節(jié)點上已緩存的資源。CDN可以分擔源站壓力,避免網(wǎng)絡(luò)擁塞,提高資源訪問速度和成功率。

(2)前端緩存,前端緩存是指在用戶側(cè)的緩存策略,包括用戶側(cè)的瀏覽器緩存和App客戶端緩存等。瀏覽器緩存,在瀏覽器首次向服務器發(fā)起該請求后,會根據(jù)響應報文中HTTP頭中設(shè)置的緩存策略,決定是否緩存應答結(jié)果,是則將應答結(jié)果和緩存策略存入瀏覽器緩存中,后續(xù)的請求會根據(jù)緩存策略判斷是否將請求發(fā)送到服務器端。App客戶端緩存,是指利用移動設(shè)備的內(nèi)存、文件系統(tǒng)或嵌入式數(shù)據(jù)庫等方式緩存數(shù)據(jù)。

(3)反向代理緩存,反向代理服務器部署在網(wǎng)站應用的最前端,在2.2.7節(jié)中描述了反向代理靜態(tài)資源緩存的辦法。

(4)應用緩存,是指將數(shù)據(jù)存儲在應用系統(tǒng)本地線程堆棧中,Java語言可存儲在Map、Set、List等集合類型數(shù)據(jù)結(jié)構(gòu)中,也可以使用Guava cache或者EHcache等第三方提供的類庫。

(5)分布式緩存,是指在業(yè)務系統(tǒng)進程外單獨部署的高可用、可擴展的緩存系統(tǒng),如Memcached、Redis等。

2.2.5 并行

串行是指多個任務依次執(zhí)行,同一時間內(nèi)只有一個任務在執(zhí)行。并行是指在系統(tǒng)中同時執(zhí)行兩個或多個任務。圖2-3是一個下單操作的串行處理流程和并行處理流程。與串行相比,并行能充分利用硬件處理能力,大幅提升效率。

并行主要應用于數(shù)據(jù)處理與任務處理。

(1)并行數(shù)據(jù)處理:并行往往與數(shù)據(jù)分片結(jié)合,通過多個進程或線程對不同的分片數(shù)據(jù)進行并發(fā)處理。MapReduce就是一種針對數(shù)據(jù)分片的并行處理架構(gòu)。

(2)并行任務執(zhí)行:并行還可應用于同時執(zhí)行多個無依賴關(guān)系的服務調(diào)用,先并發(fā)執(zhí)行再統(tǒng)一處理結(jié)果。區(qū)分串行與并行場景,靈活應用并發(fā)模式可以大幅提升系統(tǒng)處理能力。

圖2-3 串行與并行

2.2.6 異步

同步是指當發(fā)出一個功能調(diào)用時,在沒有得到結(jié)果之前,阻塞線程,該調(diào)用不返回。異步的概念和同步相對,當一個過程調(diào)用發(fā)出后,調(diào)用者不能立刻得到結(jié)果,可以繼續(xù)處理其他工作,實際處理調(diào)用的部件在處理完成后,通過狀態(tài)、通知和回調(diào)來通知調(diào)用者。

異步調(diào)用極大地提高了系統(tǒng)的吞吐能力。例如,在瀏覽器端,同步調(diào)用在得到返回結(jié)果前,瀏覽器不能做其他任何事情,而使用AJAX異步請求則實現(xiàn)了瀏覽器的局部刷新,極大地提升了用戶體驗。

(1)異步線程:Java中通過CompletableFuture實現(xiàn)了對異步調(diào)用的編排,通過thenAccept、thenApply、thenCompose等方式可以將前面異步處理的結(jié)果交給另外一個事件處理線程來異步處理。一般情況下,在一個成熟的體系架構(gòu)中已經(jīng)封裝了請求調(diào)用的模型,如Dubbo中提供了消費者和服務者的異步調(diào)用方法。應該盡量使用框架中的異步模型,避免另起爐灶。

(2)消息隊列:消息的生產(chǎn)者將消息發(fā)送到消息隊列以后,由消息的消費者從消息隊列中獲取消息,然后進行業(yè)務邏輯的處理,消息的生產(chǎn)者和消費者是異步處理的,彼此不會等待阻塞。消息隊列可以使消息生產(chǎn)者和消費者解耦,隔離失敗,使消費者具有更好的伸縮性。消息隊列還可以起到削峰填谷的作用,將請求的信息納入到消息隊列中,緩存消費者的處理速度。常用的消息隊列包括:RabbitMQ、ActiveMQ、RocketMQ、Kafka等。

(3)Servlet 3.0:Servlet在3.0之前,采用Thread-Per-Request的方式處理請求,每一次HTTP請求由一個線程負責處理,而處理線程往往要執(zhí)行訪問數(shù)據(jù)庫等操作,處理操作是非常慢的,線程并不能及時地釋放回線程池以供后續(xù)使用,吞吐受到極大限制。在Servlet 3.0以后引入了異步處理,在HttpServletRequest對象中可以獲得一個AsyncContext對象,該對象構(gòu)成了異步處理的上下文,Request和Response對象都可從中獲取。AsyncContext可以從當前線程傳給另外的線程,并在新的線程中完成對請求的處理并返回結(jié)果給客戶端,初始線程可以還給容器線程池以處理更多的請求。

2.2.7 隔離

隔離是指將不同的資源加以區(qū)分進行隔離控制。通過資源隔離可以限定問題傳播范圍,避免雪崩效應,同時隔離可以為不同場景的資源劃分泳道,避免互相堵塞,互相影響。隔離的應用方式很多,下面列出常見的隔離方式。

(1)服務隔離,在面向服務的架構(gòu)體系中,對服務進行隔離控制,避免一個服務出現(xiàn)問題引起系統(tǒng)雪崩,導致系統(tǒng)被流量沖垮,保障應用高可用性。主要措施包括限流、熔斷、降級。限流:監(jiān)控應用流量的QPS或并發(fā)線程數(shù)等指標,當達到指定閾值時對流量進行控制。熔斷:在調(diào)用鏈路中某個資源出現(xiàn)不穩(wěn)定狀態(tài)時(例如調(diào)用超時或異常比例升高),對這個資源的調(diào)用進行限制,讓請求快速失敗,防止請求發(fā)生堆積。降級:在服務器壓力劇增的情況下,根據(jù)實際業(yè)務情況及流量,對一些服務和頁面有策略地不處理或換種簡單的方式處理,從而釋放服務器資源以保證核心事務正常運作或高效運作。如庫存系統(tǒng)宕機時,為保證售賣,可以暫時使庫存調(diào)用返回有庫存。

(2)線程隔離,是指在同一進程內(nèi)根據(jù)業(yè)務情況,分別設(shè)置不同的線程池進行隔離,每個線程池單獨配置,如圖2-4所示。如Tomcat、Dubbo都可以根據(jù)業(yè)務場景完成線程隔離。

圖2-4 線程隔離

(3)進程隔離,是指在將單個系統(tǒng)拆分為多個子系統(tǒng)后,對子系統(tǒng)以及子系統(tǒng)依賴的關(guān)聯(lián)資源同時進行隔離。如在電商秒殺場景中,因為秒殺的業(yè)務抖動較大,為保護其他業(yè)務,需要將秒殺場景相關(guān)的系統(tǒng)進程、緩存、DB等資源獨立。又如AB測試場景,需要隔離出兩套環(huán)境,用不同的流量進行測試。

(4)動靜分離,靜態(tài)頁面是指網(wǎng)站頁面中幾乎不變的頁面(或者變化頻率很低),例如靜態(tài)html頁面、js/css等樣式文件,只需要CDN、Nginx、Squid/Varnish等中間件就可以處理。動態(tài)頁面是指基于不同用戶不同場景訪問,服務端動態(tài)渲染生成的不一樣的頁面,例如JSP、PHP等文件,需要部署到Tomcat、Weblogic等容器上。

靜態(tài)頁面只需要在服務器上存儲,無需再進行計算處理,訪問路徑短,訪問速度快,并發(fā)能力強。而動態(tài)頁面訪問路徑長,訪問速度相對較慢(數(shù)據(jù)庫的訪問,網(wǎng)絡(luò)傳輸,業(yè)務邏輯計算),擴展不易。因此可以將兩者不同特征的頁面分開部署,如圖2-5所示,實現(xiàn)動靜分離。將靜態(tài)頁面與動態(tài)頁面以不同域名區(qū)分,同時將靜態(tài)文件在架構(gòu)上盡量前置部署,例如將靜態(tài)資源部署到CDN、Nginx上,充分利用服務器距離用戶物理位置近、反向代理中間件并發(fā)處理能力強的特點,提升靜態(tài)資源的加載速度,減輕服務器的壓力。

圖2-5 動靜分離

針對動態(tài)文件,可以采用動態(tài)頁面靜態(tài)化的辦法,將原本需要動態(tài)生成的站點提前生成好,使用靜態(tài)頁面加速技術(shù)來訪問。此種辦法適用總數(shù)據(jù)量不大,生成靜態(tài)頁面數(shù)量不多但需要頻繁訪問的業(yè)務,在技術(shù)上可以使用Apache的mod_rewrite以及Nginx的rewrite等功能實現(xiàn),也可以自己模擬HttpClient調(diào)用服務請求返回靜態(tài)內(nèi)容生成靜態(tài)文件。

(5)前后端分離,在早期的開發(fā)架構(gòu)中,前后端一體,組織結(jié)構(gòu)中不區(qū)分前后端,開發(fā)人員在寫業(yè)務邏輯的同時也需要編寫JSP處理展示邏輯,JSP中含有html、css、js以及控制展示的服務端代碼或標簽。隨著AJAX的出現(xiàn),出現(xiàn)了前后端分離的架構(gòu),其核心是前端面向接口編程,前端頁面使用Ajax調(diào)用后端的接口,接口返回JSON后,前端控制JSON數(shù)據(jù)的展示方式,在部署上前后端要分開獨立部署。從組織結(jié)構(gòu)上分為前端工程師和后端工程師,前端工程師需要掌握html、css、js等技能,后端工程師需要掌握Java等后端技術(shù)棧。

(6)讀寫分離,是指讓主數(shù)據(jù)庫處理事務性增、改、刪操作,而從數(shù)據(jù)庫處理查詢操作。通過數(shù)據(jù)庫復制把事務性操作導致的變更同步到從數(shù)據(jù)庫。通過讀寫分離可以減少主庫壓力,尤其適用于寫少讀多的場景。在數(shù)據(jù)庫層面利用數(shù)據(jù)庫自身提供的主從復制功能,或者其他binlog復制工具實現(xiàn)主從同步以及只讀庫的復制擴展。在客戶端可以使用MyCat、ShardingSphere等中間件配置讀寫路由邏輯,避免代碼侵入。

(7)在線與離線分離,將實時任務與非實時任務進行分割。

在線任務一般是指用戶對時間敏感,希望每次操作都能在極短的時間內(nèi)看到結(jié)果的操作,如下單購買等用戶操作。一般情況下,系統(tǒng)反應時間小于2s用戶體驗最好;2~8s,用戶可以忍受;大于8s,用戶將流失。離線任務一般數(shù)據(jù)量大,用戶對時間不敏感。常見的離線任務場景包括積分計算、日志處理、BI分析等。如用戶進行消費產(chǎn)生的積分并不需要立刻看到,可以延遲幾分鐘甚至可以在第二天再看到。在實現(xiàn)中一般通過定時周期性執(zhí)行一個Job任務,定期執(zhí)行離線任務,數(shù)據(jù)經(jīng)過抽取、清洗、計算等過程進行加工處理。在技術(shù)上綜合使用Job,Kettle、Spring Bach、消息隊列、MapReduce、Spark等技術(shù)。

在設(shè)計系統(tǒng)時,需要區(qū)分用戶場景,適時將離線任務從在線任務中抽取出來,采用離線任務對應的架構(gòu)設(shè)計方法。離線任務的架構(gòu)設(shè)計主要包括:全量與增量、推送還是拉取、流式計算還是批量計算。

全量與增量是指將全量數(shù)據(jù)通過數(shù)據(jù)預處理提前完成計算,再通過時間戳、數(shù)據(jù)狀態(tài)等字段標識出新產(chǎn)生或發(fā)生變化的數(shù)據(jù),每次工作任務只處理此部分數(shù)據(jù),將數(shù)據(jù)處理的范圍控制在最小。

推送與拉取是指數(shù)據(jù)由生產(chǎn)者推送給數(shù)據(jù)消費者,還是消費者從生產(chǎn)者產(chǎn)生的數(shù)據(jù)中進行抽取。比如日志分析一般采取拉取系統(tǒng)日志的辦法,拉取的方式對原系統(tǒng)侵入較小。而積分計算,可以通過在應用系統(tǒng)中埋點推送到消息隊列中。推送的方式比較容易理解,處理容易。

流式與批量:在流式計算中輸入是持續(xù)的,在時間上是無界的,即沒有固定的時間周期,計算結(jié)果是持續(xù)輸出的。流式計算的典型是ES日志分析,業(yè)務系統(tǒng)產(chǎn)生日志后,ES拉取日志到索引服務器,服務器依次將每一條日志插入倒排索引庫。批量計算,一般先有一部分數(shù)據(jù)集,然后針對數(shù)據(jù)集進行計算,并將結(jié)果一次性輸出。批量計算的典型場景是數(shù)據(jù)報表,比如要計算年報數(shù)據(jù),需先抽取各類業(yè)務數(shù)據(jù)到寬表,然后對寬表數(shù)據(jù)按日匯總,得出日報,進而加工成月報、年報。流式計算與批量計算的比較,如圖2-6所示。

圖2-6 流式計算與批量計算

(8)冷熱分離是指將熱點數(shù)據(jù)與不常用的業(yè)務和數(shù)據(jù)進行分離的辦法。進程隔離中提到的秒殺業(yè)務隔離其實也是一種熱點業(yè)務的分離,但一般情況下的冷熱分離是指冷熱數(shù)據(jù)的分離。用戶一般只會偶爾關(guān)注歷史數(shù)據(jù)(一個月以前已經(jīng)完結(jié)的訂單很少有用戶再去查看),而歷史數(shù)據(jù)會占據(jù)較多的資源,此時可按照時間維度將歷史數(shù)據(jù)歸檔,歸檔后節(jié)省下的資源用于熱數(shù)據(jù)的處理。歸檔可以是異構(gòu)的,數(shù)據(jù)可以存儲到不同類型的存儲中間件或存儲介質(zhì)中,在消費端可以單獨定制數(shù)據(jù)查詢服務,路由到歸檔數(shù)據(jù)庫中。需注意數(shù)據(jù)冷熱分離與冷備熱備在概念上的區(qū)別,在數(shù)據(jù)庫備份過程中,如果備份操作時數(shù)據(jù)庫不提供服務,此種方式就稱為冷備,反之稱為熱備。

(9)其他隔離方式:隔離方式還有很多種,不一而足,例如爬蟲分隔,即通過負載均衡等機制將網(wǎng)絡(luò)爬蟲與正常流量分隔。

2.2.8 容錯

在一個分布式系統(tǒng)中,從時間維度和容量維度看,故障是不可避免的。容錯的目的就是在一個分布式系統(tǒng)中,當系統(tǒng)運行時,即使有錯誤發(fā)生仍能保證不間斷提供服務。容錯的主要思路是設(shè)計備用方案,在組件發(fā)生故障時通過備份方案代替故障組件發(fā)揮作用。

(1)硬件環(huán)境容錯,各服務器廠家都生產(chǎn)有相應的高可靠服務器,解決思路是服務器內(nèi)提供雙份硬件,如雙路電源、內(nèi)存等。在IDC機房中一般通過多路網(wǎng)絡(luò)、多路供電措施、同時備用UPS設(shè)備、柴油發(fā)電設(shè)備等綜合措施保障機房的可靠性。

(2)應用集群容錯,應用集群將無狀態(tài)的服務或系統(tǒng)應用鏡像后,在多個服務器上進行部署,客戶端通過負載均衡算法訪問服務,若其中一個服務發(fā)生問題,自動將此服務排除在集群外,其他服務繼續(xù)發(fā)揮作用。

(3)數(shù)據(jù)集群容錯,是指關(guān)系型數(shù)據(jù)庫或NoSQL數(shù)據(jù)庫通過共享存儲或者主主復制、主從復制方式實現(xiàn)集群。主主復制,是雙主庫都可以進行寫操作,數(shù)據(jù)變更通過復制的方式傳遞給另一個庫,當一個主庫發(fā)生錯誤時,另一個主庫立即接管發(fā)揮作用。主從復制,是從庫從主庫復制數(shù)據(jù),從庫平時只能讀不能寫,當主庫發(fā)生錯誤時從庫升級為主庫發(fā)揮作用。

(4)容災備份,通過整套環(huán)境的備份,起到災難后立刻接管的作用,包括多機房部署,同城災備、異地災備等形式。多機房部署是在同一數(shù)據(jù)中心的多個分區(qū)部署相同的分布式系統(tǒng),保證相同的應用或者數(shù)據(jù)庫,數(shù)據(jù)庫通過數(shù)據(jù)傳輸軟件進行同步。同城災備是分布式系統(tǒng)在一個城市的不同數(shù)據(jù)中心部署。異地災備是將分布式系統(tǒng)部署在不同的地域。

(5)服務容錯,在分布式系統(tǒng)面向API的編程中,需考慮超時、重試、混序等異常現(xiàn)象,保證服務冪等,即任意多次客戶操作或服務調(diào)用所產(chǎn)生的影響均與一次執(zhí)行的影響相同。典型的異常場景包括:因網(wǎng)絡(luò)重發(fā)或系統(tǒng)bug重發(fā)收到的多次付款請求;前端頁面的重復提交;創(chuàng)建訂單時網(wǎng)絡(luò)超時;等待支付回調(diào)結(jié)果時,收到退款請求等情況。解決的辦法如下。

1)冪等提交,采用會話token校驗機制。在生成表單頁面時,服務器會先生成一個token保存于session,并把該token傳給表單頁面,用于后續(xù)校驗。當表單提交時會帶上token,服務器端判斷session保存的token和表單提交subtoken是否一致,若不一致或session的token為空或表單未攜帶token則不通過。首次提交表單時session的token與表單攜帶的token一致,則判斷通過,并刪除session保存的subtoken。當再次提交表單時,由于session的token為空則不通過。從而實現(xiàn)了防止表單重復提交。

2)狀態(tài)機冪等,采用樂觀鎖的機制,通過唯一索引+版本號進行更新,保證狀態(tài)正確。涉及狀態(tài)機(狀態(tài)變更圖)相關(guān)的業(yè)務,需要設(shè)置狀態(tài)字段,如果狀態(tài)機已經(jīng)處于下一個狀態(tài),這時來了一個上一個狀態(tài)的變更,就需要采用樂觀鎖的機制,通過唯一索引+狀態(tài)字段進行更新,使不符合狀態(tài)機要求的操作不能成功,保證了有限狀態(tài)機的冪等。

3)流水冪等,在數(shù)據(jù)庫層建立正確的唯一索引,通過唯一索引保證數(shù)據(jù)冪等。對于服務調(diào)用,需要在調(diào)用接口中增加交易流水號字段(唯一索引),一般通過將消費者渠道來源編碼與序列號組裝成交易流水號(source+seq),交易時根據(jù)交易流水號進行判斷,調(diào)用此交易流水是否已經(jīng)處理過,如果處理過則直接返回結(jié)果。

(6)超時重試,針對超時未返回結(jié)果的業(yè)務,一般要進行重試處理,多次重試后仍無結(jié)果的,可以通過交易補償或異步消息等方式保證最終一致。如支付業(yè)務,在最終未收到支付回調(diào),或支付回調(diào)處理失敗時,可以按照對賬文件進行補賬,這也是交易補償?shù)囊环N方式。

2.2.9 安全

互聯(lián)網(wǎng)天然的開放性對系統(tǒng)安全提出了巨大的挑戰(zhàn)。系統(tǒng)安全是一個綜合工程,涉及弱電施工、網(wǎng)絡(luò)拓撲、主機管理、軟件架構(gòu)等多個環(huán)節(jié),按領(lǐng)域可以分為管理安全、物理安全、主機安全、網(wǎng)絡(luò)安全、應用安全和數(shù)據(jù)安全幾類。圍繞安全的矛與盾的攻守是個長期過程,應定期進行全路徑的安全體檢,在軟件開發(fā)過程中應該定期進行代碼檢查和漏洞掃描。

(1)物理安全,物理安全是信息安全的前提,是保護機房設(shè)備、設(shè)施免遭地震、水災、火災或其他人為破壞的措施。

(2)主機安全,是指對主機的操作系統(tǒng)、訪問控制的安全保護。如操作系統(tǒng)安全升級等。

(3)網(wǎng)絡(luò)安全,是針對整個網(wǎng)絡(luò)拓撲結(jié)構(gòu)的安全保護。如防火墻保護、入侵檢測(IPS)等。

(4)應用安全,是指業(yè)務系統(tǒng)的安全保護,如用戶密碼加密、接口調(diào)用鑒權(quán)、XSS攻擊防范、SQL注入防范、垃圾與敏感信息過濾、App安全加固、短信轟炸保護等。

(5)數(shù)據(jù)安全,是指對圖片文件、數(shù)據(jù)庫數(shù)據(jù)、隊列消息等數(shù)據(jù)資產(chǎn)的鑒權(quán)訪問、數(shù)據(jù)加密、數(shù)據(jù)備份等保護措施。

(6)管理安全,是指與安全相關(guān)的組織結(jié)構(gòu)、管理制度等。

2.2.10 治理

在一個分布式系統(tǒng)中需要一個全局的治理結(jié)構(gòu),實現(xiàn)全局的監(jiān)控、調(diào)度、保護和異常處理,并統(tǒng)籌協(xié)調(diào)與大規(guī)模集群模式相適應的開發(fā)、測試與運維工作。

(1)系統(tǒng)監(jiān)控:在面向服務的分布式系統(tǒng)中除了傳統(tǒng)的對主機負載、I/O、內(nèi)存以及應用情況進行監(jiān)控外,還要關(guān)注系統(tǒng)調(diào)用鏈情況、服務穩(wěn)定相關(guān)的熔斷情況,在發(fā)現(xiàn)問題時自動報警。

(2)交易治理:在面向服務的架構(gòu)中,通過注冊中心、控制臺、網(wǎng)關(guān)等對服務地址、負載均衡策略進行管理,在應對高并發(fā)流量時,通過自動或手動方式進行限流、熔斷、降級或者進行擴展處理。

(3)DevOps:統(tǒng)籌協(xié)調(diào)開發(fā)、運維、測試的一體化整合,通過Docker、K8s,Jenkins等基礎(chǔ)設(shè)施集成其他工具實現(xiàn)測試、檢查、部署的持續(xù)集成。

主站蜘蛛池模板: 张掖市| 郎溪县| 鲜城| 准格尔旗| 巩留县| 调兵山市| 彭山县| 安徽省| 白朗县| 滨海县| 贵州省| 句容市| 敦化市| 漠河县| 阿坝| 定远县| 苏州市| 青神县| 裕民县| 新晃| 万全县| 肇源县| 济南市| 赤峰市| 云阳县| 称多县| 江津市| 娄烦县| 屯昌县| 房山区| 金阳县| 沙湾县| 丘北县| 武鸣县| 澳门| 广南县| 贵定县| 永城市| 城口县| 体育| 贵州省|