目錄
RPC原理
造轮子
框架使用" >框架使用
首頁 常見問題 手寫RPC框架,真不是為了裝13!

手寫RPC框架,真不是為了裝13!

Aug 16, 2023 pm 05:01 PM
rpc框架

面試中,很容易被面試官問到:

如何設計一個RPC框架

你可能沒被問到過,可能是運氣好,也可能是你還沒到這個等級。通常月薪20k以上,基本上都會問一些設計性的題目。

站在面試官角度:問這類題目,總比一個八股文強,這裡面會牽涉到很多技術點。例如:設計模式、通訊協定、動態代理、虛擬化、執行緒池等知識。

好吧,不扯遠了,我們開始聊今天的話題。

RPC全程為Remote procedure call 遠端過程調用,這幾個字很多人可能並不是特別的理解,再簡單的說就是:

像調用本地方法一樣呼叫遠端服務

例如,下面一個案例:一個使用者操作服務:

public interface UserService{
    String findUserNameById(Integer userId);
}
@Service
public class UserServiceImpl implements UserService{
    String findUserNameById(Integer userId){
        //查数据或查缓存获取到用户名
        return "田哥"
    }
}
登入後複製

現在一個controller裡想呼叫UserServiceImpl的findUserNameById方法取得使用者名稱。

@RestController
public class UserController{
    @Resource
    private UserService userService;
    
    @GetMapping("/test")
    public String test(){
        return userService.findUserNameById(1);
    }
}
登入後複製

假設UserController、UserServiceImpl、UserService三個類別都在同一個專案裡,controller想呼叫findUserNameById方法是非常簡單的。

但是,如果controller是另一個項目,也想像上面那樣調用(細微的不同,感覺還是一樣),這時候我們就可以用到了RPC框架。

1、需要把介面UserService放在一個單獨專案裡,我們通常稱之為api專案。

2、需要把UserServiceImpl放在一個單獨專案裡,我們通常稱之為叫做provider專案。

3、controller嘛,透過是web之類的(consumer)專案裡

4、把api打成jar包,然後consumer專案、provider專案都引用它。

市面上的RPC框架,比如說:Dubbo (阿里)、Thrift(FaceBook)、gRpc(Google)、brpc (百度)等都在不同重點去解決最初的目的,有的想極致完美,有的追求極致性能,有的偏向極致簡單。

RPC原理

回到前面我們說的像是呼叫本地一樣的呼叫遠端服務,到底需要哪些技術支撐呢?

  • 動態代理程式,因為我們consumer專案裡只有介面UserService定義,沒有實作類,想要呼叫一個介面的方法?那就只能搞個代理對象了。
  • 編解碼,也就是consumer需要把請求參數傳到provider去,網路傳輸過程先把我們的參數編碼,然後傳到provider, provider再對傳過來的參數進行解碼。
  • 網路通訊,跨進程一定會牽涉到網路通訊。
  • 網路傳輸協定,consumer和provider 對於來回的參數訊息,肯定得有個標準,你按照什麼樣的方式傳給我,不然我怎麼知道你想表達什麼。
  • 序列化與反序列化
  • #資料壓縮,在進行資料網路傳輸時,如果資料太大了,我們得考慮能不能對資料進行壓縮。
  • 註冊中心,如果provider 進行叢集部署(同樣服務部署多個機器上),這時候我們需要在consumer進行手動維護,如果量一旦大起來了,這工作量可想而知。
  • 動態感知服務上離線,如果provider 存在宕機或部署了新的節點,這時候consumer就需要知道哪些服務下線了,哪些服務上線了。
  • 動態路由,如果provider 進行叢集部署(同樣服務部署多個機器上),我們不可能讓consumer都落在同一個節點上,這樣資源無法充分利用了,古代皇帝的雨露均霑。動態路由那就會牽涉到各種各樣的演算法,例如隨機,輪詢,權重等。

為什麼需要註冊中心,我之前分享過:

美團面試:如何設計一個註冊中心?

#

造轮子

根据上面的这些原理,田哥也搞了一个RPC框架,命名为mink(一个动物的名称)。

--mink
----mink-rpc rpc基本功能
----mink-registry 服务注册与发现
----mink-spring 集成SpringBoot
登入後複製

然后,我们把mink-spring打成jar包,服务发布和服务引用都把这个jar给依赖进去。

手寫RPC框架,真不是為了裝13!

手寫RPC框架,真不是為了裝13!

手寫RPC框架,真不是為了裝13!


框架使用

上面,我们创造了轮子,下面,我们就来看如何使用。

手寫RPC框架,真不是為了裝13!

mink-demo就是一个Spring Boot项目,有三个module。

手寫RPC框架,真不是為了裝13!


我们把mink-api打成jar包,共consumer和provider使用。

也就是我们在consumer和provider都引入:

<dependency>
    <groupId>com.tian</groupId>
    <artifactId>mink-api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
登入後複製

下面,我们来看看provider端的代码:

<dependency>
   <groupId>com.tian</groupId>
   <artifactId>mink-spring</artifactId>
   <version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
   <groupId>com.tian</groupId>
   <artifactId>mink-api</artifactId>
   <version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter</artifactId>
   <version>2.5.4</version>
</dependency>
登入後複製

我们的mink框架,只需要引入mink-spring依赖即可。

接着就是properties的配置:

mink.rpc.servicePort=20880
mink.rpc.registryType=0
mink.rpc.registryAddress=127.0.0.1:2181
登入後複製

再来看看具体服务实现类:

package com.tian.service;

import com.tian.annotation.MinkService;

/**
 * @author tianwc  公众号:java后端技术全栈、面试专栏
 * @version 1.0.0
 * @description 用户服务
 * @createTime 2022年08月23日 18:16
 */
@MinkService
public class UserServiceImpl implements UserService {
    @Override
    public String findUserNameByiD(Integer id) {
        System.out.println("服务调用");
        return "tian";
    }
}
登入後複製

这一步,我们只需要在实现类上加上注解@MinkService即可。

最后就是项目启动类:

@ComponentScan(basePackages = {"com.tian.service","com.tian"})
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
登入後複製

我们启动项目(注册中心用的是zookeeper):

手寫RPC框架,真不是為了裝13!


从日志中可以看出,我们的服务已经成功注册到注册中心了。

下面,我们来看看consumer端代码。

首先来看看依赖:

<dependency>
   <groupId>com.tian</groupId>
   <artifactId>mink-spring</artifactId>
   <version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
   <groupId>com.tian</groupId>
   <artifactId>mink-api</artifactId>
   <version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter</artifactId>
   <version>2.5.4</version>
</dependency>

   org.springframework.boot
   spring-boot-starter-web
   2.5.4
登入後複製

这依赖也很简单,没什么好说的。

再来看看properties配置项:

mink.rpc.registryType=0
mink.rpc.registryAddress=127.0.0.1:2181

server.port=8090
登入後複製

是不是也很简单?

再来看看我们的controller代码:

package com.tian.controller;

import com.tian.annotation.MinkReference;
import com.tian.service.UserService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author tianwc  公众号:java后端技术全栈、面试专栏
 * @version 1.0.0
 * @description 消费端
 * @createTime 2022年08月23日 23:08
 */
@RestController
public class UserController {

    @MinkReference
    private UserService userService;

    @RequestMapping("/test")
    public String test() {
        return userService.findUserNameByiD(1);
    }
}
登入後複製

需要用到对应服务,只需要添加注解@MinkReference即可。

最后就是项目启动类,简单的不行。

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
登入後複製

启动日志:

手寫RPC框架,真不是為了裝13!

访问:http://localhost:8090/test

手寫RPC框架,真不是為了裝13!

成功!整个过程,非常轻松地集成mink框架并在业务代码中使用。

总结起来,其实就三步:

1、pom中添加依赖

2、properties文件中配置注册中心信息

3、使用的时候加上注解@MinkReference@MinkService即可

以上是手寫RPC框架,真不是為了裝13!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
威爾R.E.P.O.有交叉遊戲嗎?
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

手寫RPC框架,真不是為了裝13! 手寫RPC框架,真不是為了裝13! Aug 16, 2023 pm 05:01 PM

你可能沒有被問到過,可能是運氣好,也可能是你還沒到這個等級。通常月薪20k以上,基本上都會問一些設計性的題目。站在面試官角度:問這類題目,總比一個八股文強,這裡面會牽涉到很多技術點。例如:設計模式、通訊協定、動態代理、虛擬化、執行緒池等知識。

阿里面試官:你給我手寫個RPC框架看看 阿里面試官:你給我手寫個RPC框架看看 Aug 17, 2023 pm 04:24 PM

RPC 是一個電腦通訊協定。該協議允許運行於一台計算機的程序調用另一台計算機的子程序,而開發人員無需額外地為這個交互編程。

Go語言中的RPC框架原理與應用 Go語言中的RPC框架原理與應用 Jun 01, 2023 pm 03:01 PM

一、RPC框架的概念在分散式系統中,常常需要在不同的服務端和客戶端之間傳遞數據,RPC(RemoteProcedureCall)框架是一種常用的技術手段。 RPC框架允許應用程式透過遠端訊息傳遞呼叫另一個執行環境的函數或方法,從而使程式能夠在不同的電腦上運行。目前市面上有許多RPC框架,如Google的gRPC、Thrift、Hessian等,本文主要介

PHP中如何進行RPC框架的開發? PHP中如何進行RPC框架的開發? May 13, 2023 pm 03:22 PM

RPC(RemoteProcedureCall),是一種進程間通訊協議,它允許不同的進程在不同的實體機器上透過網路進行通訊和協作。 RPC框架越來越受到關注,因為它可以幫助開發者輕鬆實現分散式系統的開發。在本篇文章中,我們會一步一步介紹如何使用PHP進行RPC架構的開發。一、什麼是RPC框架? RPC框架就是一個用來實作遠端過程呼叫的框架。在基於RPC的

有哪些rpc框架 有哪些rpc框架 Aug 03, 2023 am 10:17 AM

rpc框架有:1、gRPC,由Google開發的高效能,開源的RPC框架;2、Apache Thrift,由Facebook開發和開源的跨語言RPC框架;3、Apache Dubbo,一款高性能,輕量級的RPC框架,適用於大規模分散式系統;4、Apache Axis2,一款基於Web服務標準的RPC框架;5、Spring Cloud,一套建構分散式系統的開源框架。

Go語言RPC框架橫評:表現、易用性、社群支持對比 Go語言RPC框架橫評:表現、易用性、社群支持對比 Feb 27, 2024 pm 09:12 PM

Go語言作為一種舉足輕重的現代程式語言,其在分散式系統開發的應用愈發廣泛。而在建構分散式系統時,RPC(遠端過程呼叫)框架的選擇往往是至關重要的。本文將對目前主流的Go語言RPC框架進行一次橫向評估,比較它們在效能、易用性和社群支援等方面的優缺點,並附上具體的程式碼範例。 1.效能比較在分散式系統中,效能往往是開發者關注的首要指標之一。以下是幾個主

如何在go語言中實現高並發的RPC框架 如何在go語言中實現高並發的RPC框架 Aug 05, 2023 pm 12:49 PM

如何在Go語言中實現高並發的RPC框架簡介:隨著互聯網的快速發展,高並發應用越來越受到關注。採用RPC(RemoteProcedureCall)框架是常見的解決方案。本文將介紹如何在Go語言中實現高並發的RPC框架,並且會附帶程式碼範例。 RPC框架簡介:RPC是一種通訊協議,它允許一個電腦程式呼叫另一個位址空間(通常位於遠端電腦上)的子程序,而不需

PHP7.0中的RPC框架有哪些? PHP7.0中的RPC框架有哪些? May 29, 2023 am 11:10 AM

隨著電腦技術的不斷發展,分散式系統已成為主流,而遠端過程呼叫(RPC)則是實現分散式系統的重要手段。 PHP作為一種流行的Web程式語言,也有著自己的RPC框架,其中在PHP7.0版本中引入了一些新的RPC框架。本文將介紹PHP7.0常見的RPC架構及其特點。 PHPRemoteProcedureCall(phpRPC)phpRPC是一款輕量級的RP