帶你手寫基於 Spring 的可插拔式 RPC 框架(二)總體結構

前言

上一篇文章中咱們已經知道了什麼是 RPC 框架和爲何要作一個 RPC 框架了,這一章咱們來從宏觀上分析,怎麼來實現一個 RPC 框架,這個框架都有那些模塊以及這些模塊的做用。java

整體設計

在咱們的整個框架裏比較重要的幾個模塊:
rpc-procotol: 既然是可插拔是框架,咱們須要支持選擇底層協議,這部分是通訊協議相關的模塊。
rpc-spring: 咱們的框架是基於 spring 開發的,這個模塊是將咱們的一些功能和 spring 整合起來,好比自動注入代理 bean,啓動服務端 server 等等。
rpc-register: 註冊中心模塊,負責服務發現和容錯。
rpc-monitor: 將註冊中心的信息顯示在網頁上。
rpc-consumer: 消費端模塊,用於測試。
rpc-provider: 服務端模塊,用於測試。git

  1. 註冊中心模塊
    對於註冊中心來講,能夠選擇 zookeeper 和 redis,咱們只實現了 zookeeper,redis 但願有能力的同窗能夠在 github 上完善。
    咱們在使用 RPC 框架時,服務提供者和服務消費者都須要把本身註冊進去,服務消費者能夠將服務提供者的信息緩存到本地,經過註冊節點刪除的回調方法來去掉不可用的服務。
    註冊中心代理了咱們寫 http 請求時手動寫地址的功能,幫咱們自動找到可用的服務。
  2. 網絡協議模塊
    服務消費端須要使用接口代理類的 invoke 方法將請求發給服務提供者的 RPC server(雙方已經創建好了鏈接),RPC server 在死循環中一直等待接受請求,收到請求後調用本地的接口實現類進行處理,最後返回結
    果給服務調用端,這樣就完成了一個 RPC 服務調用的過程。
    RPC 底層網絡通訊協議包括三個實現,netty 實現的客戶端和服務端,http + Tomcat 實現的客戶端和服務端,最後時 Socket 實現的客戶端和服務端(性能比較低,編程練習使用)。
  3. 整合 Spring 模塊
    咱們整個框架是和 Spring 整合在一塊兒的,咱們在 Spring 中自定義的一些註解(相似與 Dubbo),自動爲接口成代理類並注入到了 Spring 容器中,在代碼中使用 @Autowired 自動注入便可使用。RPC server 的啓動也要依靠 Spring 來幫咱們完成。
  4. 監控模塊
    經過這個模塊能夠查看全部服務的狀態以及接口調用的相關信息。
  5. 測試模塊
    rpc-provider 和 rpc-consumer 都是測試類,方便於咱們對代碼進行測試。

效果展現

咱們先提早來看看最後最後的效果,首先說明,性能表現測試根據不一樣的機器和不一樣的網絡環境可能會有所不一樣,下面的測試結果是基於我本身的機器的。 個人電腦最多起 2000 個併發線程,多了就 OOM 了,在公司的電腦嘗試過起 10000 個併發線程,沒有任何問題,下面看 2000 個併發線程的表現。github

測試類redis

public static void main(String[] args) throws Exception {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("rpc.xml");
        //並行度10000
        int parallel = 2000;

        //開始計時
        long a1 = System.currentTimeMillis();

        CountDownLatch signal = new CountDownLatch(1);
        CountDownLatch finish = new CountDownLatch(parallel);

        for (int index = 0; index < parallel; index++) {
            CalcParallelRequestThread client = new CalcParallelRequestThread(signal, finish, index,applicationContext);
            new Thread(client).start();
        }

        //n個併發線程瞬間發起請求操做
        signal.countDown();
        finish.await();

        long a2 = System.currentTimeMillis();

        String tip = String.format("RPC調用總共耗時: [%s] 毫秒", a2 - a1);
        System.out.println(tip);

    }

2000 併發 1秒多,仍是比較快的。感興趣的能夠試試在本身的電腦起 1w 或者 10w 加線程測試一下。spring

相關文章
相關標籤/搜索