<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    I want to fly higher
    programming Explorer
    posts - 114,comments - 263,trackbacks - 0

    分布式系統(tǒng)的基礎(chǔ)知識

    • 阿姆達(dá)爾定律
    • 多線程交互模式
      • 互不通信,沒有交集,各自執(zhí)行各自的任務(wù)和邏輯
      • 基于共享容器(如隊列)協(xié)同的多線程模式->生產(chǎn)者-消費者->隊列
      • 通過事件協(xié)同的多線程模式->如B線程需要等到某個狀態(tài)或事件發(fā)生后才能繼續(xù)工作,而這個狀態(tài)改變或者事件產(chǎn)生和A線程相關(guān)
        • 避免死鎖
    • 網(wǎng)絡(luò)通信基礎(chǔ)知識
      • OSI、TCP/IP
      • 網(wǎng)絡(luò)IO實現(xiàn)方式
        • BIO
        • NIO->Reactor模式
        • AIO->Proactor模式
    負(fù)載均衡
    • 硬件負(fù)載均衡
    • LVS等軟件的負(fù)載均衡
    • 名稱服務(wù)
    • 規(guī)則服務(wù)器
    • Master-Worker
    小結(jié)
    1.一致性hash的算法思路(游戲服務(wù)器進程/線程設(shè)計思路)(擴容/縮容平滑)/環(huán)形消息隊列disruptor
    2.緩存服務(wù)器擴容或者縮容要盡量平滑
    3.消息中間件-MOM:Message-Oriented middleware,is software infrastructure focused on sending and receiving messages between distributed system.
    4.兩個常被提及的好處:異步和解耦.
    5.CountDownLatch不能循環(huán)使用,而CyclicBarrier可以循環(huán)使用(從名字上看,【循環(huán)_cyclic】屏障)
    

    大型網(wǎng)站及其架構(gòu)演進過程

    海量數(shù)據(jù)+高并發(fā)訪問量+復(fù)雜的業(yè)務(wù)和系統(tǒng)
    
    • 數(shù)據(jù)庫與應(yīng)用分離
    • 應(yīng)用服務(wù)器走向集群(引入負(fù)載均衡器)
    session問題
    • Session Sticky
    • Session Replication
    • Session數(shù)據(jù)集中存儲
    • Cookie Based
    讀寫分離
    • 引入讀庫->搜索引擎(站內(nèi)搜索功能)->Search Cluster
    • 專庫專用->數(shù)據(jù)垂直拆分
    • 數(shù)據(jù)水平拆分
    加快數(shù)據(jù)讀取
    • 緩存->頁面緩存->Cache Cluster
    分布式存儲系統(tǒng)
    • Distributed Storage
    拆分應(yīng)用
    • 走服務(wù)化的路
    消息中間件

    中間件

    特定中間件是解決特定場景問題的組件,它能夠讓軟件開發(fā)人員專注于自己應(yīng)用的開發(fā)
    
    • 遠(yuǎn)程過程調(diào)用和對象訪問中間件->解決分布式環(huán)境下應(yīng)用的互相訪問問題
    • 消息中間件:解決應(yīng)用之間的消息傳遞、解耦、異步的問題
    • 數(shù)據(jù)訪問中間件:解決應(yīng)用訪問數(shù)據(jù)庫的共性問題的組件
    構(gòu)建Java中間件的基礎(chǔ)知識
    • JVM/GC/內(nèi)存堆布局
    • 并發(fā)
      • 線程池/synchronized/ReentrantLock/volatile(可見性與操作互斥是兩件事情)/Atomics/wait、nofity、nofifyAll/CountDownLatch/
      • CyclicBarrier/Semaphore/Exchanger/Future、FutureTask/
      • 并發(fā)容器:CopyOnWrite、Concurrent
    • 動態(tài)代理
    • 反射
    • 網(wǎng)絡(luò)通信選擇
      • BIO/NIO/AIO
      • MINA、Netty
      • 協(xié)議制定
    中間件范疇
    • 應(yīng)用的拆分
    • 服務(wù)的拆分
    • 數(shù)據(jù)的拆分
    • 應(yīng)用的解耦

    服務(wù)框架

    運行期服務(wù)框架與應(yīng)用和容器的關(guān)系
    • 直接或者間接依賴的jar導(dǎo)致應(yīng)用里同一個jar包有不同的版本->產(chǎn)生沖突
    • 將服務(wù)框架自身用到的類和應(yīng)用用到的類都控制在User-Defined Class Loader級別->實現(xiàn)相互間隔離
    • web容器對于多個web應(yīng)用的處理以及osgi對于不同的bundle的處理都采用了類似的方法
    服務(wù)調(diào)用者與服務(wù)提供者之間通訊方式的選擇
    • 調(diào)用者[服務(wù)框架]
      • -->服務(wù)注冊查找中心
        • --->服務(wù)提供者[服務(wù)框架]
    • 并不是每次調(diào)用遠(yuǎn)程服務(wù)前都通過服務(wù)注冊查找中心來查找可用地址->而是把地址緩存在調(diào)用者本地->當(dāng)有變化時主動從服務(wù)注冊查找中心發(fā)起通知->告訴調(diào)用者可用的服務(wù)提供者列表的變化
      • 客戶端拿到可用的服務(wù)提供者的地址列表后->如何為當(dāng)次的調(diào)用進行選擇就是路由要解決的問題->隨機、輪訓(xùn)、權(quán)重(一般指動態(tài)權(quán)重)
    引入基于接口、方法、參數(shù)的路由
    • 因為一般情況下,一個集群會提供多個服務(wù),每個服務(wù)又有多個方法.->需要細(xì)粒度的控制服務(wù)路由
    • 如服務(wù)提供者有兩個服務(wù)-接口A和接口B->接口A中的某個方法1執(zhí)行比較耗時->影響整體性能->排隊
      • 隔離資源,使得快慢不同、重要級別不同的方法之間互不影響
    服務(wù)調(diào)用端的流控處理
    • 控制到服務(wù)提供者的請求的流量
    序列化與反序列化處理
    • 具體制定通信協(xié)議時->版本號、可擴展(擴展性、向后兼容性)屬性以及發(fā)起方支持能力的介紹(如是否支持壓縮等)
    網(wǎng)絡(luò)通信實現(xiàn)選擇
    • 同步方式進行遠(yuǎn)程調(diào)用使用nio
    • io線程/數(shù)據(jù)隊列/通信對象隊列/定時任務(wù)
      • 請求線程發(fā)送數(shù)據(jù)->進入數(shù)據(jù)隊列->生成通信對象(阻塞請求線程)->加入通信對象隊列->請求線程等待(通信對象用于喚醒請求線程)
      • 數(shù)據(jù)隊列->io線程->socket連接->進行數(shù)據(jù)收發(fā)(需要發(fā)送的數(shù)據(jù)進入數(shù)據(jù)隊列后,這樣請求線程就不需要直接和socket連接打交道->復(fù)用socket連接)
      • 如果遠(yuǎn)程調(diào)用超時前有執(zhí)行結(jié)果返回->io線程會通知通信對象->通信對象結(jié)束請求線程等待->結(jié)果傳送給請求線程
      • 定時任務(wù)用于負(fù)責(zé)檢查通信對象隊列中的哪些通信對象已經(jīng)超時->然后這些通信對象會通知請求線程已經(jīng)超時
    • 支持多種異步服務(wù)調(diào)用方式
      • OneWay->只管發(fā)送請求而不關(guān)心結(jié)果的方式->只需要把發(fā)送的數(shù)據(jù)放入數(shù)據(jù)隊列即可
      • CallBack->請求發(fā)送方發(fā)送請求后會繼續(xù)執(zhí)行自己的操作->等對方有響應(yīng)時進行一個回調(diào)
        • 請求方設(shè)置回調(diào)->加入回調(diào)對象隊列
        • 收到服務(wù)提供者的返回后->io線程會通知回調(diào)對象->執(zhí)行回調(diào)方法
        • 對于超時->定時任務(wù)的方式->如果沒有返回->也需要執(zhí)行回調(diào)對象的方法->告知已超時沒有結(jié)果
        • 如果不引入新的線程->那么回調(diào)的執(zhí)行要么是io線程中要么是在定時任務(wù)的線程中
        • [建議用新的線程執(zhí)行回調(diào)->不要因為回調(diào)本身的代碼執(zhí)行時間久等問題影響了io線程或者定時任務(wù)].
      • Future->請求線程通過future來獲取通信結(jié)果并直接控制超時->同上Future對象隊列 io線程依然是從數(shù)據(jù)隊列中得到數(shù)據(jù)再進行通信->得到結(jié)果后會把它傳給Future
      • 可靠異步->要保證異步請求能夠在遠(yuǎn)程被執(zhí)行->消息中間件來完成這個保證
      • 使用Future方式對遠(yuǎn)程服務(wù)調(diào)用的優(yōu)化
        • 一個請求中調(diào)用多個遠(yuǎn)程服務(wù)的情況
        • 按照調(diào)用順序把服務(wù)的請求發(fā)送給服務(wù)A,服務(wù)B,服務(wù)C->請求發(fā)送過去并不直接等待執(zhí)行結(jié)果
        • 而是直到服務(wù)C的請求也發(fā)出去后再來統(tǒng)一等待服務(wù)A、服務(wù)B和服務(wù)C的執(zhí)行結(jié)果->然后再接著進行本地的數(shù)據(jù)處理
        • 前提:所調(diào)用服務(wù)A、B、C之間并沒有相互的依賴關(guān)系
        • 即并行調(diào)用優(yōu)化->因為Future方式的支持
      • 反序列化線程:一般是使用io線程,不過這樣會影響io線程的工作效率;另一種方式是把反序列化工作從io線程轉(zhuǎn)移到其他線程去做
    服務(wù)提供端的設(shè)計與實現(xiàn)
    • 服務(wù)端的工作
      • 本地服務(wù)的注冊管理
      • 根據(jù)進來的請求定位服務(wù)并執(zhí)行
    • IO線程通信處理->反序列化的工作取決于具體實現(xiàn),io線程或者工作線程中進行的方式都有
      • 得到反序列化的消息并定位服務(wù)后->調(diào)用服務(wù)一般在非io線程進行(工作線程)
    • 執(zhí)行不同服務(wù)的線程池隔離
      • 服務(wù)提供端,工作線程池不止一個,而是多個,定位到服務(wù)后,根據(jù)服務(wù)名稱、方法、參數(shù)來確定具體執(zhí)行服務(wù)調(diào)用的是哪個線程池.->這樣,不同線程池之間是隔離的->不會出現(xiàn)爭奪線程資源的情況.
    • 整個服務(wù)框架的功能分為服務(wù)調(diào)用者和服務(wù)提供者兩方面,此外像序列化、協(xié)議、通信等是公用的功能.在具體實現(xiàn)上,是把這些功能都放在一起形成一個完成的服務(wù)框架->而不是分為服務(wù)調(diào)用者框架和服務(wù)提供者框架
    • 服務(wù)框架必須做到模塊化且可配置->模塊可替換->并留有一定的擴展點來擴展原有功能
    服務(wù)升級
    • 接口不變->內(nèi)部的服務(wù)實現(xiàn)有變化->比較簡單,采用灰度發(fā)布的方式驗證然后全部發(fā)布就可以了
    • 接口中增加方法->也比較簡單,直接增加方法即可->需要使用新方法的調(diào)用者就使用新方法,原來的調(diào)用者繼續(xù)使用原來的方法即可
    • 接口的某些方法修改調(diào)用的參數(shù)列表
      • 對使用原來方法的代碼都進行修改->不太可行->因為要求我們同時發(fā)布多個系統(tǒng)
      • 版本號解決->常用的方式->使用老方法的系統(tǒng)繼續(xù)調(diào)用原來版本的服務(wù),而需要使用新方法的系統(tǒng)則使用新版本的服務(wù)
      • 在設(shè)計方法上考慮參數(shù)的擴展性->可行,不太好->因參數(shù)列表可擴展一般就以為是采用類似map的方式來傳遞參數(shù)->不直觀,并且對參數(shù)的校驗會比較復(fù)雜
    實戰(zhàn)中的優(yōu)化
    • 服務(wù)的拆分
      • 要拆分的服務(wù)是需要為多方提供公共功能
    • 服務(wù)的粒度
      • 需要根據(jù)業(yè)務(wù)的實際情況來劃分服務(wù)
    • 優(yōu)雅和實用的平衡
      • 多調(diào)用一次就比之前多了一次網(wǎng)絡(luò)->一些功能直接在服務(wù)調(diào)用者的機器上實現(xiàn)會更加合適、經(jīng)濟
      • 如服務(wù)調(diào)用者直接讀緩存->大部分對數(shù)據(jù)的請求直接走一次緩存就可以,只有少部分沒有命中緩存的數(shù)據(jù)讀取需要走服務(wù)提供者->然后再到數(shù)據(jù)庫進行讀取并插入緩存
    • 分布式環(huán)境的請求合并
      • 分布式鎖-->額外開銷->另外一個思路->在服務(wù)調(diào)用端不是把請求隨機分發(fā)給服務(wù)提供者,而是根據(jù)一定的規(guī)則把同樣的請求發(fā)送到同一個服務(wù)提供者上->減少復(fù)雜性.
    服務(wù)治理
    • 服務(wù)信息、服務(wù)質(zhì)量、服務(wù)容量、服務(wù)依賴、服務(wù)分布、服務(wù)統(tǒng)計、服務(wù)元數(shù)據(jù)、服務(wù)查詢、服務(wù)報表、服務(wù)監(jiān)視、服務(wù)上下線、服務(wù)路由、服務(wù)限流降級、服務(wù)歸組、服務(wù)線程池管理、機房規(guī)則、服務(wù)授權(quán)、
    • ESB
      • Enterprise Service Bus:企業(yè)服務(wù)總線

    數(shù)據(jù)訪問層

    數(shù)據(jù)庫減壓思路
    • 優(yōu)化應(yīng)用,看看是否有不必要的壓力給了數(shù)據(jù)庫(應(yīng)用優(yōu)化)
    • 看看有沒有辦法可以降低對數(shù)據(jù)庫的壓力,例如引入緩存、加搜索引擎等
    • 把數(shù)據(jù)庫的數(shù)據(jù)和訪問分到多臺數(shù)據(jù)庫上,分開支持->核心思路和邏輯
      • 數(shù)據(jù)拆分->垂直拆分->水平拆分
    單機變?yōu)槎鄼C后,事務(wù)如何處理
    • 分布式事務(wù)->XA/DTP-->AP(Application Program)->RM(Resource Manager)->TM(Transaction Manager)
      • 兩階段提交->Prepare->Commit
      • Prepare階段有一個節(jié)點資源失敗則Rollback
    • 大型網(wǎng)站一致性的基礎(chǔ)理論-CAP/BASE
      • CAP:Consitency,一致性、Availability,可用行、Partition-Tolerance,分區(qū)容忍性
      • 分布式系統(tǒng)中不能同時滿足上面三項,CA、AP、CP
      • 分布式系統(tǒng)中,我們一般選擇加強可用性和分區(qū)容忍性而犧牲一致性->首先先滿足A和P,然后看如何解決C的問題.
      • BASE模型
        • Basically Available,基本可用,允許分區(qū)失敗
        • Soft state,軟狀態(tài),接受一段時間的狀態(tài)不同步
        • Eventually consistent,最終一致,保證最終數(shù)據(jù)的狀態(tài)是一致的
        • 對于C,我們采用的方式和策略就是保持最終一致,也就是不保證數(shù)據(jù)發(fā)生變化后所有節(jié)點立刻一致,但是保證他們最終是一致的。在大型網(wǎng)站中,為了更好的保持?jǐn)U展性和可用性,一般都不會選擇強一致性,而是采用最終一致的策略來實現(xiàn).
    • 比兩階段提交更輕量一些的Paxos協(xié)議
      • 核心原則:少數(shù)服從多數(shù)
    • 集群內(nèi)數(shù)據(jù)一致性的算法實例
      • Quorum、Vector Clock算法
    • 從工程上說,如果能夠避免分布式事務(wù)的引入,那么還是避免為好;如果一定要引入分布式事務(wù),那么可以考慮最終一致的方法,而不是追求強一致。而且從實現(xiàn)上來說,我們是通過補償?shù)臋C制不斷重試,讓之前因為異常而沒有進行到底的操作繼續(xù)進行而不是回滾。如果還是不能滿足需求,那么基于Paxos的算法會是一個不錯的選擇.
    多機的Sequence問題與處理
    • 唯一性
    • 連續(xù)性
      • 提供一個實現(xiàn)方案:把所有id集中放到一個地方進行管理,每臺機器使用時都從這個id生成器上取
    跨庫查詢
    數(shù)據(jù)訪問層的設(shè)計與實現(xiàn)
    • 對外提供數(shù)據(jù)訪問層的方式
      • 為用戶提供專有API->不推薦->沒有通用性
      • 通用方式->jdbc->數(shù)據(jù)層自身可以作為一個jdbc的實現(xiàn),即暴露出jdbc的接口給應(yīng)用
      • 基于orm或者類orm接口的方式
    • 按照數(shù)據(jù)層流程的順序看數(shù)據(jù)層設(shè)計
      • SQL解析
        • 通過SQL解析可以得到SQL中的關(guān)鍵信息,如表明、字段、where條件等;而在數(shù)據(jù)層中,一個很重要的事情是根據(jù)執(zhí)行的SQL得到被操作的表,根據(jù)參數(shù)及規(guī)則來確定目標(biāo)數(shù)據(jù)庫連接
      • 規(guī)則處理階段
        • 用固定哈希算法作為規(guī)則_分庫分表
      • 一致性 hash
        • [把節(jié)點對應(yīng)的哈希值變?yōu)榱艘粋€范圍],而不再是離散的.在一致性哈希中,我們會把整個哈希值的范圍定義的非常大,然后把這個范圍分配給現(xiàn)有的節(jié)點
        • 虛擬節(jié)點對一致性hash的改進
          • 解決增加或減少節(jié)點時負(fù)載不均衡的問題
      • 映射表與規(guī)則自定義方式
        • 通過比較復(fù)雜的函數(shù)計算來解決數(shù)據(jù)訪問的規(guī)則問題
      • 為什么要改寫SQL
        • 多庫多表->修改表名->跨庫計算平均值等
      • 如何選擇數(shù)據(jù)源
        • Master/Slave
        • 根據(jù)當(dāng)前SQL的特點(讀、寫)、是否在事務(wù)中以及各個庫的權(quán)重規(guī)則,計算得到這次SQL請求要訪問的數(shù)據(jù)庫
      • 執(zhí)行SQL和結(jié)果處理階段
        • 對異常的處理和判斷
    • 實戰(zhàn)
      • 復(fù)雜的連接管理
      • 三層數(shù)據(jù)源的支持和選擇
        • DataSouce/AtomDataSource/groupDataSource
      • 獨立部署的數(shù)據(jù)訪問層實現(xiàn)方式
        • jar包方式
        • proxy方式
          • 數(shù)據(jù)庫協(xié)議
          • 私有協(xié)議
      • 讀寫分離的挑戰(zhàn)和應(yīng)對
        • 數(shù)據(jù)結(jié)果相同,多從庫對應(yīng)一主庫的場景
          • 應(yīng)用通過數(shù)據(jù)層訪問數(shù)據(jù)庫,通過消息系統(tǒng)就數(shù)據(jù)庫的更新送出消息通知->數(shù)據(jù)庫同步服務(wù)器獲得消息通知后會進行數(shù)據(jù)的復(fù)制工作.分庫規(guī)則配置則負(fù)責(zé)在讀數(shù)據(jù)及數(shù)據(jù)同步服務(wù)器更新分庫時讓數(shù)據(jù)層知道分庫規(guī)則->數(shù)據(jù)同步服務(wù)器和DB主庫的交互主要是根據(jù)被修改或新增的數(shù)據(jù)主鍵來獲取內(nèi)容,采用的是行復(fù)制的形式
          • 比較優(yōu)雅的方式是基于數(shù)據(jù)庫的日志來進行數(shù)據(jù)的復(fù)制
        • 主/備庫分庫方式不同的數(shù)據(jù)復(fù)制
          • 非對稱復(fù)制->控制數(shù)據(jù)分發(fā)->如主庫按照買家id分庫,而備庫按照賣家id進行分庫
        • 引入數(shù)據(jù)變更平臺
          • 很多其他場景也會關(guān)心數(shù)據(jù)的變更,除了復(fù)制到其他數(shù)據(jù)庫,例如緩存的失效等->可以考慮構(gòu)建一個通用的平臺來管理和控制數(shù)據(jù)變更->
          • 引入Extractor和Applier->Extractor負(fù)責(zé)把數(shù)據(jù)源變更的信息加入到數(shù)據(jù)分發(fā)平臺中,而Applier的作用是把這些變更應(yīng)用到相應(yīng)的目標(biāo)上->中間的數(shù)據(jù)分發(fā)平臺中是由多個管道組成->進入到數(shù)據(jù)分發(fā)平臺的變更信息就是標(biāo)準(zhǔn)化、結(jié)構(gòu)化的數(shù)據(jù)了-
          • 如何做到數(shù)據(jù)平滑遷移
            • 最大挑戰(zhàn)是,在遷移的過程中又會有數(shù)據(jù)的變化(因為很多應(yīng)用不能接受長時間的停機)->可以考慮的方案是在開始進行數(shù)據(jù)遷移時記錄增量的日志,在遷移結(jié)束后,再對增量的變化進行處理.->在最后,可以要把要被遷移的數(shù)據(jù)的寫暫停,保證增量日志都處理完畢后,再切換規(guī)則,放開所有的寫,完成遷移工作

    消息中間件

    消息中間件對應(yīng)用的解耦
    • 如登陸系統(tǒng)負(fù)責(zé)向消息中間件發(fā)送消息,而其他的系統(tǒng)則向消息中間件來訂閱這個消息,然后完成自己的工作.
    • 通過消息中間件解耦,登陸系統(tǒng)就不用關(guān)心到底有多少個系統(tǒng)需要知曉登陸成功這件事了,而不用關(guān)心如何通知它們,只需要把登陸成功這件事轉(zhuǎn)化為一個消息發(fā)送到消息中間件就可以了
    • landon:和事件解耦一樣,如游戲中玩家升級拋出一個事件,其他子系統(tǒng)只需要監(jiān)聽該事件即可,而不必升級直接調(diào)用各個子系統(tǒng)
    • 登陸成功時需要向消息中間件發(fā)送一個消息,那么[必須保證這個消息發(fā)送到了消息中間件],否則依賴這個消息的系統(tǒng)就無法工作了
    互聯(lián)網(wǎng)時代的消息中間件
    • JMS:Java Message Service->規(guī)范->Hornetq,ActiveMQ等產(chǎn)品是這個規(guī)范的實現(xiàn)
    • 如何解決消息發(fā)送一致性
      • 消息發(fā)送一致性的定義:產(chǎn)生消息的業(yè)務(wù)動作與消息發(fā)送的一致,即如果業(yè)務(wù)操作成功了,那么由這個操作產(chǎn)生的消息一定要發(fā)送出去,否則就丟失消息了;而另一方面,如果這個業(yè)務(wù)行為沒有發(fā)生或者失敗,那么就不應(yīng)該把消息發(fā)出去.
      • JMS消息模型-Queue/Topic_支持XA協(xié)議(兩階段提交)->會引入分布式事務(wù)->存在一些限制且成本相對較高
      • 一致性方案的正向流程
        • (1) 業(yè)務(wù)處理應(yīng)用首先把消息發(fā)給消息中間件,標(biāo)記消息的狀態(tài)為待處理.
        • (2) 消息中間件收到消息后,把消息存儲在消息存儲中,并不投遞該消息.
        • (3)消息中間件返回消息處理的結(jié)果,僅是入庫的結(jié)果,結(jié)果是成功或者失敗.
        • (4)業(yè)務(wù)方收到消息中間件返回的結(jié)果并進行處理:
          • a) 如果收到的結(jié)果是失敗,那么就放棄業(yè)務(wù)處理,結(jié)束
          • b) 如果收到的結(jié)果是成功,則進行業(yè)務(wù)自身的操作
        • (5)業(yè)務(wù)操作完成,把業(yè)務(wù)操作的結(jié)果發(fā)送給消息中間件
        • (6)消息中間件收到業(yè)務(wù)操作結(jié)果,根據(jù)結(jié)果進行處理
          • a) 如果業(yè)務(wù)失敗,則刪除消息存儲中的消息,結(jié)束
          • b)如果業(yè)務(wù)成功,則更新消息存儲中的消息狀態(tài)為可發(fā)送,并且進行調(diào)度,進行消息的投遞
      • 需要注意各種步驟中可能出現(xiàn)的異常情況
      • 最終一致性方案的補償流程:
        • (1)消息中間件詢問狀態(tài)為待處理的消息對應(yīng)業(yè)務(wù)操作結(jié)果
        • (2)應(yīng)用即消息發(fā)布者對業(yè)務(wù)操作檢查操作結(jié)果
        • (3)發(fā)送業(yè)務(wù)處理結(jié)果給消息中間件
        • 4)消息中間件更新消息狀態(tài),業(yè)務(wù)成功,消息狀態(tài)為待發(fā)送;業(yè)務(wù)失敗則消息刪除
    • 如何解決消息中間件與使用者的強依賴問題
      • 把消息中間件所需要的消息表與業(yè)務(wù)數(shù)據(jù)表放到同一個業(yè)務(wù)數(shù)據(jù)庫->業(yè)務(wù)操作和寫入消息作為一個本地事務(wù)完成,然后再通知消息中間件有消息可以發(fā)送->解決一致性->也可以消息中間件定時去輪詢業(yè)務(wù)數(shù)據(jù)庫找到需要發(fā)送的消息,取出內(nèi)容后進行發(fā)送
      • 需要業(yè)務(wù)自己的數(shù)據(jù)庫承載消息數(shù)據(jù)/需要讓消息中間件去訪問業(yè)務(wù)數(shù)據(jù)庫/需要業(yè)務(wù)操作的對象是一個數(shù)據(jù)庫
      • 消息中間件不再直接與業(yè)務(wù)數(shù)據(jù)庫打交道->將業(yè)務(wù)操作、寫入消息,輪詢消息等全部放到業(yè)務(wù)應(yīng)用
      • 加一個本地磁盤作為一個消息存儲
    • 消息模型對消息接收的影響
      • JMS Queue模型:
        • 應(yīng)用1和應(yīng)用2發(fā)送消息到JMS服務(wù)器,這些消息根據(jù)到達(dá)的順序形成一個隊列->應(yīng)用3和應(yīng)用4進行消息的消費;如果Queue里面的消息被一個應(yīng)用處理了,那么連接到JMS Queue上的另一個應(yīng)用是收不到這個消息的->即連接到這個JMS Queue上的應(yīng)用共同消費了所有的消息->消息從發(fā)送端發(fā)送出來時不能確定最終會被哪個應(yīng)用消費,但是可以明確的是只有一個應(yīng)用會去消費這條消息->Peer To Peer方式(PTP)
      • JMS Topic模型:
        • 和Queue模型的最大區(qū)別在于消息接收的部分,在該模型中,接收消息的應(yīng)用3和應(yīng)用4是可以獨立收到所有到達(dá)Topic的消息的->Pub/Sub方式
      • JMS中客戶端連接的處理和帶來的限制
        • JMS中每個Connection都有一個唯一的clientId,用于標(biāo)識連接的唯一性
        • 應(yīng)用3和JMS服務(wù)器建立了兩個連接,應(yīng)用4和JMS服務(wù)器建立了一個連接->可以看到這三個連接所接收的消息是完全不同,每個連接收到的消息條數(shù)以及收到消息的順序則不是固定的.->另外每個連接都會收到所有發(fā)送到Topic的消息.
      • 我們需要什么樣的消息模型
        • 消息發(fā)送方和接收方都是集群/同一個消息的接收方可能有多個集群進行消息的處理/不同集群對于同一條消息的處理不能相互干擾
        • 如8條消息和兩個集群,每個集群恰好有兩臺機器->那么需要這兩個集群的機器分別處理掉所有8條消息->不能遺漏也不能重復(fù)
        • 引入ClusterId,用這個Id來標(biāo)識不同的集群,而集群內(nèi)的各個應(yīng)用實例的連接使用同樣的ClusterId->把Topic模型和Queue模型的特點結(jié)合起來使用
    • 消息訂閱者訂閱消息的方式
      • 作為消息中間件,提供對于消息的可靠保證是非常重要的事情->一些場景中一些下游系統(tǒng)完全通過消息中間件進行自身任務(wù)的驅(qū)動
    • 持久訂閱、非持久訂閱
      • 非持久訂閱:消息接收者應(yīng)用啟動時,就建立了訂閱關(guān)系->可以收到消息->如果消息接收者應(yīng)用結(jié)束了,那么消息訂閱關(guān)系也就不存在了->這時的消息是不會為消息接收者保留的.
      • 持久訂閱:消息訂閱關(guān)系一旦建立除非應(yīng)用顯示地取消訂閱關(guān)系否則這個訂閱關(guān)系將一直存在即使消息接收者應(yīng)用停止->這個消息也會保留,等待下次應(yīng)用啟動后再投遞給消息接收者.
    • 保證消息可靠性
      • 消息從發(fā)送端應(yīng)用到接收端應(yīng)用,中間有三個階段需要保證可靠,分別是:[消息發(fā)送者把消息發(fā)送到消息中間件];[消息中間件把消息存入消息存儲];[消息中間件把消息投遞給消息接收者]
      • 要保證這三個階段都可靠,才能保證最終消息的可靠
        • 消息發(fā)送端可靠的保證->注意異對異常的處理->可能出現(xiàn)的問題是在不注意的情況下吃掉了異常->從而導(dǎo)致錯誤的判斷結(jié)果
        • 消息存儲的可靠性保證
          • 持久存儲部分的代碼完全自主實現(xiàn)
          • 利用現(xiàn)有的存儲系統(tǒng)實現(xiàn)
            • 實現(xiàn)基于文件的消息存儲
            • 采用數(shù)據(jù)庫作為消息存儲
            • 基于雙機內(nèi)存的消息存儲
        • 消息中間件自身擴容
          • 讓消息的發(fā)送者和消息的訂閱者能夠感知到有新的消息中間件機器加入到了機器->軟負(fù)載中心
        • 消息存儲的擴容處理
          • 服務(wù)端主動調(diào)度安排投遞
      • 消息投遞的可靠性保證
        • 消息接收者在處理消息的過程中對于異常的處理->千萬不要吃掉異常后確認(rèn)消息處理成功
        • 投遞處理優(yōu)化:
          • 投遞是一定要采用多線程處理
          • 單機多訂閱者共享連接->消息只發(fā)送一次
    • 訂閱者視角的消息重復(fù)的產(chǎn)生和應(yīng)對
      • 分布式事務(wù),復(fù)雜
      • 冪等操作->對于消息接收端->采用同樣的輸入多次調(diào)用處理函數(shù)會得到同樣的結(jié)果
      • JMS的消息確認(rèn)方式與消息重復(fù)的關(guān)系
        • AUTOACKNOWLEDGE/CLIENTACKNOWLEDGE/DUPSOKACKNOWLEDGE
    • 消息投遞的其他屬性支持
      • 消息優(yōu)先級
      • 訂閱者消息處理順序和分級訂閱
      • 自定義屬性
      • 局部順序
    • 保證順序的消息隊列設(shè)計
      • 接收端的設(shè)計從原來的Push模式變?yōu)榱薖ull模式

    軟負(fù)載中心與集中配置管理

    • 軟負(fù)載中心兩個最基礎(chǔ)的職責(zé)
      • 聚合地址信息
      • 生命周期感知->需要能對服務(wù)的上下線自動感知,并且根據(jù)這個變化去更新服務(wù)地址數(shù)據(jù)
    • 軟負(fù)載中心的結(jié)構(gòu)
      • 軟負(fù)載中心的服務(wù)端->負(fù)責(zé)感知提供服務(wù)的機器是否在線,聚合提供者的機器信息并負(fù)責(zé)把數(shù)據(jù)傳給使用數(shù)據(jù)的應(yīng)用
      • 軟負(fù)載中心的客戶端
        • 服務(wù)提供者->把服務(wù)器提供者提供服務(wù)的具體信息主動傳給服務(wù)端->并且隨著提供服務(wù)的變化去更新數(shù)據(jù)
        • 服務(wù)器使用者->向服務(wù)端告知自己所需要的數(shù)據(jù)并負(fù)責(zé)去更新數(shù)據(jù),還要進行本地的數(shù)據(jù)緩存
      • 軟負(fù)載中心三部分重要的數(shù)據(jù)->聚合數(shù)據(jù)、訂閱關(guān)系、連接數(shù)據(jù)
    • 內(nèi)容聚合功能的設(shè)計
      • 保證數(shù)據(jù)正確性
      • 高效聚合數(shù)據(jù)
        • 并發(fā)下的數(shù)據(jù)正確性的保證
        • 數(shù)據(jù)更新、刪除的[順序]保證
        • 大量數(shù)據(jù)同時插入、更新時的性能保證
          • 根據(jù)key進行分線程的處理->保證同樣key的數(shù)據(jù)是在同一個線程中處理->順序任務(wù)隊列
    • 解決服務(wù)上下線的感知
      • 通過客戶端與服務(wù)端的連接感知
        • 長連接的心跳或數(shù)據(jù)的發(fā)布來判斷服務(wù)發(fā)布者是否還在線->如果很久沒有心跳或數(shù)據(jù)的發(fā)布,則判定為不在線;那么就取出這個發(fā)布者發(fā)布的數(shù)據(jù)->而對于新上線的發(fā)布者,通過連接建立和數(shù)據(jù)發(fā)布就實現(xiàn)了上線的通知
        • 當(dāng)負(fù)載中心的自身的負(fù)載很高時,可能產(chǎn)生誤判,如軟負(fù)載中心壓力很大,處理請求變慢,心跳數(shù)據(jù)來不及處理->會以為心跳超時而判斷服務(wù)不在線,認(rèn)為服務(wù)不可用并且把信息通知給服務(wù)調(diào)用者,這會導(dǎo)致原本可用的服務(wù)被下線了
        • 另外的問題,如果服務(wù)發(fā)布者到軟負(fù)載中心的網(wǎng)絡(luò)鏈路有問題而服務(wù)發(fā)布者到服務(wù)使用者的鏈路沒問題,也會造成感知的問題->因為軟負(fù)載中心屬于旁路
          • 解決:軟負(fù)載中心客戶端增加邏輯,當(dāng)收到軟負(fù)載中心通知的應(yīng)用下線數(shù)據(jù)時,需要服務(wù)調(diào)用者進行驗證才能接收這個通知
      • 通過對于發(fā)布數(shù)據(jù)中提供的地址端口進行連接的檢查
        • 需要服務(wù)調(diào)用者進行最終確認(rèn),因為在系統(tǒng)中進行的實際業(yè)務(wù)調(diào)用通信是在服務(wù)調(diào)用者和服務(wù)提供者之間
    • 軟負(fù)載中心的數(shù)據(jù)分發(fā)的特點和設(shè)計
      • 數(shù)據(jù)分發(fā)與消息訂閱的區(qū)別
        • 消息中間件需要保證消息不丟失->每條消息都應(yīng)該送到相關(guān)訂閱者->而軟負(fù)載中心只需要保證最新數(shù)據(jù)送到相關(guān)的訂閱者->不需要保證每次的數(shù)據(jù)變化都能讓最終訂閱者感知
        • 消息中間件中同一個集群中的不同機器是分享所有消息的,因為該消息只要同一集群中的一臺機器去處理了就行->而軟負(fù)載中心則不同,因為其維護的是大家都需要用的服務(wù)數(shù)據(jù)->所以需要把這數(shù)據(jù)分發(fā)給所有的機器
      • 提升數(shù)據(jù)分發(fā)性能需要注意的問題
        • 數(shù)據(jù)壓縮->CPU換帶寬
        • 全量與增量的選擇->建議剛開始的實現(xiàn)中采用簡單的方式,即傳送全量數(shù)據(jù),當(dāng)全量數(shù)據(jù)很大時就需要考慮采用增量傳送的方式實現(xiàn).
      • 針對服務(wù)化的特性支持
        • 軟負(fù)載數(shù)據(jù)分組
          • 根據(jù)環(huán)境進行劃分
          • 分優(yōu)先級的隔離
        • 提供自動感知以外的上下線開關(guān)
          • 優(yōu)雅的停止應(yīng)用
            • 我們應(yīng)該先從服務(wù)列表中去掉這個機器->等待當(dāng)時正在執(zhí)行的服務(wù)器結(jié)束,然后再停止應(yīng)用->通過指令直接從軟負(fù)載中心使機器下線
          • 保持應(yīng)用場景,用于排錯
            • 遇到服務(wù)的問題時,可以把出問題的服務(wù)留下一臺進行故障定位和場景分析->此時需要把這臺機器從服務(wù)列表中拿下來,以免有新的請求進來造成服務(wù)的失敗,這也是需要軟負(fù)載中心直接使服務(wù)下線的一個場景.
        • 維護管理路由規(guī)則
          • 對不同特性的數(shù)據(jù)進行拆分
    • 從單機到集群
      • 數(shù)據(jù)管理問題/連接管理問題
      • 數(shù)據(jù)統(tǒng)一管理
        • 數(shù)據(jù)聚合放在一個地方->軟負(fù)載中心集群,無狀態(tài)->對于數(shù)據(jù)發(fā)布者和訂閱者來說,選擇軟負(fù)載中心集群中的任何一個機器連接皆可
        • 把軟負(fù)載中心集群中的機器的職責(zé)分開,即把聚合數(shù)據(jù)的任務(wù)和推送數(shù)據(jù)的任務(wù)分到專門的機器上處理->將軟負(fù)載中心集群中有一臺機器為軟負(fù)載中心數(shù)據(jù)聚合,另一臺機器為軟負(fù)載中心數(shù)據(jù)推送->發(fā)布者和訂閱者的連接是分開管理的->為了提升性能,在軟負(fù)載中心負(fù)責(zé)數(shù)據(jù)推送的機器上是可以對聚合數(shù)據(jù)做緩存
      • 數(shù)據(jù)對等管理方案
        • 將數(shù)據(jù)分散在各個軟負(fù)載中心的節(jié)點上并且把自己節(jié)點管理的數(shù)據(jù)分發(fā)到其他節(jié)點上,從而保證每個節(jié)點都有整個集群的全部數(shù)據(jù)并且這些節(jié)點的角色是對等的->使用軟負(fù)載中心的數(shù)據(jù)發(fā)布者和數(shù)據(jù)訂閱者只需要去連接軟負(fù)載中心集群中的任何一臺機器就可以->軟負(fù)載中心集群內(nèi)部,各個節(jié)點之間會進行數(shù)據(jù)的同步
          • 批量處理同步->合并變化,同步一次
          • 如果節(jié)點較多,同步量會較大->對集群內(nèi)的節(jié)點進行指責(zé)劃分
          • 如果集群管理的總體數(shù)據(jù)很多,超過了單機限制->則需要對數(shù)據(jù)進行分組處理->讓每個節(jié)點管理一部分?jǐn)?shù)據(jù)->即用UI規(guī)則對數(shù)據(jù)進行類似分庫分表的操作->則數(shù)據(jù)訂閱者可能就需要連接多個數(shù)據(jù)分發(fā)節(jié)點了
    • 集中配置管理中心
      • 集中配置管理中心結(jié)構(gòu)
        • 準(zhǔn)備的持久存儲來保存持久數(shù)據(jù)(Master-Slave)->一般采用關(guān)系型數(shù)據(jù)庫->通過兩個節(jié)點的主備來解決持久數(shù)據(jù)安全的問題.
        • 集中配置管理中心集群這層由多個集中配置管理中心節(jié)點組成->對等->都可以提供數(shù)據(jù)給應(yīng)用端等->互不依賴
        • 集中配置管理中心的單個節(jié)點->部署了一個nginx和一個web應(yīng)用->其中web應(yīng)用主要負(fù)責(zé)完成相關(guān)的程序邏輯如數(shù)據(jù)庫的相關(guān)操作以及根據(jù)ip等的分組操作,即整個應(yīng)用的邏輯放在了web應(yīng)用中;單機的本地文件Local File則是為了容災(zāi)和提升性能,客戶端進行數(shù)據(jù)獲取的時候,最后都是從nginx直接獲取本地文件并把數(shù)據(jù)返回給請求端
      • 集中配置管理中心的使用分為了以下兩部分
        • 提供給應(yīng)用使用的客戶端->主要是業(yè)務(wù)應(yīng)用通過客戶端去獲取配置信息和數(shù)據(jù),用于數(shù)據(jù)的讀取
        • 為控制臺或者控制腳本提供管理SDK
          • 包括了對數(shù)據(jù)的讀寫,通過管理SDK可以進行配置數(shù)據(jù)的更改
      • 客戶端實現(xiàn)和容災(zāi)策略
        • 客戶端通過http協(xié)議與集中配置管理中心進行通信
          • 通過輪詢獲取最新數(shù)據(jù)_普通輪詢
          • 改進使用長輪詢,Long Polling->如果沒有數(shù)據(jù),長輪詢會等待;如果等待數(shù)據(jù),立刻返回;如果一直沒有數(shù)據(jù)則等到超時后返回,繼續(xù)建立連接,而普通輪詢就直接返回了->是HTTP普通輪詢和Socket長連接方式的折中-
        • 容災(zāi)
          • 數(shù)據(jù)緩存
          • 數(shù)據(jù)快照
          • 本地配置
          • 文件格式->如果是二進制數(shù)據(jù)格式,那么就沒有對應(yīng)的工具是無法對配置進行修改->如果客戶端容災(zāi)退化到一個單機應(yīng)用就會需要直接修改配置內(nèi)容和數(shù)據(jù)->那么文本格式的限制就非常重要和關(guān)鍵了
      • 服務(wù)端實現(xiàn)和容災(zāi)策略
        • Nginx+Web應(yīng)用->和邏輯相關(guān)的部分在Web應(yīng)用上實現(xiàn),Nginx用于請求的處理和最后結(jié)果的返回,而供返回的數(shù)據(jù)的都在本地文件系統(tǒng)中
        • 和數(shù)據(jù)庫的數(shù)據(jù)同步
      • 數(shù)據(jù)庫策略
        • 數(shù)據(jù)庫在設(shè)計時需要支持配置的版本管理,即隨著配置內(nèi)容的更改,老的版本是需要保留的,為了方便進行配置變更的對比和回滾->而數(shù)據(jù)庫本身需要主備進行數(shù)據(jù)的容災(zāi)考慮

    構(gòu)建大型網(wǎng)站的其他要素

    • 加速靜態(tài)內(nèi)容訪問速度的CDN
      • CDN源站/CDN節(jié)點
      • 網(wǎng)絡(luò)緩存技術(shù)
      • 幾個關(guān)鍵技術(shù)
        • 全局調(diào)度->需要根據(jù)用戶地域、接入運營商以及CDN機房的負(fù)載情況去調(diào)度
        • 緩存技術(shù)->提升命中率
        • 內(nèi)容分發(fā)
        • 帶寬優(yōu)化
    • 大型網(wǎng)站的存儲支持
      • 基本上就是在解決存儲和計算的問題
      • 關(guān)系型數(shù)據(jù)庫
      • 分布式文件系統(tǒng)
        • 圖片、大文本存儲->使用數(shù)據(jù)庫不合適
        • NAS網(wǎng)絡(luò)存儲設(shè)備(Network Attached Storage),其本身的IO吞吐性能以及擴展性在大型網(wǎng)站中會出現(xiàn)比較明顯不足
        • 分布式文件系統(tǒng)具體產(chǎn)品
          • 開源的淘寶的TFS
          • 不開源的Google#GFS,Goole File System->GFS Client(負(fù)責(zé)從Master獲取要操作的文件在ChunkServer中的具體地址,然后直接和ChunkServer通信,獲取數(shù)據(jù)或者進行數(shù)據(jù)的寫入、更新)/GFS Master(維護所有的文件系統(tǒng)元數(shù)據(jù)、控制整個系統(tǒng)范圍內(nèi)的一些活動、與ChunkServer之間通過周期性的心跳進行通信,檢測對方是否在線)/GFS chunkserver(Data Node,文件存儲的地方)
          • 主要解決了單機文件存儲容量及安全性的問題,把多臺廉價pC組成一個大的分布式的看起來像文件系統(tǒng)的集群
          • [HDFS,采用Java的類GFS的實現(xiàn)]
        • NoSQL
          • No SQL/Not Only SQL
          • 基本上處于分布式文件系統(tǒng)和SQL關(guān)系型數(shù)據(jù)庫之間的系統(tǒng)都被歸為NOSQL的范疇
          • 數(shù)據(jù)模型
            • Key-Value,沒辦法進行高效的范圍查詢
            • Ordered Key-Value,Key是有序的->可解決基于Key的范圍查詢的效率問題,不過在這個模型中,Value本身的內(nèi)容和結(jié)構(gòu)是由應(yīng)用來負(fù)責(zé)解析和存儲的->如果在多個應(yīng)用中去使用則并不直觀也不方便
            • BigTable
              • Google的結(jié)構(gòu)化數(shù)據(jù)的分布式存儲系統(tǒng)->Value是由多個Column Family組成
            • Document,Full-Text Search
              • 可以在Value中任意自定義復(fù)雜的Scheme/對索引方面的支持
            • Graph
              • 支持圖結(jié)構(gòu)的數(shù)據(jù)類型
          • 系統(tǒng)結(jié)構(gòu)
            • [HBase]->借鑒Google BigTable的一個Java版本的開源實現(xiàn)
              • 存儲到HBase的數(shù)據(jù)是通過HRegionServer來管理的,每個HRegionServer管理了多個HRegion,每個Region管理具體的數(shù)據(jù)->HMaster是管理所有HRegionServer的節(jié)點,是一個中心控制的結(jié)構(gòu)
            • Amazon#Dynamo結(jié)構(gòu)
              • 采用了一致性哈希進行管理
              • [Cassandra]是一個開源的類似Dynamo的實現(xiàn)
    • 緩存系統(tǒng)
      • 非持久的存儲,是為了加速應(yīng)用對數(shù)據(jù)的讀取
      • Redis和Memcache是兩個使用很廣泛的開源緩存系統(tǒng)->Redis已經(jīng)有了對于集群的支持,也可以做單機的應(yīng)用來使用;而memcache本身還是一個單機的應(yīng)用,在使用時->集群->常見的是采用一致性哈希的方式
      • 使用緩存的場景
        • 使用緩存來降低對底層存儲的讀壓力,需要注意緩存和數(shù)據(jù)存儲中數(shù)據(jù)一致性問題
        • 應(yīng)用 <---> 緩存 <---> 存儲
          • 這種方式,應(yīng)用是不直接操作存儲,存儲由緩存控制;對于緩存來說,需要保證數(shù)據(jù)寫入緩存后能夠存入存儲中,所以緩存本身的邏輯會復(fù)雜些,需要有很多操作日志及故障恢復(fù)等
        • 另一種方式,應(yīng)用直接與緩存和存儲進行交互。一般的做法是應(yīng)用在寫數(shù)據(jù)時更新存儲,然后失效緩存數(shù)據(jù);而在讀數(shù)據(jù)時首先讀緩存,如果緩存中沒有數(shù)據(jù),那么再去讀存儲,并且把數(shù)據(jù)寫入緩存
        • 第三種方式,對于全數(shù)據(jù)緩存比較合適,即當(dāng)存儲的數(shù)據(jù)變化時,直接從存儲去同步數(shù)據(jù)到緩存中,以更新緩存數(shù)據(jù)
        • 另一個重要場景是對于Web應(yīng)用的頁面渲染內(nèi)容的緩存
          • 具體的實現(xiàn)技術(shù)為ESI(Edge Side Includes)->通過在返回的頁面中加上特殊的標(biāo)簽,然后根據(jù)標(biāo)簽的內(nèi)容去用緩存進行填充的一個過程.
          • 處理ESI標(biāo)簽的具體工作可以放在Java的應(yīng)用容器中做,也可以放在Java應(yīng)用容器前置的服務(wù)器做
    • 搜索系統(tǒng)
      • 站內(nèi)搜索->網(wǎng)站的數(shù)據(jù)量和訪問量很小時,一些數(shù)據(jù)的查詢可以直接用數(shù)據(jù)庫的Like操作來實現(xiàn)->實現(xiàn)效率低->不智能
      • 爬蟲問題->根據(jù)數(shù)據(jù)變化來更新索引
      • 倒排索引
      • 查詢預(yù)處理
      • 相關(guān)度計算
    • 數(shù)據(jù)計算支撐
      • 離線計算、實時計算
      • 離線計算
        • 把業(yè)務(wù)數(shù)據(jù)從在線存儲中移動到離線存儲中,然后進行數(shù)據(jù)處理的過程
        • Google MapReduce模型
          • Map階段:根據(jù)設(shè)定的規(guī)則把整體數(shù)據(jù)集映射給不同的Worker來處理并且生成各自的處理結(jié)果
          • Reduce階段:對前面處理過的數(shù)據(jù)進行聚合,形成最后的結(jié)果
          • [Hadoop]是MapReduce的一個開源實現(xiàn).Hadoop使用HDFS進行數(shù)據(jù)存儲,而[Spark]則提供了基于內(nèi)存的集群計算的支持
      • 在線計算
        • 流式計算->Storm
    • 發(fā)布系統(tǒng)
      • 分發(fā)應(yīng)用->需要提供自動高效并且容易操作的機制來把經(jīng)過測試的程序包分發(fā)到線上應(yīng)用->一般采用Web的操作方式
        • 發(fā)布控制臺->多機房->發(fā)布服務(wù)器
      • 啟動校驗
        • 應(yīng)用重啟啟動后,需要進行校驗從而完成這臺應(yīng)用服務(wù)器上的應(yīng)用發(fā)布->對應(yīng)用的校驗通常是應(yīng)用自身提供一個檢測腳本或者頁面,發(fā)布系統(tǒng)執(zhí)行這個腳本或者訪問頁面后來判斷返回的結(jié)果
        • 停止應(yīng)用時,需要優(yōu)雅的關(guān)閉->需要在關(guān)閉應(yīng)用前把這個應(yīng)用從負(fù)載均衡或者軟負(fù)載中心上移除
      • 灰度發(fā)布
        • 會對新應(yīng)用進行分批發(fā)布,逐步擴大新應(yīng)用在整個集群中的比例直至最后全部完成->這里講的灰度發(fā)布主要是針對新應(yīng)用在用戶體驗方面完全感知不到的更新.
      • 產(chǎn)品改版Beta
        • 提供新舊應(yīng)用的共存
    • 應(yīng)用監(jiān)控系統(tǒng)
      • 能夠及時了解應(yīng)用的運行狀況并能夠進行相應(yīng)的控制
      • 監(jiān)視和控制量部分
        • 數(shù)據(jù)監(jiān)視維度
          • 系統(tǒng)數(shù)據(jù)和應(yīng)用自身的數(shù)據(jù)->系統(tǒng)數(shù)據(jù)指的就是當(dāng)前應(yīng)用運行的系統(tǒng)環(huán)境的信息,如CPU使用率、內(nèi)存使用情況、交換分區(qū)使用情況、當(dāng)前系統(tǒng)負(fù)載、IO情況等;而應(yīng)用自身的數(shù)據(jù),則是不同應(yīng)用有不同的數(shù)據(jù),一般會是調(diào)用次數(shù)、成功率、響應(yīng)時間、異常數(shù)量等維度的數(shù)據(jù)
        • 數(shù)據(jù)記錄方式
          • 系統(tǒng)自身的數(shù)據(jù)已經(jīng)被記錄到了本地磁盤,應(yīng)用的數(shù)據(jù)一般也是存放在應(yīng)用自身的目錄中,便于采集->也有直接把應(yīng)用日志通過網(wǎng)絡(luò)發(fā)送到采集服務(wù)器的情況,可以減輕本地寫日志的壓力
          • 對于應(yīng)用數(shù)據(jù)的記錄,會考慮用定時統(tǒng)計的方式記錄一些量很大的信息.如對于一個提供服務(wù)的應(yīng)用,在沒有特別需求時,并不直接記錄每次調(diào)用的信息,而是會記錄一段時間如5s或者一個間隔時間內(nèi)的總調(diào)用次數(shù)、總響應(yīng)時間這樣寫信息,而對于異常信息則每次都會予以記錄;采用統(tǒng)計的方式是為了減小記錄的大小以及對本地磁盤的寫入壓力
        • 數(shù)據(jù)采集的方式
          • 采集方式有應(yīng)用服務(wù)器主動對同給監(jiān)控中心以及等待監(jiān)控中心來拉取兩種方式->前者控制權(quán)在應(yīng)用服務(wù)器上,可能出現(xiàn)的問題是應(yīng)用服務(wù)器推送的壓力超過采集的中心服務(wù)器的能力,會造成重試等額外開銷并且需要應(yīng)用服務(wù)器上的推送程序控制重試邏輯和當(dāng)前傳送位置等信息->后者把復(fù)雜性都放在中心采集服務(wù)器上處理,使得應(yīng)用服務(wù)器中支持?jǐn)?shù)據(jù)采集的部分變的簡單
          • 展現(xiàn)與告警
            • 提供圖表的形式可以提供Web頁面的展示->通過手機應(yīng)用來接收報警->比短信方式好
          • 控制
            • 應(yīng)用啟動后在運行期對于應(yīng)用的行為改變->對于應(yīng)用的運維,最低的要求是出現(xiàn)問題時可以通過重啟應(yīng)用解決,但是我們還是需要更加精細(xì)化的控制應(yīng)用-降低和一些切換。降級是我們遇到大量請求且不能擴容的情況時所進行的功能限制的行為->而切換更多的是當(dāng)依賴的下層系統(tǒng)出現(xiàn)故障并且需要手工進行切換時的一個管理,這些控制一般都是通過開關(guān),參數(shù)設(shè)置來完成
    • 依賴管理系統(tǒng)
      • 隨著網(wǎng)站功能增多,應(yīng)用的個數(shù)迅速增加,應(yīng)用之間的關(guān)系也會越來越復(fù)雜,理清這些依賴關(guān)系并能夠管理這些依賴會非常重要
      • 一個應(yīng)用在完成某個功能時到底需要依賴哪些外部系統(tǒng)、這些依賴中哪些是必要依賴,強依賴(登陸驗證用戶名和密碼),哪些是有了更好沒有也可以的依賴,弱依賴(如記錄登陸時間和ip等)
      • 動態(tài)檢測和靜態(tài)檢測->動態(tài)檢測的主要檢查方式是模擬被調(diào)用系統(tǒng)不可用和響應(yīng)慢的兩種情況
        • Google#Dapper,A Large-Scale Distributed Systems Tracing Infrastructure->traceId,index->形成一個調(diào)用時序圖
    • 多機房問題分析
      • 同城機房和異地機房
        • 同城多個機房中,對于重要的應(yīng)用系統(tǒng),會在不止一個機房中部署;而對于數(shù)據(jù)庫系統(tǒng),則會把主備放在不同機房->盡量避免不必要的跨機房的內(nèi)部系統(tǒng)調(diào)用
        • 為了數(shù)據(jù)安全,把產(chǎn)生的業(yè)務(wù)數(shù)據(jù)都同步到異地的機房->把一些對數(shù)據(jù)延遲不敏感的系統(tǒng)部署到異地,如只讀系統(tǒng).
    • 系統(tǒng)容量規(guī)劃
      • 我們應(yīng)該知道的信息就是整個系統(tǒng)的容量以及運行時所處的水位->我們把某個應(yīng)用系統(tǒng)集群能夠提供的并發(fā)能力和當(dāng)前的壓力比作一個水桶的容量和水位->那么準(zhǔn)確知道各個系統(tǒng)的容量和當(dāng)前高峰時的水位是一件很重要的事情->因為我們還是希望優(yōu)先通過擴大容量來支持更多的請求而不是首選降級的方案.
      • 考慮過去的增長情況并結(jié)合人為的判斷
        • 弄清楚當(dāng)前系統(tǒng)高峰期的水位
        • 弄清楚當(dāng)前各個系統(tǒng)的容量
          • 通過測試->壓力測試
        • 設(shè)置警戒值,高峰水位搞過警戒值就增加容量,保持高峰的水位是低于警戒值的
    • 內(nèi)部私有云

    總結(jié):

    可以將一些設(shè)計思路、方法等應(yīng)用到游戲服務(wù)器整體架構(gòu)設(shè)計當(dāng)中(主要是登陸、支付等http服務(wù)).

    posted on 2016-05-27 19:05 landon 閱讀(1848) 評論(0)  編輯  收藏 所屬分類: BookServerFramework
    主站蜘蛛池模板: 中文字幕在线免费| 毛片无码免费无码播放| 亚洲综合国产精品第一页| 成人无码a级毛片免费| 亚洲天堂一区在线| 免费va人成视频网站全| 久久青草免费91观看| 亚洲一区AV无码少妇电影| 国产综合亚洲专区在线| 67194熟妇在线永久免费观看| 亚洲av日韩av永久在线观看| 亚洲AV无码久久精品成人| 毛片网站免费在线观看| 久久久久久噜噜精品免费直播 | 国产精品免费看香蕉| 在线播放免费人成毛片乱码| 亚洲欧美一区二区三区日产| 久久亚洲国产午夜精品理论片| 最近免费中文字幕4| 国产午夜无码精品免费看| 亚洲精品无码日韩国产不卡av| 亚洲V无码一区二区三区四区观看| 成人免费在线视频| 日本xxxx色视频在线观看免费| 杨幂最新免费特级毛片| 亚洲偷偷自拍高清| 久久久久久亚洲精品| 亚洲国产成人精品女人久久久 | 黄色三级三级免费看| 亚洲欧洲日产国产最新| 久久影院亚洲一区| 日韩在线视频免费看| 99国产精品视频免费观看| 国产精品青草视频免费播放| 精品国产日韩久久亚洲| 亚洲精品综合久久中文字幕| 亚洲乱码日产一区三区| 免费人成视频x8x8入口| 日韩毛片免费在线观看| 日本免费人成在线网站| 免费人成在线观看网站品爱网|