乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      來吧!手寫一個 RPC 框架。畢設(shè)/項目經(jīng)驗穩(wěn)了!

       鷹兔牛熊眼 2020-08-19

      guide-rpc-framework 是一個 一款基于 Netty+Kyro+Zookeeper 實現(xiàn)的自定義 RPC 框架。目前已經(jīng)開源,地址:https://github.com/Snailclimb/guide-rpc-framework (覺得不錯再 Star!),歡迎小伙伴們指導(dǎo)建議!

      如果 guide-rpc-framework 有任何需要改進和完善的地方,歡迎提交 PR/ISSUE ,和我一起完善!?( ′???` )比心

      前言

      雖說 RPC 的原理實際不難,但是,自己在實現(xiàn)的過程中自己也遇到了很多問題。guide-rpc-framework 目前只實現(xiàn)了 RPC 框架最基本的功能,一些可優(yōu)化點都在下面提到了,有興趣的小伙伴可以自行完善。

      通過這個簡易的輪子,你可以學(xué)到 RPC 的底層原理和原理以及各種 Java 編碼實踐的運用。

      你甚至可以把 guide-rpc-framework 當(dāng)做你的畢設(shè)/項目經(jīng)驗的選擇,這是非常不錯!對比其他求職者的項目經(jīng)驗都是各種系統(tǒng),造輪子肯定是更加能贏得面試官的青睞。

      如果你要將 guide-rpc-framework 當(dāng)做你的畢設(shè)/項目經(jīng)驗的話,我希望你一定要搞懂,而不是直接復(fù)制粘貼我的思想。你可以 fork 我的項目,然后進行優(yōu)化。如果你覺得的優(yōu)化是有價值的話,你可以提交 PR 給我,我會盡快處理。

      介紹

      guide-rpc-framework 是一款基于 Netty+Kyro+Zookeeper 實現(xiàn)的 RPC 框架。代碼注釋詳細,結(jié)構(gòu)清晰,并且集成了 Check Style 規(guī)范代碼結(jié)構(gòu),非常適合閱讀和學(xué)習(xí)。

      由于 Guide哥自身精力和能力有限,如果大家覺得有需要改進和完善的地方的話,歡迎 fork 本項目,然后 clone 到本地,在本地修改后提交 PR 給我,我會在第一時間 Review 你的代碼。

      我們先從一個基本的 RPC 框架設(shè)計思路說起!

      一個基本的 RPC 框架設(shè)計思路

      注意 :我們這里說的 RPC 框架指的是:可以讓客戶端直接調(diào)用服務(wù)端方法就像調(diào)用本地方法一樣簡單的框架,比如我前面介紹的 Dubbo、Motan、gRPC 這些。如果需要和 HTTP 協(xié)議打交道,解析和封裝 HTTP 請求和響應(yīng)。這類框架并不能算是“RPC 框架”,比如 Feign。

      一個最簡單的 RPC 框架使用示意圖如下圖所示,這也是 guide-rpc-framework 目前的架構(gòu) :

      img

      服務(wù)提供端 Server 向注冊中心注冊服務(wù),服務(wù)消費者 Client 通過注冊中心拿到服務(wù)相關(guān)信息,然后再通過網(wǎng)絡(luò)請求服務(wù)提供端 Server。

      作為 RPC 框架領(lǐng)域的佼佼者Dubbo的架構(gòu)如下圖所示,和我們上面畫的大體也是差不多的。

      img

      一般情況下, RPC 框架不僅要提供服務(wù)發(fā)現(xiàn)功能,還要提供負載均衡、容錯等功能,這樣的 RPC 框架才算真正合格的。

      簡單說一下設(shè)計一個最基本的 RPC 框架的思路:

      img
      1. 注冊中心 :注冊中心首先是要有的,推薦使用 Zookeeper。注冊中心負責(zé)服務(wù)地址的注冊與查找,相當(dāng)于目錄服務(wù)。服務(wù)端啟動的時候?qū)⒎?wù)名稱及其對應(yīng)的地址(ip+port)注冊到注冊中心,服務(wù)消費端根據(jù)服務(wù)名稱找到對應(yīng)的服務(wù)地址。有了服務(wù)地址之后,服務(wù)消費端就可以通過網(wǎng)絡(luò)請求服務(wù)端了。
      2. 網(wǎng)絡(luò)傳輸 :既然要調(diào)用遠程的方法就要發(fā)請求,請求中至少要包含你調(diào)用的類名、方法名以及相關(guān)參數(shù)吧!推薦基于 NIO 的 Netty 框架。
      3. 序列化 :既然涉及到網(wǎng)絡(luò)傳輸就一定涉及到序列化,你不可能直接使用 JDK 自帶的序列化吧!JDK 自帶的序列化效率低并且有安全漏洞。所以,你還要考慮使用哪種序列化協(xié)議,比較常用的有 hession2、kyro、protostuff。
      4. 動態(tài)代理 :另外,動態(tài)代理也是需要的。因為 RPC 的主要目的就是讓我們調(diào)用遠程方法像調(diào)用本地方法一樣簡單,使用動態(tài)代理可以屏蔽遠程方法調(diào)用的細節(jié)比如網(wǎng)絡(luò)傳輸。也就是說當(dāng)你調(diào)用遠程方法的時候,實際會通過代理對象來傳輸網(wǎng)絡(luò)請求,不然的話,怎么可能直接就調(diào)用到遠程方法呢?
      5. 負載均衡 :負載均衡也是需要的。為啥?舉個例子我們的系統(tǒng)中的某個服務(wù)的訪問量特別大,我們將這個服務(wù)部署在了多臺服務(wù)器上,當(dāng)客戶端發(fā)起請求的時候,多臺服務(wù)器都可以處理這個請求。那么,如何正確選擇處理該請求的服務(wù)器就很關(guān)鍵。假如,你就要一臺服務(wù)器來處理該服務(wù)的請求,那該服務(wù)部署在多臺服務(wù)器的意義就不復(fù)存在了。負載均衡就是為了避免單個服務(wù)器響應(yīng)同一請求,容易造成服務(wù)器宕機、崩潰等問題,我們從負載均衡的這四個字就能明顯感受到它的意義。
      6. ......

      項目基本情況和可優(yōu)化點

      為了循序漸進,最初的是時候,我是基于傳統(tǒng)的 BIO 的方式 Socket 進行網(wǎng)絡(luò)傳輸,然后利用 JDK 自帶的序列化機制 來實現(xiàn)這個 RPC 框架的。后面,我對原始版本進行了優(yōu)化,已完成的優(yōu)化點和可以完成的優(yōu)化點我都列在了下面 ??。

      為什么要把可優(yōu)化點列出來? 主要是想給那些希望優(yōu)化這個 RPC 框架的小伙伴一點思路。歡迎大家 fork 本倉庫,然后自己進行優(yōu)化。

      項目模塊概覽

      img

      運行項目

      導(dǎo)入項目

      fork 項目到自己的倉庫,然后克隆項目到自己的本地:git clone git@github.com:username/guide-rpc-framework.git,使用 IDEA 打開,等待項目初始化完成。

      初始化 git hooks

      這一步主要是為了在 commit 代碼之前,跑 Check Style,保證代碼格式?jīng)]問題,如果有問題的話就不能提交。

      以下演示的是 Mac/Linux 對應(yīng)的操作,Window 用戶需要手動將 config/git-hooks 目錄下的pre-commit 文件拷貝到 項目下的 .git/hooks/ 目錄。

      執(zhí)行下面這些命令:

      ?  guide-rpc-framework git:(master) ? chmod +x ./init.sh
      ?  guide-rpc-framework git:(master) ? ./init.sh

      init.sh 這個腳本的主要作用是將 git commit 鉤子拷貝到項目下的 .git/hooks/ 目錄,這樣你每次 commit 的時候就會執(zhí)行了。

      CheckStyle 插件下載和配置

      IntelliJ IDEA-> Preferences->Plugins->搜索下載 CheckStyle 插件,然后按照如下方式進行配置。

      CheckStyle 插件下載和配置

      配置完成之后,按照如下方式使用這個插件!

      插件使用方式

      下載運行 zookeeper

      這里使用 Docker 來下載安裝。

      下載:

      docker pull zookeeper:3.5.8

      運行:

      docker run -d --name zookeeper -p 2181:2181 zookeeper:3.5.8

      使用

      服務(wù)提供端

      實現(xiàn)接口:

      @Slf4j
      @RpcService(group = 'test1', version = 'version1')
      public class HelloServiceImpl implements HelloService {
          static {
              System.out.println('HelloServiceImpl被創(chuàng)建');
          }

          @Override
          public String hello(Hello hello) {
              log.info('HelloServiceImpl收到: {}.', hello.getMessage());
              String result = 'Hello description is ' + hello.getDescription();
              log.info('HelloServiceImpl返回: {}.', result);
              return result;
          }
      }
       
      @Slf4j
      public class HelloServiceImpl2 implements HelloService {

          static {
              System.out.println('HelloServiceImpl2被創(chuàng)建');
          }

          @Override
          public String hello(Hello hello) {
              log.info('HelloServiceImpl2收到: {}.', hello.getMessage());
              String result = 'Hello description is ' + hello.getDescription();
              log.info('HelloServiceImpl2返回: {}.', result);
              return result;
          }
      }

      發(fā)布服務(wù)(使用 Netty 進行傳輸):

      /**
       * Server: Automatic registration service via @RpcService annotation
       *
       * @author shuang.kou
       * @createTime 2020年05月10日 07:25:00
       */

      @RpcScan(basePackage = {'github.javaguide.serviceimpl'})
      public class NettyServerMain {
          public static void main(String[] args) {
              // Register service via annotation
              new AnnotationConfigApplicationContext(NettyServerMain.class);
              NettyServer nettyServer = new NettyServer();
              // Register service manually
              HelloService helloService2 = new HelloServiceImpl2();
              RpcServiceProperties rpcServiceProperties = RpcServiceProperties.builder()
                      .group('test2').version('version2').build();
              nettyServer.registerService(helloService2, rpcServiceProperties);
              nettyServer.start();
          }
      }

      服務(wù)消費端

      ClientTransport rpcClient = new NettyClientTransport();
      RpcServiceProperties rpcServiceProperties = RpcServiceProperties.builder()
        .group('test1').version('version1').build();
      RpcClientProxy rpcClientProxy = new RpcClientProxy(rpcClient, rpcServiceProperties);
      HelloService helloService = rpcClientProxy.getProxy(HelloService.class);
      String hello = helloService.hello(new Hello('111''222'));

      相關(guān)問題

      為什么要造這個輪子?Dubbo 不香么?

      寫這個 RPC 框架主要是為了通過造輪子的方式來學(xué)習(xí),檢驗自己對于自己所掌握的知識的運用。

      實現(xiàn)一個簡單的 RPC 框架實際是比較容易的,不過,相比于手寫 AOP 和 IoC 還是要難一點點,前提是你搞懂了 RPC 的基本原理。

      我之前從理論層面在我的知識星球分享過如何實現(xiàn)一個 RPC。不過理論層面的東西只是支撐,你看懂了理論可能只能糊弄住面試官。咱程序員這一行還是最需要動手能力,即使你是架構(gòu)師級別的人物。當(dāng)你動手去實踐某個東西,將理論付諸實踐的時候,你就會發(fā)現(xiàn)有很多坑等著你。

      大家在實際項目上還是要盡量少造輪子,有優(yōu)秀的框架之后盡量就去用,Dubbo 在各個方面做的都比較好和完善。

      如果我要自己寫的話,需要提前了解哪些知識

      Java :

      1. 動態(tài)代理機制;
      2. 序列化機制以及各種序列化框架的對比,比如 hession2、kyro、protostuff。
      3. 線程池的使用;
      4. CompletableFuture 的使用
      5. ......

      Netty :

      1. 使用 Netty 進行網(wǎng)絡(luò)傳輸;
      2. ByteBuf 介紹
      3. Netty 粘包拆包
      4. Netty 長連接和心跳機制

      Zookeeper :

      1. 基本概念;
      2. 數(shù)據(jù)結(jié)構(gòu);
      3. 如何使用 Netflix 公司開源的 zookeeper 客戶端框架 Curator 進行增刪改查;

      教程

      Guide 的星球已經(jīng)更新完了《從零開始手把手教你實現(xiàn)一個簡單的 RPC 框架》。

      公眾號“JavaGuide”后回復(fù) “星球”即可獲取星球?qū)賰?yōu)惠券。

      我的公眾號

      另外,加不加入純屬個人意愿,而且這個教程也沒講什么,你單看我寫的代碼應(yīng)該也可以搞懂。目前,星球已經(jīng)運營大半年多了,里面也沉淀了一些內(nèi)容,后面會提高入場價格。運營一個比較好的知識交流社區(qū)是我 2020 一直嘗試做好的事情。目前來看,我覺得做的還算可以,不過還有很多提高的余地(回答問題、活躍度以及精華主題數(shù)都是在所有星球里面非??壳暗模?/span>

      收費主要是為了提高準(zhǔn)入門檻,也算是對自己付出勞動的認(rèn)可。說實話,知識星球的那點收益對我來說是無足輕重的(星球抽了20%,拿到手還要扣稅一波,哈哈哈)。

      最后

      文章有幫助可以點個「在看」或「分享」,都是支持,我都喜歡!

      我是 Guide 哥,Java后端開發(fā),會一點前端知識,喜歡烹飪,自由的少年。一個三觀比主角還正的技術(shù)人。我們下期再見!

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多