0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

RPC的機(jī)制的誕生和基礎(chǔ)概念

馬哥Linux運(yùn)維 ? 來源:馬哥Linux運(yùn)維 ? 2024-03-11 10:06 ? 次閱讀

【摘要】 Rpc基本概念RPC(Remote Procedure Call)遠(yuǎn)程過程調(diào)用,是一種通過網(wǎng)絡(luò)從遠(yuǎn)程計(jì)算機(jī)程序上請求服務(wù),而不需要了解底層網(wǎng)絡(luò)技術(shù)的協(xié)議,簡單的理解是一個節(jié)點(diǎn)請求另一個節(jié)點(diǎn)提供的服務(wù)。RPC只是一套協(xié)議,基于這套協(xié)議規(guī)范來實(shí)現(xiàn)的框架都可以稱為 RPC 框架,比較典型的有 有阿里巴巴的 Dubbo、Google 的 gRPC、Facebook 的 Thrift 和 Twitt...

Rpc基本概念

RPC(Remote Procedure Call)遠(yuǎn)程過程調(diào)用,是一種通過網(wǎng)絡(luò)從遠(yuǎn)程計(jì)算機(jī)程序上請求服務(wù),而不需要了解底層網(wǎng)絡(luò)技術(shù)的協(xié)議,簡單的理解是一個節(jié)點(diǎn)請求另一個節(jié)點(diǎn)提供的服務(wù)。RPC只是一套協(xié)議,基于這套協(xié)議規(guī)范來實(shí)現(xiàn)的框架都可以稱為 RPC 框架,比較典型的有 有阿里巴巴的 Dubbo、Google 的 gRPC、Facebook 的 Thrift 和 Twitter 的 Finagle 等。

RPC 機(jī)制和實(shí)現(xiàn)過程

RPC 是遠(yuǎn)程過程調(diào)用的方式之一,涉及調(diào)用方和被調(diào)用方兩個進(jìn)程的交互。因?yàn)?RPC 提供類似于本地方法調(diào)用的形式,所以對于調(diào)用方來說,調(diào)用 RPC 方法和調(diào)用本地方法并沒有明顯區(qū)別。

RPC的機(jī)制的誕生和基礎(chǔ)概念

1984 年,Birrell 和 Nelson 在 ACM Transactions on Computer Systems 期刊上發(fā)表了名為“Implementing remote procedure calls”的論文,該文對 RPC 的機(jī)制做了經(jīng)典的詮釋:

RPC 遠(yuǎn)程過程調(diào)用是指計(jì)算機(jī) A 上的進(jìn)程,調(diào)用另外一臺計(jì)算機(jī) B 上的進(jìn)程的方法。其中A 上面的調(diào)用進(jìn)程被掛起,而 B 上面的被調(diào)用進(jìn)程開始執(zhí)行對應(yīng)方法,并將結(jié)果返回給 A,計(jì)算機(jī) A 接收到返回值后,調(diào)用進(jìn)程繼續(xù)執(zhí)行。

發(fā)起 RPC 的進(jìn)程通過參數(shù)等方式將信息傳送給被調(diào)用方,然后被調(diào)用方處理結(jié)束后,再通過返回值將信息傳遞給調(diào)用方。這一過程對于開發(fā)人員來說是透明的,開發(fā)人員一般也無須知道雙方底層是如何進(jìn)行消息通信和信息傳遞的,這樣可以讓業(yè)務(wù)開發(fā)人員更專注于業(yè)務(wù)開發(fā),而非底層細(xì)節(jié)。

RPC 讓程序之間的遠(yuǎn)程過程調(diào)用具有與本地調(diào)用類似的形式。比如說某個程序需要讀取某個文件的數(shù)據(jù),開發(fā)人員會在代碼中執(zhí)行 read 系統(tǒng)調(diào)用來獲取數(shù)據(jù)。

當(dāng) read 實(shí)際是本地調(diào)用時(shí),read 函數(shù)由鏈接器從依賴庫中提取出來,接著鏈接器會將它鏈接到該程序中。雖然 read 中執(zhí)行了特殊的系統(tǒng)調(diào)用,但它本身依然是通過將參數(shù)壓入堆棧的常規(guī)方式調(diào)用的,調(diào)用方并不知道 read 函數(shù)的具體實(shí)現(xiàn)和行為。

當(dāng) read 實(shí)際是一個遠(yuǎn)程過程時(shí)(比如調(diào)用遠(yuǎn)程文件服務(wù)器提供的方法),調(diào)用方程序中需要引入 read 的接口定義,稱為客戶端存根(client-stub)。遠(yuǎn)程過程 read 的客戶端存根與本地方法的 read 函數(shù)類似,都執(zhí)行了本地函數(shù)調(diào)用。不同的是它底層實(shí)現(xiàn)上不是進(jìn)行操作系統(tǒng)調(diào)用讀取本地文件來提供數(shù)據(jù),而是將參數(shù)打包成網(wǎng)絡(luò)消息,并將此網(wǎng)絡(luò)消息發(fā)送到遠(yuǎn)程服務(wù)器,交由遠(yuǎn)程服務(wù)執(zhí)行對應(yīng)的方法,在發(fā)送完調(diào)用請求后,客戶端存根隨即阻塞,直到收到服務(wù)器發(fā)回的響應(yīng)消息為止。

下圖展示了遠(yuǎn)程方法調(diào)用過程中的客戶端和服務(wù)端各個階段的操作。

469a3e84-dec9-11ee-a297-92fbcf53809c.png

總結(jié)下RPC執(zhí)行步驟:

調(diào)用客戶端句柄,執(zhí)行傳遞參數(shù)。

調(diào)用本地系統(tǒng)內(nèi)核發(fā)送網(wǎng)絡(luò)消息。

消息傳遞到遠(yuǎn)程主機(jī),就是被調(diào)用的服務(wù)端。

服務(wù)端句柄得到消息并解析消息。

服務(wù)端執(zhí)行被調(diào)用方法,并將執(zhí)行完畢的結(jié)果返回給服務(wù)器句柄。

服務(wù)器句柄返回結(jié)果,并調(diào)用遠(yuǎn)程系統(tǒng)內(nèi)核。

消息經(jīng)過網(wǎng)絡(luò)傳遞給客戶端。

客戶端接受數(shù)據(jù)。

安裝gRPC和Protobuf

gRPC由google開發(fā),是一款語言中立、平臺中立、開源的遠(yuǎn)程過程調(diào)用系統(tǒng)
gRPC客戶端和服務(wù)端可以在多種環(huán)境中運(yùn)行和交互,例如用java寫一個服務(wù)端,可以用go語言寫客戶端調(diào)用
在gRPC中,我們可以一次性的在一個 proto文件中定義服務(wù)并使用任意的支持gRPC的語言去實(shí)現(xiàn)客戶端和服務(wù)端,整個過程操作變得簡單,就像調(diào)用本地函數(shù)一樣。

通過 proto生成服務(wù)端代碼,也就是服務(wù)端的骨架,提供低層通信抽象
通過 proto生成客戶端代碼,也就是客戶端的存根,隱藏了不同語言的差異,提供抽象的通信方式,就像調(diào)用本地函數(shù)一樣。

安裝

go getgithub.com/golang/protobuf/proto

go getgoogle.golang.org/grpc(無法使用,用如下命令代替)

git clonehttps://github.com/grpc/grpc-go.git$GOPATH/src/google.golang.org/grpc

git clonehttps://github.com/golang/net.git$GOPATH/src/golang.org/x/net

git clonehttps://github.com/golang/text.git$GOPATH/src/golang.org/x/text

go get -ugithub.com/golang/protobuf/{proto,protoc-gen-go}

git clonehttps://github.com/google/go-genproto.git$GOPATH/src/google.golang.org/genproto

cd $GOPATH/src/

go installgoogle.golang.org/grpc

go getgithub.com/golang/protobuf/protoc-gen-go

上面安裝好后,會在GOPATH/bin下生成protoc-gen-go.exe

但還需要一個protoc.exe,windows平臺編譯受限,很難自己手動編譯,直接去網(wǎng)站下載一個,地址:https://github.com/protocolbuffers/protobuf/releases/tag/v3.9.0,同樣放在GOPATH/bin下

proto 服務(wù)定義

gRPC 使用protocol buffer 來定義服務(wù)接口,protocol buffer和 XML、JSON一樣是一種結(jié)構(gòu)化數(shù)據(jù)序列化的可擴(kuò)展存儲結(jié)構(gòu),protocol buffer是一種語言中立,結(jié)構(gòu)簡單高效,比XML更小更簡單,可以通過特殊的插件自動生成代碼來讀寫操作這個數(shù)據(jù)結(jié)構(gòu)。

import "myproject/other_protos.proto";// 導(dǎo)入其他 proto文件
syntax = "proto3"; // 指定proto版本
package hello;     // 指定默認(rèn)包名

// 指定golang包名
option go_package = "hello";

message SearchRequest 
{
  required string query = 1;// 必須賦值字段
  optional int32 page_number = 2 [default = 10];// 可選字段
  repeated int32 result_per_page = 3;// 可重復(fù)字段 
}

message SearchResponse 
{
  message Result // 嵌套定義
  {
    required string url = 1;
    optional string title = 2;
    repeated string snippets = 3;
  }
  repeated Result result = 1;
}

message SomeOtherMessage 
{
  optional SearchResponse.Result result = 1;// 使用其他消息的定義
}

service List{// 定義gRPC服務(wù)接口
rpc getList(SearchRequest) returns (SearchResponse);
}
// 插件自動生成gRPC骨架和存根
protoc --go_out=plugins=grpc: ./ *.proto

后面需要實(shí)現(xiàn)服務(wù)端具體的邏輯就行,然后注冊到gRPC服務(wù)器
客戶端在調(diào)用遠(yuǎn)程方法時(shí)會使用阻塞式存根,所以gRPC主要使用同步的方式通信,在建立連接后,可以使用流的方式操作。
客戶端編排為protocol buffer的格式,服務(wù)端再解排執(zhí)行,以HTTP2 傳輸

gRPC 優(yōu)勢

更高效的進(jìn)程通信:使用基于protocol buffer在Http2 中以二進(jìn)制協(xié)議通信,而不是JSON、XML文本格式

簡單定義的服務(wù)接口、易擴(kuò)展

強(qiáng)類型、跨語言

一元RPC、服務(wù)端流、客戶端流、雙工流

gRPC入門

簡單使用

protocol buffer

syntax = "proto3";
package hello;
// 第一個分割參數(shù),輸出路徑;第二個設(shè)置生成類的包路徑

option go_package = "./proto/hello";
// 設(shè)置服務(wù)名稱
service Greeter {
  // 設(shè)置方法
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// 請求信息用戶名.
message HelloRequest {
  string name = 1;
}

// 響應(yīng)信息
message HelloReply {
  string message = 1;
}

服務(wù)端

package main

import (
"context"
"flag"
"fmt"
"log"
"net"

"google.golang.org/grpc"
pb "mygrpc/proto/hello"
)

var (
port = flag.Int("port", 50051, "The server port")
)

type server struct {
pb.UnimplementedGreeterServer
}

func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
log.Printf("Received: %v", in.GetName())
return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
}

func main() {
flag.Parse()
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
// 開啟rpc
s := grpc.NewServer()
// 注冊服務(wù)
pb.RegisterGreeterServer(s, &server{})
log.Printf("server listening at %v", lis.Addr())
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}

客戶端

package main

import (
"context"
"flag"
"log"
"time"

"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
pb "mygrpc/proto/hello" // 引入編譯生成的包
)

const (
defaultName = "world"
)

var (
addr = flag.String("addr", "localhost:50051", "the address to connect to")
name = flag.String("name", defaultName, "Name to greet")
)

func main() {
flag.Parse()
// 與服務(wù)建立連接.
conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
// 創(chuàng)建指定服務(wù)的客戶端
c := pb.NewGreeterClient(conn)

// 連接服務(wù)器并打印出其響應(yīng)。
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
// 調(diào)用指定方法
r, err := c.SayHello(ctx, &pb.HelloRequest{Name: *name})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.GetMessage())
}

客戶端連接gRPC服務(wù)器以后,就可以像調(diào)用本地函數(shù)一樣操作遠(yuǎn)程服務(wù)器。

審核編輯:黃飛

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 計(jì)算機(jī)
    +關(guān)注

    關(guān)注

    19

    文章

    7286

    瀏覽量

    87516
  • 服務(wù)器
    +關(guān)注

    關(guān)注

    12

    文章

    8842

    瀏覽量

    84945
  • JAVA
    +關(guān)注

    關(guān)注

    19

    文章

    2946

    瀏覽量

    104362
  • RPC
    RPC
    +關(guān)注

    關(guān)注

    0

    文章

    110

    瀏覽量

    11483

原文標(biāo)題:RPC簡介和grpc的使用

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    HarmonyOS跨進(jìn)程通信—IPC與RPC通信開發(fā)

    一、IPC與RPC通信概述 基本概念 IPC(Inter-Process Communication)與RPC(Remote Procedure Call)用于實(shí)現(xiàn)跨進(jìn)程通信,不同的是前者
    的頭像 發(fā)表于 02-02 17:47 ?1160次閱讀
    HarmonyOS跨進(jìn)程通信—IPC與<b class='flag-5'>RPC</b>通信開發(fā)

    聊聊Dubbo - Dubbo可擴(kuò)展機(jī)制實(shí)戰(zhàn)

    摘要: 在Dubbo的官網(wǎng)上,Dubbo描述自己是一個高性能的RPC框架。今天我想聊聊Dubbo的另一個很棒的特性, 就是它的可擴(kuò)展性。1. Dubbo的擴(kuò)展機(jī)制在Dubbo的官網(wǎng)上,Dubbo描述
    發(fā)表于 06-04 17:33

    RPC的結(jié)構(gòu)原理是什么?

    遠(yuǎn)程過程調(diào)用(RPC)是一個協(xié)議,程序可以使用這個協(xié)議請求網(wǎng)絡(luò)中另一臺計(jì)算機(jī)上某程序的服務(wù)而不需知道網(wǎng)絡(luò)細(xì)節(jié)。(過程調(diào)用有時(shí)也稱作函數(shù)調(diào)用,或子例行程序調(diào)用。)RPC使用client/server模型。請求程序是client,而服務(wù)提供程序則為server。
    發(fā)表于 10-12 10:43

    直連設(shè)備怎么rpc雙向控制

    Thing***oard提供非常強(qiáng)大的可視化部件,除了圖表、地圖車聯(lián)網(wǎng)外,還有控制部件,通過mqtt rpc可以輕松實(shí)現(xiàn)平臺 -- 設(shè)備端 設(shè)備到平臺雙向數(shù)據(jù)傳輸及控制。Thingboard 連接
    發(fā)表于 07-12 06:55

    RPC是什么

    RPC是什么?RabbitMQ又是什么?
    發(fā)表于 10-08 09:24

    【學(xué)習(xí)打卡】OpenHarmony的RPC連接介紹

    常規(guī)過程調(diào)用返回一樣。注意:RPC特別適合客戶端-服務(wù)器(例如查詢-響應(yīng))交互,其中控制流在調(diào)用者和被調(diào)用者之間交替。從概念上講,客戶端和服務(wù)器不會同時(shí)執(zhí)行。相反,執(zhí)行線程從調(diào)用者跳轉(zhuǎn)到被調(diào)用者,然后再
    發(fā)表于 07-28 18:13

    什么是RPC

    什么是RPC   英文原義:Remote Procedure Call Protocol 中文釋義:(RFC-1831)遠(yuǎn)過程調(diào)用協(xié)議 注  解:一種通過
    發(fā)表于 02-23 11:48 ?902次閱讀

    什么是RPC?為什么需要RPC?

    首先要明確一點(diǎn):RPC可以用HTTP協(xié)議實(shí)現(xiàn),并且用HTTP是建立在 TCP 之上最廣泛使用的 RPC,但是互聯(lián)網(wǎng)公司往往用自己的私有協(xié)議,比如鵝廠的JCE協(xié)議,私有協(xié)議不具備通用性為什么還要用呢?因?yàn)橄啾扔贖TTP協(xié)議,RPC
    的頭像 發(fā)表于 04-16 12:49 ?1.5w次閱讀
    什么是<b class='flag-5'>RPC</b>?為什么需要<b class='flag-5'>RPC</b>?

    RPC的JAVA實(shí)現(xiàn)工作原理

    在傳統(tǒng)的開發(fā)模式中,我們通常將系統(tǒng)的各個服務(wù)部署在單臺機(jī)器,隨著服務(wù)的擴(kuò)展,這種方式已經(jīng)完全無法滿足系統(tǒng)大規(guī)模的擴(kuò)展需要,分布式系統(tǒng)由此誕生,在分布式系統(tǒng)中,最重要就是各個服務(wù)之間的 RPC 調(diào)用。
    的頭像 發(fā)表于 05-05 23:39 ?3447次閱讀
    <b class='flag-5'>RPC</b>的JAVA實(shí)現(xiàn)工作原理

    為什么需要RPC接口

    論復(fù)雜度,RPC框架肯定是高于簡單的HTTP接口的。但毋庸置疑,HTTP接口由于受限于HTTP協(xié)議,需要帶HTTP請求頭,導(dǎo)致傳輸起來效率或者說安全性不如RPC。
    發(fā)表于 07-13 17:46 ?2575次閱讀

    解析操作系統(tǒng)的概念、結(jié)構(gòu)和機(jī)制

    全面。解析操作系統(tǒng)的概念、結(jié)構(gòu)和機(jī)制。
    發(fā)表于 03-26 14:19 ?8次下載

    OpenDaylight中的RPC &amp; Notification是什么

    我們將介紹RPC和Notification,并從進(jìn)程內(nèi)外的通信開始,著重介紹遠(yuǎn)程過程調(diào)用和發(fā)布-訂閱機(jī)制,然后分析MD-SAL的通信交互過程。
    的頭像 發(fā)表于 02-14 15:15 ?871次閱讀
    OpenDaylight中的<b class='flag-5'>RPC</b> &amp; Notification是什么

    RPC 和 REST 區(qū)別是什么

    01. 既 REST ,何 RPC ? 在 OpenStack 里的進(jìn)程間通信方式主要有兩種,一種是基于HTTP協(xié)議的RESTFul API方式,另一種則是RPC調(diào)用。 那么這兩種方式在應(yīng)用場景上有
    的頭像 發(fā)表于 11-02 10:40 ?2881次閱讀
    <b class='flag-5'>RPC</b> 和 REST 區(qū)別是什么

    鴻蒙開發(fā)通信與連接:ohos.rpc RPC通信

    本模塊提供進(jìn)程間通信能力,包括設(shè)備內(nèi)的進(jìn)程間通信(IPC)和設(shè)備間的進(jìn)程間通信(RPC),前者基于Binder驅(qū)動,后者基于軟總線驅(qū)動。
    的頭像 發(fā)表于 06-21 09:40 ?396次閱讀
    鴻蒙開發(fā)通信與連接:ohos.<b class='flag-5'>rpc</b> <b class='flag-5'>RPC</b>通信

    Dubbo源碼淺析(一)—RPC框架與Dubbo

    一、什么是RPC 1.1 RPC概念 RPC,Remote Procedure Call 即遠(yuǎn)程過程調(diào)用,與之相對的是本地服務(wù)調(diào)用,即LPC(Local Procedure Call)
    的頭像 發(fā)表于 08-16 15:18 ?466次閱讀
    Dubbo源碼淺析(一)—<b class='flag-5'>RPC</b>框架與Dubbo