目錄:
帶你手寫基於 Spring 的可插拔式 RPC 框架(一)介紹
帶你手寫基於 Spring 的可插拔式 RPC 框架(二)整體結構
帶你手寫基於 Spring 的可插拔式 RPC 框架(三)通訊協議模組
帶你手寫基於 Spring 的可插拔式 RPC 框架(四)代理類的注入與服務啟動
帶你手寫基於 Spring 的可插拔式 RPC 框架(五)註冊中心
原始碼在第五篇部落格的末尾
概述
首先這篇文章是要帶大家來實現一個框架,聽到框架大家可能會覺得非常高大上,其實這和我們平時寫業務員程式碼沒什麼區別,但是框架是要給別人使用的,所以我們要換位思考,怎麼才能讓別人用著舒服,怎麼樣才能讓我們的框架效能優異。通過自己寫一個框架,我們能學到的有很多,能讓我們脫離 CURD,在更高的層面上去思考。
目的
寫這個框架最主要的目的是要讓大家瞭解整個框架的設計思想和用到的技術,並不是讓大家關注程式碼,當然我實現的程式碼一定不是完美的,還有很多需要改進的地方,希望大家不吝賜教,一起進步。
提前準備
如果把所有細節給大家講清楚,那完全可以出一本書了。我們的文章當然也會將細節,不過希望大家有一些知識儲備,這樣我們才能重點去關注設計思想,瞭解如何去設計這個 RPC 框架,把自己想不通的地方給想明白了。
提前學習的知識
- Netty 框架,希望大家對這個框架有個基礎的瞭解,能夠編寫簡單的客戶端服務端通訊的 Demo,如果沒學過可以臨時補一下。傳送門->Netty
- 動態代理,其實不僅僅是動態代理,基本的設計模式是每個程式設計師必備的,而動態代理使用的又非常廣泛,大家至少要對動態代理的概念有所瞭解。
- Dubbo 的使用經歷,如果你用過 Dubbo 的話對於理解我們接下來的文章有很大的幫助。
解決了什麼問題
這個框架到底解決了什麼問題?我們在什麼場景下需要使用這個框架那?我們先來了解一個概念。
微服務架構
微服務架構旨在將原來傳統的單體的 web 程式進行解耦,按功能進行劃分,將原來的大應用拆分成一個一個小的服務。這樣很大程度上提高了整個系統的可伸縮行,可以高效的應對各種各樣的併發和資料壓力。
來看官方定義:
1、一些由獨立的服務共同組成系統
2、單獨部署,跑在自己的程式中
3、每個服務為獨立的業務開發
4、分散式管理
5、非常強調隔離性
微服務已經成為目前網際網路公司的標配了,使用微服務時我們需要思考一個問題,原來是在一個程式內,現在被拆分成不同的程式,而且很有可能部署在不同的伺服器上。那麼服務之間如何通訊那?
RPC
RPC 是一種遠端呼叫協議,他可以高效準確的完成服務之間的相互呼叫,而且最重要的是使用者不需要關心 RPC 協議的底層實現,網路傳輸使用 Http,Netty,還是 Socket 都可以。
有人可能會有疑問,我用 http 請求,裡面寫上目標的 ip,埠,加上引數不是也能呼叫服務並且返回資料嗎?為什麼要引入 RPC 這個概念那?
如果你能思考到這,說明你已經很厲害了,懂得在使用工具時思考為什麼。
對於直接使用 http 請求來說,適合介面較少,服務之間相互呼叫不多的情況,而且需要指定地址,埠等等資訊。優點就是簡單直接,但是無法應對高併發以及複雜服務互動的情況。
RPC 就是為了解決上面的問題而生的,首先使用者只需要呼叫服務即可,連線和傳送資料交給底層協議去完成,另外對於高併發支援非常好,另外提供服務治理,註冊中心等功能。適合大型網站,服務複雜,高併發的情況。
從一個點看 RPC 的架構
使用過 Dubbo 等 RPC 框架的應該知道,我們可以像呼叫本地方法一樣呼叫另一個伺服器上的服務,有的人可能不明白這句話時什麼意思,程式碼演示一下。
UserService 是另一個伺服器上的服務,我們可以像呼叫本地方法一樣呼叫,不用管底層協議,不夠用管 UserService 在哪個伺服器上。
UserService userService = ProxyFactory.getProxy(UserService.class);
User user = userService.get("11112");
那麼我們是如何把在另外一個伺服器上的服務拿到我們本地來的那?有人看上面的 ProxyFactory 可能就已經猜出來了,使用的是動態代理,我們在本地獲取到了介面的代理類,在 invoke 方法中將引數傳給對應的服務,服務端在接收到資料後,使用反射呼叫對應的實現類,完成處理後將結果返回給呼叫端。
如果你不明白上面的解釋,我們用一張圖來解釋這個過程:
簡單點說,RPC 幫我們把對應的請求發過去,服務端有一個伺服器一直接收這種請求,收到資料後呼叫服務對應的處理方法處理後返回給呼叫端。