色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
电子发烧友
开通电子发烧友VIP会员 尊享10大特权
海量资料免费下载
精品直播免费看
优质内容免费畅学
课程9折专享价
創(chuàng)作中心

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

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

深入理解RPC自定義網(wǎng)絡協(xié)議

Linux愛好者 ? 來源:srpc ? 作者:李穎欣 ? 2022-06-12 15:00 ? 次閱讀

本文來自srpc作者李穎欣,在此基礎(chǔ)上略做改動。

只要涉及到網(wǎng)絡通信,必然涉及到網(wǎng)絡協(xié)議,應用層也是一樣。在應用層最標準和常用的就是HTTP協(xié)議。但在很多性能要求較高的場景各大企業(yè)內(nèi)部也會自定義的 RPC 協(xié)議。舉個例子,就是相當于各個省不但用官方普通話,還都有自己的方言,RPC就相當于是一個方言。

RPC的全稱是Remote Procedure Call,翻譯過來就是遠程過程調(diào)用。但這個名字起的一點都不好,過分強調(diào)了和LPC(本地過程調(diào)用)的對比。沒有突出出來 RPC 本身涉及到的一些技術(shù)特點。

我們今天來從三個角度和大家聊聊 RPC。

  • RPC是什么:通過和HTTP的對比來幫大家了解RPC
  • RPC有什么:介紹了RPC用到的用戶樁代碼、IDL序列化、壓縮、協(xié)議、通信等技術(shù)點
  • RPC生命周期:詳細探討RPC從請求發(fā)出到收到返回的全過程

今天的講解會結(jié)合基于C++實現(xiàn)的開源項目SRPC。SRPC整體代碼風格簡潔、架構(gòu)層次精巧,整體約1萬行代碼,非常適合用來學習RPC架構(gòu):https://github.com/sogou/srpc

一. RPC是什么

RPC可以分為兩部分:用戶調(diào)用接口+具體網(wǎng)絡協(xié)議。前者為開發(fā)者需要關(guān)心的,后者由框架來實現(xiàn)。

1. 用戶調(diào)用接口

舉個例子,我們定義一個函數(shù),我們希望函數(shù)如果輸入為“Hello World”的話,輸出給一個“OK”,那么這個函數(shù)是個本地調(diào)用。如果一個遠程服務收到“Hello World”可以給我們返回一個“OK”,那么這是一個遠程調(diào)用。我們會和服務約定好遠程調(diào)用的函數(shù)名。因此,我們的用戶接口就是:輸入輸出遠程函數(shù)名,比如用SRPC開發(fā)的話,client端的代碼會長這樣:

intmain()
{
Example::SRPCClientclient(IP,PORT);
EchoRequestreq;//用戶自定義的請求結(jié)構(gòu)
EchoResponseresp;//用戶自定義的回復結(jié)構(gòu)

req.set_message("HelloWorld");
client.Echo(&req,&resp,NULL);//調(diào)用遠程函數(shù)名為Echo
return0;
}

2. 具體網(wǎng)絡協(xié)議

這是框架來實現(xiàn)的,把開發(fā)者要發(fā)出和接收的內(nèi)容以某種應用層協(xié)議打包進行網(wǎng)絡收發(fā)。這里可以和HTTP進行一個明顯的對比:

  • RPC是一種自定義網(wǎng)絡協(xié)議,由具體框架來定,比如SRPC里支持的RPC協(xié)議有:SRPC / thrift / BRPC / tRPC,并且也是tRPC協(xié)議目前唯一的開源實現(xiàn),我們拿其中的SogouRPC-std protocol為例給大家看看RPC協(xié)議的大概樣子:

    87a3b7c8-e2f1-11ec-ba43-dac502259ad0.png

  • HTTP也是一種網(wǎng)絡協(xié)議,但包的內(nèi)容是固定的,必須是:請求行 + 請求頭 + 請求體;

    87d96e5e-e2f1-11ec-ba43-dac502259ad0.png

3. 進一步思考

上圖對應的顏色,所實現(xiàn)的功能是類似的。我們想一想,為什么大家都長差不多呢?

這里就需要搞清楚,我們想要實現(xiàn)用戶接口,需要怎么做?最重要需要支持以下三個功能:

  • 定位要調(diào)用的服務;
  • 把完整的消息切下來;
  • 讓我們的消息向前/向后兼容;

這樣既可以讓消息內(nèi)保證一定的靈活性,又可以方便拿下一塊數(shù)據(jù),去調(diào)用用戶想要的服務。

我們用一個表格來看一下HTTP和RPC分別是怎么解決的:

定位要調(diào)用的服務 消息長度 消息前后兼容
HTTP URL header里Content-Length body里自己解決
RPC 指定Service和Method名 協(xié)議header里自行約定 交給具體IDL

因此,大家都會需要類似的結(jié)構(gòu)去組裝一條完整的用戶請求,而第三部分的body只要框架支持,RPC協(xié)議和HTTP是可以互通的!因此開發(fā)者完全可以根據(jù)自己的業(yè)務需求進行選型,接下來我們看一下RPC的層次架構(gòu),就可以明白為什么不同RPC框架之間的互通、以及RPC和HTTP協(xié)議又是如何做到互通的。

二、 RPC有什么

我們可以借SRPC的架構(gòu),看一下RPC框架從用戶到系統(tǒng)都有哪些層次,以及SRPC目前所橫向支持的功能是什么:

  • 用戶代碼(client的發(fā)送函數(shù)/server的函數(shù)實現(xiàn))
  • IDL序列化(protobuf/thrift serialization)
  • 數(shù)據(jù)組織(protobuf/thrift/json)
  • 壓縮(none/gzip/zlib/snappy/lz4)
  • 協(xié)議(Sogou-std/Baidu-std/Thrift-framed/TRPC)
  • 通信(TCP/HTTP)

我們先關(guān)注以下三個層級:

8811d578-e2f1-11ec-ba43-dac502259ad0.png

如圖從左到右,是用戶接觸的最多到最少的層次。IDL層會根據(jù)開發(fā)者定義的請求/回復結(jié)構(gòu)進行代碼生成,目前小伙伴們用得比較多的是protobuf和thrift,而剛才說到的用戶接口和前后兼容問題,都是IDL層來解決的。SRPC對于這兩個IDL的用戶接口實現(xiàn)方式是:

  • thrift:IDL純手工解析,用戶使用srpc是不需要鏈thrift的庫的 !!!
  • protobuf:service的定義部分純手工解析

中間那列是具體的網(wǎng)絡協(xié)議,而各RPC能互通,就是因為大家實現(xiàn)了對方的“語言”,因此可以協(xié)議互通。

而RPC作為和HTTP并列的層次,第二列和第三列理論上是可以兩兩結(jié)合的,只需要第二列的具體RPC協(xié)議在發(fā)送時,把HTTP相關(guān)的內(nèi)容進行特化,不要按照自己的協(xié)議去發(fā),而按照HTTP需要的形式去發(fā),就可以實現(xiàn)RPC與HTTP互通。

三、 RPC的生命周期

到此我們可以通過SRPC看一下,把request通過method發(fā)送出去并處理response再回來的整件事情是怎么做的:

8835057a-e2f1-11ec-ba43-dac502259ad0.png

根據(jù)上圖,可以更清楚地看到剛才提及的各個層級,其中壓縮層、序列化層、協(xié)議層其實是互相解耦打通的,在SRPC代碼上實現(xiàn)得非常統(tǒng)一,橫向增加任何一種壓縮算法或IDL或協(xié)議都不需要也不應該改動現(xiàn)有的代碼,才是一個精美的架構(gòu)~

我們一直在說生成代碼,到底有什么用呢?圖中可以得知,生成代碼是銜接用戶調(diào)用接口和框架代碼的橋梁,這里以一個最簡單的protobuf自定義協(xié)議為例:example.proto

syntax="proto3";//這里proto2和proto3都可以

messageEchoRequest
{
stringmessage=1;
};

messageEchoResponse
{
stringmessage=1;
};

serviceExample
{
rpcEcho(EchoRequest)returns(EchoResponse);
};

我們定義好了請求、回復、遠程服務的函數(shù)名,通過以下命令就可以生成出接口代碼example.srpc.h

protocexample.proto--cpp_out=./--proto_path=./
srpc_generatorprotobuf./example.proto./

我們會發(fā)現(xiàn),同時還會生成出server.pb_skeleton.ccclient.pb_skeleton.cc,這是為了方便開發(fā)者的兩個空文件。我們繼續(xù)一窺究竟,看看生成代碼到底可以實現(xiàn)什么功能:

//SERVER代碼
classService:publicsrpc::RPCService
{
public:
//用戶需要自行派生實現(xiàn)這個函數(shù),與剛才pb生成的是對應的
virtualvoidEcho(EchoRequest*request,EchoResponse*response,
srpc::RPCContext*ctx)=0;
};

//CLIENT代碼
usingEchoDone=std::function<void(EchoResponse*,srpc::RPCContext*)>;

classSRPCClient:publicsrpc::SRPCClient
{
public:
//異步接口
voidEcho(constEchoRequest*req,EchoDonedone);
//同步接口
voidEcho(constEchoRequest*req,EchoResponse*resp,srpc::RPCSyncContext*sync_ctx);
//半同步接口
WFFuture<std::pair>async_Echo(constEchoRequest*req);
};

作為一個高性能RPC框架,SRPC生成的client代碼中包括了:同步半同步異步接口,文章開頭展示的是一個同步接口的做法。

而server的接口就更簡單了,作為一個服務端,我們要做的就是收到請求->處理邏輯->返回回復,而這個時候,框架已經(jīng)把剛才提到的網(wǎng)絡收發(fā)、解壓縮、反序列化等都給做好了,然后通過生成代碼調(diào)用到用戶實現(xiàn)的派生service類的函數(shù)邏輯中。

由于一種協(xié)議定義了一種client/server,因此其實我們同樣可以得到的server類型有第二部分提到過的若干種:SRPCServer/SRPCHttpServer/BRPCServer/TRPCServer/ThriftServer/...

四、 一個完整的server例子

最后我們用一個完整的server例子,來看一下用戶調(diào)用接口的使用方式,以及如何跨協(xié)議使用HTTP作為client進行調(diào)用。剛才提到,srpc_generator在生成接口的同時,也會自動生成空的用戶代碼,我們這里打開server.pb_skeleton.cc直接改兩行,即可run起來:

#include"example.srpc.h"
#include"workflow/WFFacilities.h"

usingnamespacesrpc;
staticWFFacilities::WaitGroupwait_group(1);

voidsig_handler(intsigno)
{
wait_group.done();
}

classExampleServiceImpl:publicExample::Service
{
public:

voidEcho(EchoRequest*request,EchoResponse*response,srpc::RPCContext*ctx)override
{
response->set_message("OK");//具體邏輯在這里添加,我們簡單地回復一個OK
}
};

intmain()
{
unsignedshortport=80;//因為要啟動Http服務
SRPCHttpServerserver;//我們需要構(gòu)造一個SRPCHttpServer

ExampleServiceImplexample_impl;
server.add_service(&example_impl);

server.start(port);
wait_group.wait();
server.stop();
return0;
}

只要安裝了srpc和workflow,linux下即可通過以下命令編譯出可執(zhí)行文件:

g++-oserverserver.pb_skeleton.ccexample.pb.cc-std=c++11-lsrpc

接下來是激動人心的時刻了,我們用人手一個的curl來發(fā)起一個HTTP請求:

curl-i127.0.0.1:80/Example/Echo-H'Content-Type:application/json'-d'{message:"HelloWorld"}'

886f7bce-e2f1-11ec-ba43-dac502259ad0.png

五、 解鎖更多

通過這篇文章,相信我們可以清晰地了解到RPC的接口長什么樣,也可以通過與HTTP協(xié)議互通來理解協(xié)議層次,更重要的是可以知道具體縱向的每個層次及橫向?qū)Ρ任覀兂R姷拿糠N使用模式都有哪些。但其實,RPC還可以做的事情還有很多,包括內(nèi)部各層次的解耦合設計、框架層的功能埋點、外部服務集群的對接等等:

88b5009a-e2f1-11ec-ba43-dac502259ad0.png

如果小伙伴對更多功能感興趣,歡迎點擊閱讀原文,到Github圍觀,進一步了解。

原文標題:一文搞懂 RPC 的基本原理和層次架構(gòu)

文章出處:【微信公眾號:Linux愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 網(wǎng)絡協(xié)議
    +關(guān)注

    關(guān)注

    3

    文章

    273

    瀏覽量

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

    關(guān)注

    0

    文章

    111

    瀏覽量

    11791
  • C++
    C++
    +關(guān)注

    關(guān)注

    22

    文章

    2117

    瀏覽量

    74765

原文標題:一文搞懂 RPC 的基本原理和層次架構(gòu)

文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 0人收藏

    評論

    相關(guān)推薦
    熱點推薦

    如何手搓一個自定義RPC 遠程過程調(diào)用框架

    是一種常用的技術(shù),能夠簡化客戶端與服務器之間的交互。本文將介紹如何基于Netty(網(wǎng)絡編程框架)實現(xiàn)一個自定義的簡單的RPC框架。 首先簡單介紹一下RPC 主要特點: 1.1、
    的頭像 發(fā)表于 07-22 12:17 ?1144次閱讀
    如何手搓一個<b class='flag-5'>自定義</b>的<b class='flag-5'>RPC</b> 遠程過程調(diào)用框架

    深入理解Android

    深入理解Android
    發(fā)表于 08-20 15:30

    深入理解Linux網(wǎng)絡技術(shù)內(nèi)幕》(EN)

    深入理解Linux網(wǎng)絡技術(shù)內(nèi)幕》(EN)
    發(fā)表于 02-06 15:17

    基于自定義協(xié)議網(wǎng)絡地理信息系統(tǒng)

    探索基于自定義協(xié)議開發(fā)網(wǎng)絡地理信息系統(tǒng)的方法。自定義一套工作于TCP/IP應用層的協(xié)議,基于該協(xié)議
    發(fā)表于 04-18 10:03 ?34次下載

    基于TCP/I 的自定義協(xié)議棧的研究與開發(fā)

    本文主要介紹了如何開發(fā)基于TCP/IP 協(xié)議網(wǎng)絡編程的自定義通訊協(xié)議,在QNX,Linux 和Windows 三種不同的操作系統(tǒng)平臺下實現(xiàn)多節(jié)點間的互相通訊。測試結(jié)果表明,該
    發(fā)表于 05-30 09:16 ?14次下載

    1602自定義字符

    1602液晶能夠顯示自定義字符,能夠根據(jù)讀者的具體情況顯示自定義字符。
    發(fā)表于 01-20 15:43 ?1次下載

    深入理解Android網(wǎng)絡編程

    深入理解Android網(wǎng)絡編程
    發(fā)表于 03-19 11:26 ?1次下載

    如何更加深入理解I2C總線、協(xié)議及應用

    更加深入理解I2C總線、協(xié)議及應用
    的頭像 發(fā)表于 03-20 09:29 ?3552次閱讀
    如何更加<b class='flag-5'>深入理解</b>I2C總線、<b class='flag-5'>協(xié)議</b>及應用

    C#與STM32自定義通信協(xié)議

    C#與STM32自定義通信協(xié)議功能:1.可通過C#上位機對多臺STM32下位機進行控制2.自定義上位機與下位機通信協(xié)議
    發(fā)表于 12-24 18:59 ?37次下載
    C#與STM32<b class='flag-5'>自定義</b>通信<b class='flag-5'>協(xié)議</b>

    自定義視圖組件教程案例

    自定義組件 1.自定義組件-particles(粒子效果) 2.自定義組件- pulse(脈沖button效果) 3.自定義組件-progress(progress效果) 4.
    發(fā)表于 04-08 10:48 ?14次下載

    ArkUI如何自定義彈窗(eTS)

    自定義彈窗其實也是比較簡單的,通過CustomDialogController類就可以顯示自定義彈窗。
    的頭像 發(fā)表于 08-31 08:24 ?2540次閱讀

    ESP32上的自定義UART協(xié)議開源

    電子發(fā)燒友網(wǎng)站提供《ESP32上的自定義UART協(xié)議開源.zip》資料免費下載
    發(fā)表于 02-13 16:38 ?4次下載
    ESP32上的<b class='flag-5'>自定義</b>UART<b class='flag-5'>協(xié)議</b>開源

    自定義神經(jīng)網(wǎng)絡對象識別開源分享

    電子發(fā)燒友網(wǎng)站提供《自定義神經(jīng)網(wǎng)絡對象識別開源分享.zip》資料免費下載
    發(fā)表于 06-16 09:27 ?0次下載
    <b class='flag-5'>自定義</b>神經(jīng)<b class='flag-5'>網(wǎng)絡</b>對象識別開源分享

    自定義算子開發(fā)

    一個完整的自定義算子應用過程包括注冊算子、算子實現(xiàn)、含自定義算子模型轉(zhuǎn)換和運行含自定義op模型四個階段。在大多數(shù)情況下,您的模型應該可以通過使用hb_mapper工具完成轉(zhuǎn)換并順利部署到地平線芯片上……
    的頭像 發(fā)表于 04-07 16:11 ?3184次閱讀
    <b class='flag-5'>自定義</b>算子開發(fā)

    labview超快自定義控件制作和普通自定義控件制作

    labview超快自定義控件制作和普通自定義控件制作
    發(fā)表于 08-21 10:32 ?13次下載
    主站蜘蛛池模板: 国产亚洲高清视频 | 亚洲永久免费视频 | 色狠狠色狠狠综合天天 | av无码在线日本天堂 | 久艾草在线精品视频在线观看 | 亚洲日本激情 | 亚欧洲乱码视频一二三区 | 青娱乐国产精品视频 | 无人影院在线播放视频 | 色99久久久久高潮综合影院 | 久久精品免费观看久久 | 99视频久九热精品 | 成人免费在线视频 | 竹菊精品久久久久久久99蜜桃 | 俄罗斯雏妓的BBB孩交 | 日韩精品真人荷官无码 | 永久免费看A片无码网站四虎 | 同时被两个男人轮流舔 | 精品夜夜澡人妻无码AV蜜桃 | 亚洲一区在线观看视频 | 办公室沙发口爆12P 办公室日本肉丝OL在线 | 免费在线观看一区 | 国产人妻777人伦精品HD | 国产精品点击进入在线影院高清 | 精品一区二区三区高清免费观看 | 无码国产欧美日韩精品 | 日本久久精品视频 | 日本邪恶少女漫画大全 | 快穿女主有名器的H纯肉黄暴拉文 | 大肥女ass樱桃 | 久久天堂网| 色欲人妻无码AV精品一区二区 | 国产三级在线观看免费 | 亚洲人成网77777色在线播放 | 国产这里有精品 | 久久精品伊人 | 男人都懂www深夜免费网站 | 嗯好舒服嗯好大好猛好爽 | 久久久久99精品成人片三人毛片 | 99久久精品国产免费 | 健身房被教练啪到腿软H |

    電子發(fā)燒友

    中國電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會員交流學習
    • 獲取您個性化的科技前沿技術(shù)信息
    • 參加活動獲取豐厚的禮品