一、分布式架構(gòu)的發(fā)展歷史與背景
分布式系統(tǒng)(distributed system)是建立在網(wǎng)絡(luò)之上的軟件系統(tǒng)。正是因?yàn)檐浖奶匦裕苑植际较到y(tǒng)具有高度的內(nèi)聚性和透明性燕少。因此,網(wǎng)絡(luò)和分布式系統(tǒng)之間的區(qū)別更多的在于高層軟件(特別是操作系統(tǒng))蒿囤,而不是硬件客们。簡(jiǎn)單點(diǎn)理解就是一個(gè)節(jié)點(diǎn)來(lái)干的活,先在分成多個(gè)節(jié)點(diǎn)來(lái)干。
為什么會(huì)發(fā)展分布式架構(gòu)底挫?
- 穩(wěn)定性和可用性這兩個(gè)指標(biāo)很難達(dá)到嗽桩。如:?jiǎn)吸c(diǎn)問(wèn)題,一旦大型主機(jī)出現(xiàn)故障凄敢,那整個(gè)系統(tǒng)就將處于不可用的狀態(tài)。而對(duì)于大型機(jī)的使用機(jī)構(gòu)來(lái)說(shuō)湿痢,這種不可用導(dǎo)致的損失是非常巨大的涝缝。
- 單機(jī)處理能力存在瓶頸
- 升級(jí)單機(jī)處理能力的性價(jià)比越來(lái)越低
架構(gòu)的發(fā)展歷史
分布式架構(gòu)所帶來(lái)的成本
分布式事物
分布式事物是指一個(gè)操作,分成幾個(gè)小操作在多個(gè)服務(wù)器上執(zhí)行譬重,要么多成功拒逮,要么多失敗這些分布事物要做的
不允許服務(wù)有狀態(tài)(stateless service)
無(wú)狀態(tài)服務(wù)是指對(duì)單次請(qǐng)求的處理,不依賴其他請(qǐng)求臀规,也就是說(shuō)滩援,處理一次請(qǐng)求所需的全部信息,要么都包含在這個(gè)請(qǐng)求里塔嬉,要么可以從外部獲取到(比如說(shuō)數(shù)據(jù)庫(kù))玩徊,服務(wù)器本身不存儲(chǔ)任何信息。
服務(wù)依懶關(guān)系復(fù)雜
服務(wù) A --> B--> C 那和服務(wù)C 的修改 就可能會(huì)影響 B 和C谨究,事實(shí)上當(dāng)服務(wù)越來(lái) 越多的時(shí)候恩袱,C的變動(dòng)將會(huì)越來(lái)越困難。
部署運(yùn)維成本增加
不用說(shuō)了胶哲,相比之前幾個(gè)節(jié)點(diǎn)畔塔,運(yùn)維成本的增加必須的。
源碼管理成本增加
原本一套或幾套源碼現(xiàn)在拆分成幾十個(gè)源碼庫(kù)鸯屿,其中分支澈吨、tag都要進(jìn)行相應(yīng)管理。
如何保證系統(tǒng)的伸縮性
伸縮性是指,當(dāng)前服務(wù)器硬件升級(jí)后或新增服務(wù)器處理能力就能相對(duì)應(yīng)的提升寄摆。
分布式會(huì)話
此僅針對(duì)應(yīng)用層服務(wù)谅辣,不能將Session 存儲(chǔ)在一個(gè)服務(wù)器上。
分布式JOB
通常定時(shí)任務(wù)只需要在一臺(tái)機(jī)器上觸發(fā)執(zhí)行冰肴,分布式的情況下在哪臺(tái)執(zhí)行呢屈藐?
二、如何選型分布式架構(gòu)
如何選型分布式架構(gòu)
RPC遠(yuǎn)程調(diào)用技術(shù)
協(xié)議 | 描述 | 優(yōu)點(diǎn) | 缺點(diǎn) |
---|---|---|---|
RMI | JAVA 遠(yuǎn)程方法調(diào)用熙尉、使用原生二進(jìn)制方式進(jìn)行序列化 | 簡(jiǎn)單易用联逻、SDK支持,提高開(kāi)發(fā)效率 | 不支持跨語(yǔ)言 |
Web Service | 比較早系統(tǒng)調(diào)用解決方案 检痰,跨語(yǔ)言, 其基于WSDL 生成 SOAP 進(jìn)行消息的傳遞包归。 | SDK支持、跨語(yǔ)言 | 實(shí)現(xiàn)較重铅歼,發(fā)布繁瑣 |
Http | 采用http +json 實(shí)現(xiàn) | 簡(jiǎn)單公壤、輕量换可、跨語(yǔ)言 | 不支持SDK |
Hessian | 采用http +hessian 序列化實(shí)現(xiàn) | 簡(jiǎn)單,輕量厦幅、sdk支持 | 不能跨語(yǔ)言 |
基于反向代理的集中式分布式架構(gòu)
這是最簡(jiǎn)單和傳統(tǒng)做法沾鳄,在服務(wù)消費(fèi)者和生產(chǎn)者之間,代理作為獨(dú)立一層集中部署确憨,由獨(dú)立團(tuán)隊(duì)(一般是運(yùn)維或框架)負(fù)責(zé)治理和運(yùn)維译荞。常用的集中式代理有硬件負(fù)載均衡器(如F5),或者軟件負(fù)載均衡器(如Nginx)休弃,這種軟硬結(jié)合兩層代理也是業(yè)內(nèi)常見(jiàn)做法吞歼,兼顧配置的靈活性(Nginx比F5易于配置)。
- 優(yōu)點(diǎn):簡(jiǎn)單快速塔猾、幾乎沒(méi)有學(xué)習(xí)成本
- 適用場(chǎng)景:輕量級(jí)分布式系統(tǒng)篙骡、局部分布式架構(gòu)。
- 瓶頸:Nginx中心負(fù)載丈甸、Http傳輸糯俗、JSON序列化、開(kāi)發(fā)效率老虫、運(yùn)維效率叶骨。
嵌入應(yīng)用內(nèi)部的去中心化架構(gòu)
這是很多互聯(lián)網(wǎng)公司比較流行的一種做法,代理(包括服務(wù)發(fā)現(xiàn)和負(fù)載均衡邏輯)以客戶庫(kù)的形式嵌入在應(yīng)用程序中祈匙。這種模式一般需要獨(dú)立的服務(wù)注冊(cè)中心組件配合忽刽,服務(wù)啟動(dòng)時(shí)自動(dòng)注冊(cè)到注冊(cè)中心并定期報(bào)心跳,客戶端代理則發(fā)現(xiàn)服務(wù)并做負(fù)載均衡夺欲。我們所熟悉的 duboo 和spring cloud Eureka +Ribbon/'r?b?n/ 都是這種方式實(shí)現(xiàn)跪帝。
相比第一代架構(gòu)它有以下特點(diǎn)幾點(diǎn):
- 去中心化,客戶端直連服務(wù)端些阅,減少一次網(wǎng)絡(luò)傳輸伞剑。
- 動(dòng)態(tài)注冊(cè)和發(fā)現(xiàn)服務(wù),不需要人工去發(fā)現(xiàn)設(shè)置服務(wù)市埋。
- 高效穩(wěn)定的網(wǎng)絡(luò)傳輸
- 高效可容錯(cuò)的序列化
- 代碼侵入性進(jìn)較強(qiáng)
基于獨(dú)立代理進(jìn)程的架構(gòu)
這種做法是上面兩種模式的一個(gè)折中黎泣,代理既不是獨(dú)立集中部署,也不嵌入在客戶應(yīng)用程序中缤谎,而是作為獨(dú)立進(jìn)程部署在每一個(gè)主機(jī)上抒倚,一個(gè)主機(jī)上的多個(gè)消費(fèi)者應(yīng)用可以共用這個(gè)代理,實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)和負(fù)載均衡坷澡,如下圖所示托呕。這個(gè)模式一般也需要獨(dú)立的服務(wù)注冊(cè)中心組件配合,作用同第二代架構(gòu)。
模式 | 優(yōu)點(diǎn) | 缺點(diǎn) | 適應(yīng)場(chǎng)景 | 案例 |
---|---|---|---|---|
集中式負(fù)載架構(gòu) | 簡(jiǎn)單 集中式治理 與語(yǔ)言無(wú)關(guān) | 配置維護(hù)成本高 多了一層IO 單點(diǎn)問(wèn)題 | 大部分公司都適用项郊,對(duì)運(yùn)維有要求 | 億貝馅扣、攜程、早期互聯(lián)網(wǎng)公司 |
客戶端嵌入式架構(gòu) | 無(wú)單點(diǎn) 性能更好 | 客戶端復(fù)雜 語(yǔ)言棧要求 | 中大規(guī)模公司着降、語(yǔ)言棧統(tǒng)一 | Dubbo 差油、Twitter finagle、Spring Cloud Ribbon |
獨(dú)立進(jìn)程代理架構(gòu) | 無(wú)單點(diǎn) 性能更好 與語(yǔ)言無(wú)關(guān) | 運(yùn)維部署復(fù)雜 開(kāi)發(fā)聯(lián)調(diào)復(fù)雜 | 中大規(guī)模公司 對(duì)運(yùn)維有要求 | Smart Stack任洞、Service Mesh |
三厌殉、Dubbo 架構(gòu)與設(shè)計(jì)說(shuō)明
dubbo架構(gòu)
流程說(shuō)明
- Provider(提供者)綁定指定端口并啟動(dòng)服務(wù)
- 指供者連接注冊(cè)中心,并發(fā)本機(jī)IP侈咕、端口、應(yīng)用信息和提供服務(wù)信息發(fā)送至注冊(cè)中心存儲(chǔ)
- Consumer(消費(fèi)者)器紧,連接注冊(cè)中心 耀销,并發(fā)送應(yīng)用信息、所求服務(wù)信息至注冊(cè)中心
- 注冊(cè)中心根據(jù) 消費(fèi) 者所求服務(wù)信息匹配對(duì)應(yīng)的提供者列表發(fā)送至Consumer 應(yīng)用緩存铲汪。
- Consumer 在發(fā)起遠(yuǎn)程調(diào)用時(shí)基于緩存的消費(fèi)者列表?yè)衿湟话l(fā)起調(diào)用熊尉。
- Provider 狀態(tài)變更會(huì)實(shí)時(shí)通知注冊(cè)中心、在由注冊(cè)中心實(shí)時(shí)推送至Consumer
這么設(shè)計(jì)的意義
- Consumer 與Provider 解偶掌腰,雙方都可以橫向增減節(jié)點(diǎn)數(shù)狰住。
- 注冊(cè)中心對(duì)本身可做對(duì)等集群,可動(dòng)態(tài)增減節(jié)點(diǎn)齿梁,并且任意一臺(tái)宕掉后催植,將自動(dòng)切換到另一臺(tái)
- 去中心化,雙方不直接依懶注冊(cè)中心勺择,即使注冊(cè)中心全部宕機(jī)短時(shí)間內(nèi)也不會(huì)影響服務(wù)的調(diào)用
- 服務(wù)提供者無(wú)狀態(tài)创南,任意一臺(tái)宕掉后,不影響使用
Dubbo 整體設(shè)計(jì)
- config 配置層:對(duì)外配置接口省核,以 ServiceConfig, ReferenceConfig 為中心稿辙,可以直接初始化配置類,也可以通過(guò) spring 解析配置生成配置類
- proxy 服務(wù)代理層:服務(wù)接口透明代理气忠,生成動(dòng)態(tài)代理 擴(kuò)展接口為 ProxyFactory邻储,屏蔽了底層,讓業(yè)務(wù)層只需要面向接口進(jìn)行編程旧噪。
- registry 注冊(cè)中心層:封裝服務(wù)地址的注冊(cè)與發(fā)現(xiàn)吨娜,以服務(wù) URL 為中心,擴(kuò)展接口為 RegistryFactory, Registry, RegistryService
- cluster 路由層:封裝多個(gè)提供者的路由及負(fù)載均衡舌菜,并橋接注冊(cè)中心萌壳,以 Invoker 為中心,擴(kuò)展接口為 Cluster, Directory, Router, LoadBalance
- monitor 監(jiān)控層:RPC 調(diào)用次數(shù)和調(diào)用時(shí)間監(jiān)控,以 Statistics 為中心袱瓮,擴(kuò)展接口為 MonitorFactory, Monitor, MonitorService
- protocol 遠(yuǎn)程調(diào)用層:封裝 RPC 調(diào)用缤骨,以 Invocation, Result 為中心,擴(kuò)展接口為 Protocol, Invoker, Exporter
- exchange 信息交換層:封裝請(qǐng)求響應(yīng)模式尺借,同步轉(zhuǎn)異步绊起,以 Request, Response 為中心,擴(kuò)展接口為 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer
- transport 網(wǎng)絡(luò)傳輸層:抽象 mina 和 netty 為統(tǒng)一接口燎斩,以 Message 為中心虱歪,擴(kuò)展接口為 Channel, Transporter, Client, Server, Codec
- serialize 數(shù)據(jù)序列化層:可復(fù)用的一些工具,擴(kuò)展接口為 Serialization, ObjectInput, ObjectOutput, ThreadPool
其協(xié)作流程如下
Dubbo 中的SPI機(jī)制
java spi的具體約定為:當(dāng)服務(wù)的提供者栅表,提供了服務(wù)接口的一種實(shí)現(xiàn)之后笋鄙,在jar包的META-INF/services/目錄里同時(shí)創(chuàng)建一個(gè)以服務(wù)接口命名的文件。該文件里就是實(shí)現(xiàn)該服務(wù)接口的具體實(shí)現(xiàn)類怪瓶。而當(dāng)外部程序裝配這個(gè)模塊的時(shí)候萧落,就能通過(guò)該jar包META-INF/services/里的配置文件找到具體的實(shí)現(xiàn)類名,并裝載實(shí)例化洗贰,完成模塊的注入找岖。 基于這樣一個(gè)約定就能很好的找到服務(wù)接口的實(shí)現(xiàn)類,而不需要再代碼里制定敛滋。jdk提供服務(wù)實(shí)現(xiàn)查找的一個(gè)工具類java.util.ServiceLoader
dubbo spi 在JAVA自帶的SPI基礎(chǔ)上加入了擴(kuò)展點(diǎn)的功能许布,即每個(gè)實(shí)現(xiàn)類都會(huì)對(duì)應(yīng)至一個(gè)擴(kuò)展點(diǎn)名稱,其目的是 應(yīng)用可基于此名稱進(jìn)行相應(yīng)的裝配绎晃。