RPC咱們這是 Demo,目的是突出 RPC框架重點功能 - 實現遠程調用。因此啥七七八八的都沒,而且我用僞代碼來展現,其實也就是刪除了一些保護性和約束性的代碼,由於看起來太多了不太直觀,須要一堆 try-catch 啥的,所以我刪減了一些,直擊重點。面試
首先咱們定義一個接口和一個簡單實現。redis
public interface AobingService { String hello(String name); } public class AobingServiceImpl implements AobingService { public String hello(String name) { return "Yo man Hello,I am" + name; } }
而後咱們再來實現服務提供者暴露服務的功能。數據庫
public class AobingRpcFramework { public static void export(Object service, int port) throws Exception { ServerSocket server = new ServerSocket(port); while(true) { Socket socket = server.accept(); new Thread(new Runnable() { //反序列化 ObjectInputStream input = new ObjectInputStream(socket.getInputStream()); String methodName = input.read(); //讀取方法名 Class<?>[] parameterTypes = (Class<?>[]) input.readObject(); //參數類型 Object[] arguments = (Object[]) input.readObject(); //參數 Method method = service.getClass().getMethod(methodName, parameterTypes); //找到方法 Object result = method.invoke(service, arguments); //調用方法 // 返回結果 ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream()); output.writeObject(result); }).start(); } } public static <T> T refer (Class<T> interfaceClass, String host, int port) throws Exception { return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[] {interfaceClass}, new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable { Socket socket = new Socket(host, port); //指定 provider 的 ip 和端口 ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream()); output.write(method.getName()); //傳方法名 output.writeObject(method.getParameterTypes()); //傳參數類型 output.writeObject(arguments); //傳參數值 ObjectInputStream input = new ObjectInputStream(socket.getInputStream()); Object result = input.readObject(); //讀取結果 return result; } }); } }
好了,這個 RPC 框架就這樣好了,是否是很簡單?就是調用者傳遞了方法名、參數類型和參數值,提供者接收到這樣參數以後調用對於的方法返回結果就行了!這就是遠程過程調用,咱們來看看如何使用:後端
//服務提供者只須要暴露出接口 AobingService service = new AobingServiceImpl (); AobingRpcFramework.export(service, 2333); //服務調用者只須要設置依賴 AobingService service = AobingRpcFramework.refer(AobingService.class, "127.0.0.1", 2333); service.hello();
這個示例,簡單明瞭:設計模式
- 生產者:會一直去消費socket中的數據,若是沒有的話,就會一直阻塞住,當socket中有數據時,阻塞放開,獲取方法名和參數信息,而後執行類中的方法,並將結果寫入socket。
- 消費者:其實就是搞了一個代理,當調用service.hello()時,就會觸發該代理,這個代理其實就是初始化socket,而後類名和方法寫入socket,而後等待服務端返回數據,最後取出數據,而後直接返回。
- 說明:這裏只是一個RPC框架,真正的RPC其實還包括數據序列化和反序列化的過程,而後生產者和消費者的交互,可使HTTP,也能夠是其它方式,不必定須要咱們直接操做Socket。
Dubbo基礎
Dubbo 是一個分佈式服務框架,致力於提供高性能和透明化的 RPC 遠程服務調用方案,以及 SOA 服務治理方案。簡單的說,Dubbo 就是個服務框架,說白了就是個遠程服務調用的分佈式框架。緩存
Dubbo 是阿里巴巴 2011年開源的一個基於 Java 的 RPC 框架,中間沉寂了一段時間,不過其餘一些企業還在用 Dubbo 並本身作了擴展,好比噹噹網的 Dubbox,還有網易考拉的 Dubbok。可是在 2017 年阿里巴巴又重啓了對 Dubbo 維護。在 2017 年榮獲了開源中國 2017 最受歡迎的中國開源軟件 Top 3。在 2018 年和 Dubbox 進行了合併,而且進入 Apache 孵化器,在 2019 年畢業正式成爲 Apache 頂級項目。網絡
目前 Dubbo 社區主力維護的是 2.6.x 和 2.7.x 兩大版本,2.6.x 版本主要是 bug 修復和少許功能加強爲準,是穩定版本。而 2.7.x 是主要開發版本,更新和新增新的 feature 和優化,而且 2.7.5 版本的發佈被 Dubbo 認爲是里程碑式的版本發佈。它實現了面向接口的代理 RPC 調用,而且能夠配合 ZooKeeper 等組件實現服務註冊和發現功能,而且擁有負載均衡、容錯機制等。多線程
這幅圖簡單解釋一下:架構
一些注意的點:併發
- 首先註冊中心和監控中心是可選的,你能夠不要監控,也不要註冊中心,直接在配置文件裏面寫而後提供方和消費方直連。
- 就算註冊中心和監控中心宕機了也不會影響到已經正常運行的提供者和消費者,由於消費者有本地緩存提供者的信息。
總的而言 Dubbo 分爲三層,若是每一層再細分下去,一共有十層:
大的三層分別爲 Business(業務層)、RPC 層、Remoting,而且還分爲 API 層和 SPI 層。而分 API 層和 SPI 層這是 Dubbo 成功的一點,採用微內核設計+SPI擴展,使得有特殊需求的接入方能夠自定義擴展,作定製的二次開發。
SPI(Service Provider Interface),是 JDK 內置的一個服務發現機制,它使得接口和具體實現徹底解耦。咱們只聲明接口,具體的實現類在配置中選擇。
我們再來看看每一層都是幹嗎的:
生產者和消費者的調用過程以下:
提煉一下:初始化服務拿到服務信息 -> 構造數據請求 -> 經過負載均衡選取機器節點 -> 處理統計信息 -> 序列化數據 -> 請求發送給下游
提煉一下:接受請求 -> 反序列化數據 -> 扔入線程池 -> 找到Exporter -> 過濾請求 -> 經過Invoker執行 -> 反序列化結果 -> 返回請求
下面簡單講述一下Dubbo和Spring Cloud的區別,不過在講述二者區別以前,咱們先簡單瞭解一下Spring Cloud。
Spring Cloud簡述
Spring Cloud 基於 Spring Boot,爲微服務體系開發中的架構問題,提供了一整套的解決方案——服務註冊與發現,服務消費,服務保護與熔斷,網關,分佈式調用追蹤,分佈式配置管理等。
Spring Boot 是 Spring 的一套快速配置腳手架,使用默認大於配置的理念,用於快速開發單個微服務。
核心功能:
流程:
Dubbo vs Spring Cloud
優勢:
缺點:
優勢:
缺點:
Dubbo 專一 RPC 和服務治理,Spring Cloud 則是一個微服務架構生態。
使用 Dubbo 構建的微服務架構就像組裝電腦,各環節咱們的選擇自由度很高,可是最終結果頗有可能由於一條內存質量不行就點不亮了,老是讓人不怎麼放心,可是若是你是一名高手,那這些都不是問題;而 Spring Cloud 就像品牌機,在 Spring Source 的整合下,作了大量的兼容性測試,保證了機器擁有更高的穩定性,可是若是要在使用非原裝組件外的東西,就須要對其基礎有足夠的瞭解。
關於 Dubbo 和 Spring Cloud 的相關概念和對比,上面已經敘述的很清楚了,我我的比較傾向於 Spring Cloud,緣由就是真正的微服務框架、提供整套的組件支持、使用簡單方便、強大的社區支持等等,另外,由於考慮到 .NET/.NET Core 的兼容處理,RPC 並不能很好的實現跨語言(須要藉助跨語言庫,好比 gRPC、Thrift,但由於 Dubbo 自己就是「gRPC」,在 Dubbo 之上再包一層 gRPC,有點重複封裝了),而 HTTP REST 自己就是支持跨語言實現,因此,Spring Cloud 這一點仍是很是好的(Dubbox 也支持,但性能相比要差一些)。
但凡事無絕對,每件事物有好的地方也有很差的地方,總的來講,Dubbo 和 Spring Cloud 的主要不一樣體如今兩個方面:服務調用方式不一樣和專一點不一樣(生態不一樣)。
後記這篇文章,其實主要是對Dubbo有一個總體的認識,而後初步瞭解Dubbo和Spring Cloud二者的區別,由於網上常常會把它們兩拿來比較。
整篇文章都是概念性的東西,可是對於咱們理解Dubbo又很是重要,能夠只能做爲入門篇,我目前也是先對Java技術棧的技術,先總體初步瞭解,後續會選擇幾個方向再深刻學習。
一直想整理出一份完美的面試寶典,可是時間上一直騰不開,這套一千多道面試題寶典,結合今年金三銀四各類大廠面試題,以及 GitHub 上 star 數超 30K+ 的文檔整理出來的,我上傳之後,毫無心外的短短半個小時點贊量就達到了 13k,說實話仍是有點難以想象的。
內容涵蓋:Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、Redis、MySQL、Spring、SpringBoot、SpringCloud、RabbitMQ、Kafka、Linux等技術棧(485頁)
內容涵蓋:Java基礎、JVM、高併發、多線程、分佈式、設計模式、Spring全家桶、Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、MongoDB、Redis、MySQL、RabbitMQ、Kafka、Linux、Netty、Tomcat、數據庫、雲計算等
因爲篇幅限制,詳解資料太全面,細節內容太多,因此只把部分知識點截圖出來粗略的介紹,每一個小節點裏面都有更細化的內容!
須要的小夥伴,能夠一鍵三連,點擊這裏獲取免費領取方式!