SOA(面向服務的體系結構)概念由來已久,在10多年前便開始進入到咱們廣大軟件開發者的視線中。SOA是一種粗粒度、鬆耦合服務架構,服務之間經過簡單、精肯定義接口進行通信,不涉及底層編程接口和通信模型。SOA能夠看做是B/S模型、Web Service技術以後的天然延伸。web
服務治理,也稱爲SOA治理,是指用來管理SOA的採用和實現的過程。如下是在2006年時IBM對於服務治理要點的總結:面試
服務定義(服務的範圍、接口和邊界)spring
服務部署生命週期(各個生命週期階段)編程
服務版本治理(包括兼容性)安全
服務遷移(啓用和退役)性能優化
服務註冊中心(依賴關係)網絡
服務消息模型(規範數據模型)架構
服務監視(進行問題肯定)app
服務全部權(企業組織)負載均衡
服務測試(重複測試)
服務安全(包括可接受的保護範圍)
限於當時的技術發展水平,廣大軟件設計與開發人員對於SOA和服務治理的技術認知還主要停留在Web Service和ESB總線等技術和規範上,並無真正在軟件開發中得以充分落地。
直到2011年10月27日,阿里巴巴開源了本身的SOA服務化治理方案的核心框架Dubbo,服務治理和SOA的設計理念開始逐漸在國內軟件行業中落地,並被普遍應用。
Dubbo做爲阿里巴巴內部的SOA服務化治理方案的核心框架,在2012年時已經天天爲2000+個服務提供3,000,000,000+次訪問量支持,並被普遍應用於阿里巴巴集團的各成員站點。Dubbo自2011年開源後,已被許多非阿里系公司使用,其中既有當當網、網易考拉等互聯網公司,也有中國人壽、青島海爾等傳統企業。
Dubbo是一個高性能服務框架,致力於提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案,使得應用可經過高性能RPC實現服務的輸出和輸入功能,和Spring框架能夠無縫集成。
做爲一個分佈式服務框架,以及SOA治理方案,Dubbo其核心功能主要包括:
#remoting:遠程通信基礎,提供對多種NIO框架抽象封裝,包括「同步轉異步」和「請求-響應」模式的信息交換方式。
#Cluster: 服務框架核心,提供基於接口方法的遠程過程調用,包括多協議支持,並提供軟負載均衡和容錯機制的集羣支持。
#registry: 服務註冊中心,使服務消費方能動態的查找服務提供方,使地址透明,使服務提供方能夠平滑增長或減小機器
下圖來自Dubbo官網,描述了服務註冊中心、服務提供方、服務消費方、服務監控中心之間的調用關係,具體以下圖所示:
這裏咱們只是補充一下從源碼具體實現角度來看的某些細節方面,包括Invoker、Extensier等方面。任何官方已經介紹過的細節,咱們不作多此一舉,官方文檔已經足夠詳實了,這篇文檔的定位是補充實現的相關細節,是基於我在往Dubbo添加web service協議過程當中,所碰到過的一些困難。
上圖是服務提供者暴露服務的主過程:
首先ServiceConfig類拿到對外提供服務的實際類ref(如:HelloWorldImpl),而後經過ProxyFactory類的getInvoker方法使用ref生成一個AbstractProxyInvoker實例,到這一步就完成具體服務到Invoker的轉化。接下來就是Invoker轉換到Exporter的過程。
Dubbo處理服務暴露的關鍵就在Invoker轉換到Exporter的過程(如上圖中的紅色部分),下面咱們以Dubbo和RMI這兩種典型協議的實現來進行說明:
Dubbo協議的Invoker轉爲Exporter發生在DubboProtocol類的export方法,它主要是打開socket偵聽服務,並接收客戶端發來的各類請求,通信細節由Dubbo本身實現。
RMI協議的Invoker轉爲Exporter發生在RmiProtocol類的export方法,它經過Spring或Dubbo或JDK來實現RMI服務,通信細節這一塊由JDK底層來實現,這就省了很多工做量。
上圖是服務消費的主過程:
首先ReferenceConfig類的init方法調用Protocol的refer方法生成Invoker實例(如上圖中的紅色部分),這是服務消費的關鍵。接下來把Invoker轉換爲客戶端須要的接口(如:HelloWorld)。
關於每種協議如RMI/Dubbo/Web service等它們在調用refer方法生成Invoker實例的細節和上一章節所描述的相似。
因爲Invoker是Dubbo領域模型中很是重要的一個概念,不少設計思路都是向它靠攏。這就使得Invoker滲透在整個實現代碼裏,對於剛開始接觸Dubbo的人,確實容易給搞混了。
下面咱們用一個精簡的圖來講明最重要的兩種Invoker:服務提供Invoker和服務消費Invoker:
爲了更好的解釋上面這張圖,咱們結合服務消費和提供者的代碼示例來進行說明:
#服務消費者代碼 public class DemoClientAction { private DemoService demoService; public void setDemoService(DemoService demoService) { this.demoService = demoService; } public void start() { String hello = demoService.sayHello("world" + i); } }
上面代碼中的’DemoService’就是上圖中服務消費端的proxy,用戶代碼經過這個proxy調用其對應的Invoker(DubboInvoker、 HessianRpcInvoker、 InjvmInvoker、 RmiInvoker、 WebServiceInvoker中的任何一個),而該Invoker實現了真正的遠程服務調用。
#服務提供者代碼 public class DemoServiceImpl implements DemoService { public String sayHello(String name) throws RemoteException { return "Hello " + name; } }
上面這個類會被封裝成爲一個AbstractProxyInvoker實例,並新生成一個Exporter實例。這樣當網絡通信層收到一個請求後,會找到對應的Exporter實例,並調用它所對應的AbstractProxyInvoker實例,從而真正調用了服務提供者的代碼。
Dubbo裏還有一些其餘的Invoker類,但上面兩種是最重要的。
Extensier是Dubbo中一個很是重要的類,剛接觸Dubbo源碼的人看這個類的時候也多少會有點困惑,這個類很是重要,它就像是廚房裏的「大廚」,按照用戶的隨時須要把各類「食材」烹調出來。
咱們結合具體代碼詳細說一下Extensier的實現,下面是ServiceConfig類裏的一行代碼:
private static final Protocol protocol = Extensier.getExtensier(Protocol.class).getAdaptiveExtension();
上面代碼的程序流程圖以下所示(假定是第一次執行這行代碼):
在這個過程當中最重要的兩個方法是getExtensionClasses和createAdaptiveExtensionClass(圖中紅色部分),下面詳細對這兩個方法進行分析:
#getExtensionClasses
這個方法主要讀取META-INF/services/目錄下對應文件內容,在本示例代碼中,是讀取META-INF/services/com.alibaba.dubbo.rpc.Protocol文件中的內容,具體內容以下:
com.alibaba.dubbo.registry.support.RegistryProtocol com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol com.alibaba.dubbo.rpc.protocol.injvm.InjvmProtocol com.alibaba.dubbo.rpc.protocol.rmi.RmiProtocol com.alibaba.dubbo.rpc.protocol.hessian.HessianProtocol com.alibaba.dubbo.rpc.protocol.webservice.WebServiceProtocol
它分析該文件中的每一行(每一行對應一個類),分析這些類,若是發現有哪一個類的Annotation是@Adaptive,則找到對應的AdaptiveClass了,但因爲Protocol文件裏沒有哪一個類的Annotation是@Adaptive,因此在這個例子中該方法沒找到對應的AdaptiveClass。
#createAdaptiveExtensionClass
該方法是在getExtensionClasses方法找不到AdaptiveClass的狀況下被調用,該方法主要是經過字節碼的方式在內存中新生成一個類,它具備AdaptiveClass的功能,Protocol就是經過這種方式得到AdaptiveClass類的。
在互聯網公司面試中,架構的底層必定是面試官會問問的問題,針對面試官通常會提到的問題,我錄製了一些分佈式,微服務,性能優化等技術點底層原理的錄像視頻,加羣895244712能夠免費獲取這些錄像,裏面還有些分佈式,微服務,性能優化,spring,MyBatis的等源碼知識點的錄像視頻。