這裏的架構演進應該是從服務化的角度來講,應該說隨着業務發展,應用規模擴大,系統的一些公共服務就會抽取出來,獨立開發,部署,維護,用來解決併發,擴展,維護的問題。web
傳統垂直架構面試
有的地方也叫單體應用,以mvc模式開發:redis
這種並無什麼很差,發展初期大可能是這樣,體量沒那麼大,也不須要考慮高併發大流量可擴展性什麼的,簡單粗暴,解決業務需求就好,活下去才能活的更好。算法
可是必須明白這種簡單架構存在的一些問題:sql
1. 業務不斷髮展,功能逐漸增多,應用的開發維護成本變高,部署效率下降,隨便改個代碼,編譯一次十幾分鍾就浪費了。悲劇,咱們有個系統纔開發3年,就碰到這種狀況,一次打包編譯部署,13分鐘結束。docker
2. 不一樣的人負責不一樣的部分,一些通用代碼、公共代碼就各寫各的,不能複用,若是隻是util還好,可是一些外部服務的都有重複,那就happy了(不過這種狀況的出現,不必定是架構問題,更多多是管理);編程
3. 不斷地上新需求,不斷地改代碼,有時測試不到位,指定哪裏埋了bug,上生產後系統就down了,牽一髮而動全身;json
4. 可維護性,可靠性,擴展性變差。api
既然有這些問題,就要解決啊,業務就會提要求,你要解決啊,要否則影響我業務發展,影響我ipo上市啊,苦逼的碼農開始幹活了。緩存
不提應用的拆分主從那些手段,但從拆分後應用交互看,原來的本地api交互變成的遠程api的調用,這裏就出現了rpc,固然也有走esb,webservice。其實拆分後挺麻煩的,光一個分佈式事務就能折騰死人。
RPC架構
Remote Procedure Call,遠程方法調用,屏蔽底層實現細節,像調用本地方法同樣調用遠程服務。
上個做者的圖:
這個圖對於大多數rpc框架通用,實現的幾個技術點:
1. 服務提供者發佈服務:服務接口定義,數據結構,服務提供者信息等;
2. 客戶端遠程調用:一般是使用jdk的代碼代理攔截;
3. 底層通訊:如今應該更可能是使用netty吧,固然也有走支持http的;
4. 序列化:關注序列化反序列性能,xml,json,hessiaon,pb,protostuff,kryo等;
做者給了個socket實現簡單demo,來實現遠程調用,說明上面幾個技術點。
經常使用的rpc框架
1. Thrift;
2. Hadoop的Avro-RPC;
3. Hessian;
4. gRPC;
單論rpc的話,沒太多可說的,但是若是加上服務治理,那複雜度就幾何倍數增加了。服務治理裏面東西太多了,動態註冊,動態發現,服務管控,調用鏈分析等等問題這些問題,單憑rpc框架解決不了,因此如今經常使用的說的服務化框架,一般指的是rpc+服務治理2個點。
SOA服務化架構
感受soa架構應該是在rpc以前出現,用來解決異構系統的交互,一般的實現是經過ESB,WSDL來處理。其粒度一般來講是比較粗的。也存在服務治理方面的問題。
微服務
MSA也是一種服務化架構風格,正流行ing,服務劃分
1. 原子服務,粒度細;
2. 獨立部署,主要是容器;
分享篇文章:雲棲肥俠的文章 微服務(Microservice)那點事 。
MSA與SOA的對比:
感受在有了docker後,微服務這個概念忽然火了起來,總結就是微服務+容器+DevOps。
背景
應用從集中式走向分佈式
隨着業務的發展致使功能的增多,傳統的架構模式開發,測試,部署整個流程變長,效率變低,後臺服務的壓力變大,只能經過硬件擴容來暫時緩解壓力,但解決不了根本性問題:
通用法寶:拆分,大系統拆小系統,獨立擴展和伸縮。
須要服務治理
大拆小,核心服務提煉後,服務的數量變多,並且須要一些運行態的管控,這時候就須要服務治理:
服務框架介紹
Dubbo
阿里開源的Dubbo應該是業界分佈式服務框架最出名的了吧,看過公司的rpc框架,Dubbo的擴展性比咱們的好的多了,咱們的框架每次升級,改動都不少,改天要看下Dubbo的源碼瞭解瞭解擴展性。
HSF
淘寶的體量決定了他對極致性能的追求,HSF跨機房特性挺牛。
Coral Service
這個沒據說過,孤陋寡聞了。
框架設計
架構原理
萬變不離其中,這張圖能夠歸納rpc的一些通用原理:
細化了下:
功能
性能
可靠性
分佈式的,面試會問,用池子的話講就是,知識點啊。
服務治理
技術點
在功能設計方面,做者基於netty給了demo服務端和客戶端的代碼,我的理解:
1. 通用性api;
2. 擴展性,封裝底層,提供上層接口,隔離協議和底層通信;
可靠性設計
談分佈式系統必談可靠性。
鏈路有效性
經過心跳來確認雙方c、s存活,保證鏈路可用,心跳檢測機制分爲3個層面:
1. tcp層面,即tcp的keep-alive,做用於整個tcp協議棧;
2. 協議層的心跳檢測,主要存在於長鏈接協議中,例如smpp協議;
3. 應用層的心跳,業務雙方的定時發送心跳消息;
第2個沒據說過,經常使用的是1,3。通常使用netty的話用的是netty的讀寫空閒來實現心跳。
斷連
無論由於網絡掛了仍是服務端宕機,仍是心跳超時什麼的,致使鏈路不可用關閉,這時候就須要鏈路重連,須要注意的一點就是短連後,不要當即重連,留時間給系統釋放資源,能夠scheduler處理。
消息緩存重發
底層消息不會當即發送(也會致使半包粘包),斷鏈後,致使消息丟失,看有無業務需求,有就支持斷鏈後消息重發。
資源釋放
主要是斷鏈後,必定要保證資源銷燬和釋放,固然也包括一些線程池,內存等的釋放。
性能設計
性能差的三宗罪
對於底層通信框架來講,主要是下面幾個:
1. 通信模型的選擇,主要是阻塞非阻塞那些東西;
2. 序列化反序列化(後面有章單講序列化);
3. 線程模型,主要是服務端選擇什麼樣的線程模型來處理消息。
通訊性能三原則
既然有上面的3個問題,那就針對這些作優化了:
高性能之道這節做者講了netty的優點。
也就是一般所說的編碼、解碼。一般的通信框架會提供編解碼的接口,也會內置一些經常使用的序列化反序列化工具支持。
與通信框架和協議的關係,感受能夠理解爲:通信框架是通道,其上跑的碼流數據是利用各類序列化編碼後的各類協議。
功能設計
各類序列化框架須要考慮的主要有:
在擴展性這節,做者講了netty的對序列化的一些內置支持,但實際開發中,通常不太會使用這些東西,都會提供序列化反序列接口,自行擴展定義,因此擴展性特重要。
經常使用的序列化,xml,json,hessian,kryo,pb,ps,看需求須要支持那種,具體能夠搜索各序列化的性能和壓縮後大小。
這一章最主要的是講了自定義協議棧的設計,已經交互的過程,其餘講的可靠性設計什麼的跟以前通信框架一章有重複。
通訊模型
服務提供者和消費者之間採用單鏈路,長鏈接通訊,鏈路建立流程:
1. 客戶端發送握手請求,攜帶節點ID等認證信息;
2. 服務端校驗:節點ID有效性,重複登陸,ip地址黑白名單等,經過後,返回握手應答信息;
3. 鏈路創建後,客戶端發送業務消息;
4. 客戶端服務端心跳維持鏈路;
5. 服務端退出時,關閉鏈接,客戶端感知鏈接關閉,關閉客戶端鏈接。
協議消息定義
經過attachment兼容了擴展性。做者還講了將消息頭的通用序列化和消息體的自定義序列化,看需求吧,咱們公司的框架沒作這部分支持,作了簡化,將消息頭和消息體統一封裝,而後再加一個序列化方式組成一條消息發送。
安全性設計
服務路由指的是服務提供者集羣部署,消費端如何從服務列表中選擇合適的服務提供者提供服務進行調用。
透明化路由
負載均衡
這些都是點對點的鏈接,負載均衡大多會在客戶端執行,有種場景會取決於服務端負載,就是服務端服務配置的是域名。
本地路由優先策略
路由規則
除了上面提供的各類路由負載均衡,還允許自定義路由規則:
- 條件路由:主要是經過條件表達式來實現;
- 腳本路由:經過腳本解析實現。
其實應該還有一種客戶端經過代碼自定義路由選擇。這些主要是爲了擴展性。
路由策略定製
自定義路由場景:
1. 灰度;
2. 引流;
路由策略:
1. 框架提供接口擴展;
2. 配置平臺提供路由腳本配置;
配置化路由
指的是服務調用失敗後,根據容錯策略進行自動容錯處理。
集羣容錯場景
業務執行異常不屬於服務端異常。
容錯策略
這圖不錯,關係很清晰。
容錯策略擴展
其實還有一點,感受也挺重要,就是支持容錯後本地mcok。調用失敗後的鏈路切換和快速失敗確定要支持,緩存重發能夠不用。
本篇篇幅過長,相信能堅持看到最後的都是對知識求知如渴的人,未來一定不凡。順便點點關注點點讚唄。
歡迎工做一到五年的Java工程師朋友們加入Java架構開發:878249276
羣內提供免費的Java架構學習資料(裏面有高可用、高併發、高性能及分佈式、Jvm性能調優、Spring源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)合理利用本身每一分每一秒的時間來學習提高本身,不要再用"沒有時間「來掩飾本身思想上的懶惰!趁年輕,使勁拼,給將來的本身一個交代!