gRPC詳解

gRPC是什么腕窥?

gRPC是什么可以用官網(wǎng)的一句話來概括

A high-performance, open-source universal RPC framework

所謂RPC(remote procedure call 遠程過程調(diào)用)框架實際是提供了一套機制闸英,使得應(yīng)用程序之間可以進行通信,而且也遵從server/client模型慈俯。使用的時候客戶端調(diào)用server端提供的接口就像是調(diào)用本地的函數(shù)一樣咱枉。如下圖所示就是一個典型的RPC結(jié)構(gòu)圖。

RPC通信

gRPC有什么好處以及在什么場景下需要用gRPC

既然是server/client模型觉增,那么我們直接用restful api不是也可以滿足嗎彻亲,為什么還需要RPC呢孕锄?下面我們就來看看RPC到底有哪些優(yōu)勢

gRPC vs. Restful API

gRPC和restful API都提供了一套通信機制吮廉,用于server/client模型通信,而且它們都使用http作為底層的傳輸協(xié)議(嚴(yán)格地說, gRPC使用的http2.0畸肆,而restful api則不一定)宦芦。不過gRPC還是有些特有的優(yōu)勢,如下:

  • gRPC可以通過protobuf來定義接口轴脐,從而可以有更加嚴(yán)格的接口約束條件调卑。關(guān)于protobuf可以參見筆者之前的小文Google Protobuf簡明教程
  • 另外,通過protobuf可以將數(shù)據(jù)序列化為二進制編碼大咱,這會大幅減少需要傳輸?shù)臄?shù)據(jù)量令野,從而大幅提高性能。
  • gRPC可以方便地支持流式通信(理論上通過http2.0就可以使用streaming模式, 但是通常web服務(wù)的restful api似乎很少這么用徽级,通常的流式數(shù)據(jù)應(yīng)用如視頻流,一般都會使用專門的協(xié)議如HLS聊浅,RTMP等餐抢,這些就不是我們通常web服務(wù)了,而是有專門的服務(wù)器應(yīng)用低匙。)

使用場景

  • 需要對接口進行嚴(yán)格約束的情況旷痕,比如我們提供了一個公共的服務(wù),很多人顽冶,甚至公司外部的人也可以訪問這個服務(wù)欺抗,這時對于接口我們希望有更加嚴(yán)格的約束,我們不希望客戶端給我們傳遞任意的數(shù)據(jù)强重,尤其是考慮到安全性的因素绞呈,我們通常需要對接口進行更加嚴(yán)格的約束。這時gRPC就可以通過protobuf來提供嚴(yán)格的接口約束间景。
  • 對于性能有更高的要求時佃声。有時我們的服務(wù)需要傳遞大量的數(shù)據(jù),而又希望不影響我們的性能倘要,這個時候也可以考慮gRPC服務(wù)圾亏,因為通過protobuf我們可以將數(shù)據(jù)壓縮編碼轉(zhuǎn)化為二進制格式,通常傳遞的數(shù)據(jù)量要小得多封拧,而且通過http2我們可以實現(xiàn)異步的請求志鹃,從而大大提高了通信效率。

但是泽西,通常我們不會去單獨使用gRPC曹铃,而是將gRPC作為一個部件進行使用,這是因為在生產(chǎn)環(huán)境尝苇,我們面對大并發(fā)的情況下铛只,需要使用分布式系統(tǒng)來去處理埠胖,而gRPC并沒有提供分布式系統(tǒng)相關(guān)的一些必要組件。而且淳玩,真正的線上服務(wù)還需要提供包括負載均衡直撤,限流熔斷,監(jiān)控報警蜕着,服務(wù)注冊和發(fā)現(xiàn)等等必要的組件谋竖。不過,這就不屬于本篇文章討論的主題了承匣,我們還是先繼續(xù)看下如何使用gRPC蓖乘。

gRPC HelloWorld實例詳解

gRPC的使用通常包括如下幾個步驟:

  1. 通過protobuf來定義接口和數(shù)據(jù)類型
  2. 編寫gRPC server端代碼
  3. 編寫gRPC client端代碼
    下面來通過一個實例來詳細講解上述的三步。
    下邊的hello world實例完成之后韧骗,其目錄結(jié)果如下:


    project helloworld

定義接口和數(shù)據(jù)類型

  • 通過protobuf定義接口和數(shù)據(jù)類型
syntax = "proto3";

package rpc_package;

// define a service
service HelloWorldService {
    // define the interface and data type
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// define the data type of request
message HelloRequest {
    string name = 1;
}

// define the data type of response
message HelloReply {
    string message = 1;
}
  • 使用gRPC protobuf生成工具生成對應(yīng)語言的庫函數(shù)
python -m grpc_tools.protoc -I=./protos --python_out=./rpc_package --grpc_python_out=./rpc_package ./protos/user_info.proto

這個指令會自動生成rpc_package文件夾中的helloworld_pb2.pyhelloworld_pb2_grpc.py嘉抒,但是不會自動生成__init__.py文件,需要我們手動添加

關(guān)于protobuf的詳細解釋請參考Google Protobuf簡明教程

gRPC server端代碼

#!/usr/bin/env python
# -*-coding: utf-8 -*-

from concurrent import futures
import grpc
import logging
import time

from rpc_package.helloworld_pb2_grpc import add_HelloWorldServiceServicer_to_server, \ 
    HelloWorldServiceServicer
from rpc_package.helloworld_pb2 import HelloRequest, HelloReply


class Hello(HelloWorldServiceServicer):

    # 這里實現(xiàn)我們定義的接口
    def SayHello(self, request, context):
        return HelloReply(message='Hello, %s!' % request.name)


def serve():
    # 這里通過thread pool來并發(fā)處理server的任務(wù)
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))

    # 將對應(yīng)的任務(wù)處理函數(shù)添加到rpc server中
    add_HelloWorldServiceServicer_to_server(Hello(), server)

    # 這里使用的非安全接口袍暴,世界gRPC支持TLS/SSL安全連接些侍,以及各種鑒權(quán)機制
    server.add_insecure_port('[::]:50000')
    server.start()
    try:
        while True:
            time.sleep(60 * 60 * 24)
    except KeyboardInterrupt:
        server.stop(0)


if __name__ == "__main__":
    logging.basicConfig()
    serve()

gRPC client端代碼

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function
import logging

import grpc
from rpc_package.helloworld_pb2 import HelloRequest, HelloReply
from rpc_package.helloworld_pb2_grpc import HelloWorldServiceStub

def run():
    # 使用with語法保證channel自動close
    with grpc.insecure_channel('localhost:50000') as channel:
        # 客戶端通過stub來實現(xiàn)rpc通信
        stub = HelloWorldServiceStub(channel)

        # 客戶端必須使用定義好的類型,這里是HelloRequest類型
        response = stub.SayHello(HelloRequest(name='eric'))
    print ("hello client received: " + response.message)

if __name__ == "__main__":
    logging.basicConfig()
    run()

演示

先執(zhí)行server端代碼

python hello_server.py

接著執(zhí)行client端代碼如下:

?  grpc_test python hello_client.py
hello client received: Hello, eric!

References

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末政模,一起剝皮案震驚了整個濱河市岗宣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌淋样,老刑警劉巖耗式,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異趁猴,居然都是意外死亡刊咳,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門躲叼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芦缰,“玉大人,你說我怎么就攤上這事枫慷∪美伲” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵或听,是天一觀的道長探孝。 經(jīng)常有香客問我,道長誉裆,這世上最難降的妖魔是什么顿颅? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮足丢,結(jié)果婚禮上粱腻,老公的妹妹穿的比我還像新娘庇配。我一直安慰自己,他們只是感情好绍些,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布捞慌。 她就那樣靜靜地躺著,像睡著了一般柬批。 火紅的嫁衣襯著肌膚如雪啸澡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天氮帐,我揣著相機與錄音嗅虏,去河邊找鬼。 笑死上沐,一個胖子當(dāng)著我的面吹牛皮服,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播参咙,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼冰更,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了昂勒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤舟铜,失蹤者是張志新(化名)和其女友劉穎戈盈,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谆刨,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡塘娶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了痊夭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片刁岸。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖她我,靈堂內(nèi)的尸體忽然破棺而出虹曙,到底是詐尸還是另有隱情,我是刑警寧澤番舆,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布酝碳,位于F島的核電站,受9級特大地震影響恨狈,放射性物質(zhì)發(fā)生泄漏疏哗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一禾怠、第九天 我趴在偏房一處隱蔽的房頂上張望返奉。 院中可真熱鬧贝搁,春花似錦、人聲如沸芽偏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哮针。三九已至关面,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間十厢,已是汗流浹背等太。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蛮放,地道東北人缩抡。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像包颁,于是被迫代替她去往敵國和親瞻想。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容

  • 原文連接: 一文了解RPC以及gRPC基于Golang和Java的簡單實現(xiàn) 一:什么是RPC 簡介:RPC:Re...
    賈順閱讀 8,871評論 2 12
  • 轉(zhuǎn)自:http://blog.csdn.net/kesonyk/article/details/50924489 ...
    晴天哥_王志閱讀 24,772評論 2 38
  • 正則表達式模塊 import re 匹配流程 正則表達式的寫法 () 表示分組娩嚼。例如:(\d\d\d)-(\d\d...
    又雙叒叕茍了一天閱讀 592評論 0 0
  • 我們從最初級的一個層面去講就是能量蘑险。物質(zhì)能量的對應(yīng),物質(zhì)的能量對應(yīng)當(dāng)中岳悟,比方說我曾經(jīng)跟一個人說過佃迄,我說人對視一眼,...
    薩克西閱讀 1,117評論 1 7
  • 2008年贵少,費城棒球隊Philly's贏得國聯(lián)冠軍后呵俏,整個城區(qū)歇斯底里地瘋狂了好幾天,徹夜地尖叫鳴笛與被游行擠癱瘓...
    Sisi_1204閱讀 1,060評論 1 50