如何一步步構建屬於自己的Java 中間件實踐?

Java 編程語言 DNS 軟件 通信 java進階架構師 java進階架構師 2018-01-04

參考:《大型網站系統與Java中間件實踐》

第一章 分佈式系統介紹

  • 線程與進程的執行模式

  • 網絡通信基礎知識

  • 如何把應用從單機擴展到分佈式

  • 分佈式系統的難點

第二章 大型網站及其架構演進過程

  • 單機負載告警,數據庫與應用分離

  • 應用服務器負載告警,走向集群

  • 數據讀壓力變大,讀寫分離

  • 彌補關係型數據庫的不足,引入分佈式存儲系統

  • 讀寫分離後,數據庫又遇到瓶頸

  • 數據庫問題解決後,應用面對的新挑戰

  • 初識消息中間件

參考:《大型網站系統與Java中間件實踐》

第一章 分佈式系統介紹

  • 線程與進程的執行模式

  • 網絡通信基礎知識

  • 如何把應用從單機擴展到分佈式

  • 分佈式系統的難點

第二章 大型網站及其架構演進過程

  • 單機負載告警,數據庫與應用分離

  • 應用服務器負載告警,走向集群

  • 數據讀壓力變大,讀寫分離

  • 彌補關係型數據庫的不足,引入分佈式存儲系統

  • 讀寫分離後,數據庫又遇到瓶頸

  • 數據庫問題解決後,應用面對的新挑戰

  • 初識消息中間件

如何一步步構建屬於自己的Java 中間件實踐?

第一章 分佈式系統介紹

分佈式系統的定義:組件分佈在網絡計算機上,組件間僅僅通過消息傳遞來通信並協調行動。

分佈式系統的意義:

  • 升級單機處理能力的性價比越來越低

  • 單機處理能力存在瓶頸

  • 處於穩定性和可用性的考慮

摩爾定律:當價格不變時,每隔18個月,集成電路上可容納的晶體管數目會增加一倍,性能也將提升一倍。

線程與進程的執行模式

馮諾依曼結構:輸入設備、輸入設備、運算器、控制器、存儲器。

基於共享容器協同的多線程模式:經典如生產者消費者問題,對於存儲數據的容器或對象,有線程安全和不安全之分,對於不安全的容器或對象,一般可以通過加鎖或者通過Copy On Write的方式控制併發。

通過事件協同的多線程模式:避免死鎖

多進程模式:

  • 線程是屬於進程的,一個進程內的多個線程共享了進程的內存空間;而多個進程間的內存空間是獨立的,因此多個進程間通過內存共享、交換數據的方式與多個線程間就有所不同

  • 此外,進程間通信、協調,以及通過一些事件通知或者等待一些互斥鎖的釋放方面也不一樣

  • 多進程相對於單進程多線程來說,資源控制會更容易實現;多進程中單個進程出現問題,不會造成整體的不可用

  • 多進程之間可以共享數據,但其代價較大,會涉及序列化和反序列化的開銷

網絡通信基礎知識

OSI七層模型與TCP/IP模型:

Socket套接字進行網絡通信開發時,用到的三種方式:BIO、NIO和AIO

BIO:Blocking IO,採用阻塞的方式實現,一個線程處理一個Socket,發生建立連接、讀數據、寫數據的操作時,都可能會阻塞。

NIO:Nonblocking IO,基於時間驅動思想,採用Reactor模式,可以在一個線程中處理多個Socket套接字

AIO:AsynchronousIO,異步IO,採用Proactor模式,與NIO的差別是,AIO在進行讀寫操作時,只需要調用響應的read/write方法,並且需要傳入CompletionHandler,在動作完成後會調用。

如何把應用從單機擴展到分佈式

輸入設備的變化

輸出設備的變化

控制器的變化

方式1和2,透明代理:對發起方和處理方都是透明的

  • 使用硬件負載均衡

  • 使用LVS(或其他軟件負載均衡系統)

缺點:

  • 會增加網絡的開銷,一方面指流量,另一方面指延遲

  • 這個透明代理處於請求的必經之路,如果代理出現問題,所有請求都會受到影響。我們需要考慮代理服務器的熱備份

方式3,採用名稱服務器直連的方式:

請求發起方和處理方直接沒有代理服務器,而是直接連接。外部多了一個“名稱服務”的角色,作用有:

  • 收集提供請求處理的服務器的地址信息

  • 提供這些地址信息給請求發起方

名稱服務只是起到一個地址交換的作用,在發起請求的機器上,需要根據從名稱服務得到的地址進行負載均衡的工作。

優點如下:

  • 名稱服務器出現問題,有辦法可以保證處理正常

  • 發起方和處理方直連,減少中間路徑和帶寬小號

缺點就是代碼升級較複雜

方式4,採用規則服務器控制路由的請求直連調用

與名稱服務器不同的是,規則服務器並不和請求處理的機器交互,只負責把規則提供給請求發起的機器。

方式5,Master+Worker的方式

存在一個Master節點來管理任務,由Master把任務分配給不同的Worker進行處理。

運算器的變化

  • 通過DNS服務器進行調度和控制

  • 增加負載均衡設備,DNS返回的永遠是負載均衡地址

存儲器的變化

同控制器的變化,加代理服務器、or名稱服務器、or規則服務器

分佈式系統的難點

  • 缺乏全局時鐘

  • 面對故障獨立性

  • 處理單點故障,如果不能把單點變為集群,則需要給單點做好備份,降低單點故障影響範圍

  • 事務的挑戰:2PC、最終一致、BASE、CAP、Paxos等

第二章 大型網站及其架構演進過程

大型網站:訪問量(PV)、數據量、業務複雜度

單機負載告警,數據庫與應用分離

應用服務器負載告警,走向集群

  • 服務器選擇問題:DNS、集群前加負載均衡設備

  • Session的問題

Session保存會話狀態,在Web服務器上,各個會話獨立存儲,多臺服務器不能保證每次請求都落在同一邊的服務器上。解決方案如下:

1、Session Sticky:負載均衡根據會話標識進行轉發,讓同樣的Session請求每次都發送到同一個服務器端處理

缺點:

  • 如果一臺Web服務器宕機或重啟,會話數據會丟失,用戶要重新登錄

  • 會話標識是應用層信息,則負載均衡要在應用層進行解析,開銷比在第四層大

  • 負載均衡變為了有狀態的節點,要將會話保存到具體Web服務器的映射。內存消耗會變大,容災更麻煩

2、Session Replication:會話在多態服務器上覆制同步

缺點:

  • 同步Session數據造成了網絡帶寬的開銷

  • 每臺Web服務器都要保存所有的Session數據,數據量容易很大

3、Session數據集中存儲

Session數據不再Web服務器上,而是放在另一個集中存儲的地方。

缺點:

  • 讀寫Session數據引入了網絡操作,存在時延和不穩定性

  • 如果集中存儲Session的機器或者集群有問題,就會影響我們的應用

4、Cookie Based:把Session數據放在Cookie中

缺點:

  • Cookie長度的限制

  • 安全性:外部訪問和修改

  • 帶寬消耗

  • 性能影響:每次HTTP請求都帶有Session數據

數據讀壓力變大,讀寫分離

1、採用數據庫作為讀庫

缺點:

  • 數據複製問題;

  • 應用對於數據源的選擇問題:寫操作和事務走主庫,考慮從庫相對主庫的延遲

2、搜索引擎其實是一個讀庫

3、加速數據讀取的利器——緩存

  • 數據緩存,Key-Value,“熱數據”,容量不夠時清除緩存

  • 頁面緩存,ESI標籤頁面緩存

彌補關係型數據庫的不足,引入分佈式存儲系統

分佈式文件系統,解決小文件和大文件的存儲問題

分佈式key-value系統,提供高性能的半結構化支持

分佈式數據庫提供一個支持大數據、高併發的數據庫系統

讀寫分離後,數據庫又遇到瓶頸

儘管讀寫分離以及分佈式存儲系統,能夠降低主庫的壓力,但是交易、商品、用戶的數據都還在一個數據庫中,壓力還在繼續增加,我們有數據垂直拆分和水平拆分兩種選擇;

1、專庫專用,數據垂直拆分

垂直拆分即把不同的業務數據分到不同的數據庫中。

問題:

  • 應用需要多個數據源,帶來的是每個數據庫連接池的隔離

  • 單機跨業務事務,一種方法是使用分佈式事務,性能較低;另一種辦法就是去掉事務

2、單表達到瓶頸,數據水平拆分

水平拆分就是把同一個表的數據拆到兩個數據庫中。

問題:

  • SQL路由問題,選擇哪個數據表

  • 主鍵處理等機制不同,如自增主鍵

  • 一些查詢需要從兩個數據庫中取數據,加上分頁操作,比較難處理

數據庫問題解決後,應用面對的新挑戰

拆分應用

  • 根據業務特性,還可以根據用戶註冊、登陸、用戶信息維護等再拆分。

  • 走服務化的路,共享代碼放在各個服務中心,如商品中心、用戶中心、交易中心

初識消息中間件

消息中間件是在分佈式系統中完成消息發送和接收的基礎軟件。兩個明顯好處:異步、解耦。

第三章 構建Java中間件

第四章 服務框架

第五章 數據訪問層

第六章 消息中間件

篇幅較多,留待下章講解

已完結專題(關注後查看):

【mysql優化專題】【HTTP協議】

【架構技術專題】【多線程/池專題】

更新中專題(關注後查看):

  • 【dubbo專題】【dubbo源碼專題】

  • 【JVM專題】【HTTP協議專題】

  • 【設計模式專題】【高併發專題】

  • 【架構技術專題】【netty專題】

  • 【數據結構專題】【redis專題】

相關推薦

推薦中...