自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

使用gRPC構(gòu)建實(shí)際的微服務(wù)

譯文
開(kāi)發(fā) 架構(gòu)
早期的微服務(wù)實(shí)現(xiàn)利用了代表性狀態(tài)傳輸(REST)架構(gòu)作為事實(shí)上的通信技術(shù)。然而,充分利用REST的服務(wù)常常適用于面向外部的服務(wù),這些服務(wù)直接暴露給消費(fèi)者。我們?cè)诒疚闹袑⒏钊氲亟榻B為什么gRPC是構(gòu)建微服務(wù)間通信的一種出色選擇。

【51CTO.com快譯】早期的微服務(wù)實(shí)現(xiàn)利用了代表性狀態(tài)傳輸(REST)架構(gòu)作為事實(shí)上的通信技術(shù)。然而,充分利用REST的服務(wù)常常適用于面向外部的服務(wù),這些服務(wù)直接暴露給消費(fèi)者。由于它們基于傳統(tǒng)的基于文本的消息傳遞(JSON、XML和CVS over HTTP等)――針對(duì)人類進(jìn)行了優(yōu)化,因此這些不是內(nèi)部服務(wù)間通信的理想選擇。

相反,使用一種基于文本的消息傳遞協(xié)議,我們可以利用針對(duì)服務(wù)間通信進(jìn)行優(yōu)化的二進(jìn)制協(xié)議。云原生計(jì)算基金會(huì)的gRPC(一種高性能的開(kāi)源通用遠(yuǎn)程過(guò)程調(diào)用框架)是服務(wù)間通信的理想選擇,因?yàn)樗褂脜f(xié)議緩沖區(qū)(protocol buffer)作為服務(wù)間通信的二進(jìn)制數(shù)據(jù)交換格式。

我們使用不同的技術(shù)和編程語(yǔ)言構(gòu)建多個(gè)微服務(wù)時(shí),有一種標(biāo)準(zhǔn)的方法來(lái)定義服務(wù)接口和底層的消息交換格式很重要。gRPC提供了一種簡(jiǎn)潔而強(qiáng)大的方法,可以使用協(xié)議緩沖區(qū)指定服務(wù)合約。因此,gRPC可能是最適合構(gòu)建內(nèi)部微服務(wù)間通信的解決方案。

我們?cè)诒疚闹袑⒏钊氲亟榻B為什么gRPC是構(gòu)建微服務(wù)間通信的一種出色選擇。

gRPC的基礎(chǔ)知識(shí)

有了gRPC,客戶可以對(duì)不同機(jī)器上的服務(wù)器應(yīng)用程序直接調(diào)用方法,好像該機(jī)器就是本地對(duì)象。gRPC立足于傳統(tǒng)的遠(yuǎn)程過(guò)程調(diào)用(RPC)技術(shù)的基礎(chǔ),但是實(shí)施在現(xiàn)代技術(shù)堆棧(比如HTTP2和協(xié)議緩沖區(qū)等)上,確保***的互操作性。

gRPC本身支持這種功能:使用gRPC接口定義語(yǔ)言(IDL)來(lái)定義服務(wù)合約。因此,作為服務(wù)定義的一部分,你可以指定可以遠(yuǎn)程調(diào)用的方法以及參數(shù)和返回類型的數(shù)據(jù)結(jié)構(gòu)。

圖1表明了gRPC的使用,在線零售應(yīng)用程序作為庫(kù)存和產(chǎn)品搜索服務(wù)的一部分。 Inventory服務(wù)的合約使用gRPC IDL來(lái)定義,該IDL在inventory.proto文件中已有指定。因此,Inventory服務(wù)的開(kāi)發(fā)人員應(yīng)先使用該服務(wù)來(lái)定義所有業(yè)務(wù)功能,然后利用proto文件生成服務(wù)端框架代碼。與之相仿,可以使用同樣的proto文件生成客戶端代碼(存根,stub)。

使用gRPC構(gòu)建實(shí)際的微服務(wù)

圖1

由于gRPC與編程語(yǔ)言無(wú)關(guān),你可以使用異構(gòu)語(yǔ)言來(lái)構(gòu)建服務(wù)和客戶端。在這個(gè)例子中,我們使用Ballerina(ballerina.io)生成了Inventory服務(wù)代碼,使用Java生成了客戶端代碼。你可以使用GitHub上的這個(gè)源代碼(https://github.com/kasun04/grpc-microservices)來(lái)試試該示例。

庫(kù)存(inventory.proto)的服務(wù)合約如下所示: 

  1. syntax = "proto3"
  2. package grpc_service; 
  3. import "google/protobuf/wrappers.proto"
  4. service InventoryService { 
  5.    rpc getItemByName(google.protobuf.StringValue) returns (Items); 
  6.    rpc getItemByID(google.protobuf.StringValue) returns (Item); 
  7.    rpc addItem(Item) returns (google.protobuf.BoolValue); 
  8. message Items { 
  9.    string itemDesc = 1; 
  10.    repeated Item items = 2; 
  11. message Item { 
  12.     string id = 1; 
  13.     string name = 2; 
  14.     string description = 3; 
  15.  

服務(wù)合約易于理解,可以在客戶端和服務(wù)之間共享。如果服務(wù)合約有任何變化,服務(wù)代碼和客戶端代碼都要重新生成。

比如說(shuō),以下代碼片段顯示了為Ballerina生成的gRPC服務(wù)的代碼。 對(duì)于我們?cè)趃RPC服務(wù)定義中的每個(gè)操作,都會(huì)生成相應(yīng)的Ballerina代碼。(Ballerina提供了開(kāi)箱即用的功能,使用“ballerina grpc –input inventory.proto –output service-skeleton –mode service”或“ballerina grpc –input inventory.proto –output bal-client –mode client”,生成服務(wù)代碼或客戶端代碼)。 

  1. import ballerina/grpc; 
  2. import ballerina/io; 
  3. endpoint grpc:Listener listener { 
  4.    host:"localhost"
  5.    port:9000 
  6. }; 
  7. @grpc:ServiceConfig 
  8. service InventoryService bind listener { 
  9.    getItemByName(endpoint caller, string value) { 
  10.        // Implementation goes here. 
  11.        // You should return a Items 
  12.    } 
  13.    getItemByID(endpoint caller, string value) { 
  14.        // Creating a dummy inventory item 
  15.        Item requested_item; 
  16.        requested_item.id = value; 
  17.        requested_item.name = "Sample Item " + value ; 
  18.        requested_item.description = "Sample Item Desc for " + value; 
  19.        _ = caller->send(requested_item); 
  20.        _ = caller->complete(); 
  21.    } 
  22.    addItem(endpoint caller, Item value) { 
  23.        // Implementation goes here. 
  24.        // You should return a boolean 
  25.    } 
  26.  

至于客戶端,再次用Inventory服務(wù)的gRPC服務(wù)定義來(lái)生成產(chǎn)品搜索服務(wù),這是一個(gè)Java(Spring Boot)服務(wù)。你可以使用maven插件為Spring Boot/Java服務(wù)生成客戶端存根(客戶端代碼嵌入在Spring Boot服務(wù)中)。調(diào)用生成的客戶端存根的客戶端代碼如下所示: 

  1. package mfe.ch03.grpc; 
  2. import com.google.protobuf.StringValue; 
  3. import io.grpc.ManagedChannel; 
  4. import io.grpc.ManagedChannelBuilder; 
  5. public class InventoryClient { 
  6.    public static void main(String[] args) { 
  7.        ManagedChannel channel = ManagedChannelBuilder.forAddress("127.0.0.1", 9000) 
  8.                .usePlaintext() 
  9.                .build(); 
  10.        InventoryServiceGrpc.InventoryServiceBlockingStub stub 
  11.                = InventoryServiceGrpc.newBlockingStub(channel); 
  12.        Inventory.Item item = stub.getItemByID( 
  13. StringValue.newBuilder().setValue("123").build()); 
  14.        System.out.println("Response : " + item.getDescription()); 
  15.    } 
  16.  

底層的通信

客戶端調(diào)用服務(wù)時(shí),客戶端gRPC庫(kù)使用協(xié)議緩沖區(qū),并編組(marshal)遠(yuǎn)程過(guò)程調(diào)用,該調(diào)用隨后通過(guò)HTTP2來(lái)發(fā)送。在服務(wù)器端,請(qǐng)求解組(un-marshalled),使用協(xié)議緩沖區(qū)執(zhí)行相應(yīng)的過(guò)程調(diào)用。響應(yīng)遵循從服務(wù)器到客戶端的類似的執(zhí)行流程。

使用gRPC開(kāi)發(fā)服務(wù)和客戶端的主要優(yōu)點(diǎn)是,你的服務(wù)代碼或客戶端代碼不需要為解析JSON或類似的基于文本的消息格式(在代碼內(nèi)或隱含在Jackson等底層庫(kù)中,對(duì)服務(wù)代碼而言隱藏起來(lái))操心。二進(jìn)制格式解組、轉(zhuǎn)換成對(duì)象。此外,我們要處理多個(gè)微服務(wù)并確保和維護(hù)互操作性時(shí),對(duì)通過(guò)IDL定義服務(wù)接口給予***支持是強(qiáng)大的功能。

用gRPC構(gòu)建微服務(wù)的實(shí)例

基于微服務(wù)的應(yīng)用程序由多個(gè)服務(wù)組成,并使用眾多編程語(yǔ)言構(gòu)建?;跇I(yè)務(wù)使用場(chǎng)景,你可以選擇最合適的技術(shù)來(lái)構(gòu)建服務(wù)。gRPC在這種多語(yǔ)言架構(gòu)中起到非常重要的作用。如圖2所示,產(chǎn)品搜索服務(wù)與另外多個(gè)服務(wù)進(jìn)行通信,這些服務(wù)是使用gRPC作為通信協(xié)議構(gòu)建的。因此,我們可以為每個(gè)服務(wù)定義服務(wù)合約:庫(kù)存、電子品類和服裝品類等?,F(xiàn)在,如果你想要打造一種多語(yǔ)言架構(gòu),可以使用不同的實(shí)現(xiàn)技術(shù)來(lái)生成服務(wù)框架。

圖2顯示了用Ballerina lang編寫的庫(kù)存服務(wù)、用Golang編寫的電子服務(wù)和用Vert.x(Java)編寫的服裝服務(wù)。客戶端還可以為這每個(gè)服務(wù)合約生成存根。

圖2

仔細(xì)研究圖2中的微服務(wù)通信風(fēng)格,可以看出gRPC用于所有內(nèi)部通信,而面向外部的通信可以基于REST或GraphQL。我們將REST用于面向外部的通信時(shí),大多數(shù)外部客戶端可以將服務(wù)用作API(利用Open API等API定義技術(shù)),因?yàn)榇蠖鄶?shù)外部客戶端知道如何與充分利用REST的HTTP服務(wù)進(jìn)行通信。此外,我們可以使用GraphQL之類的技術(shù),讓消費(fèi)者可以根據(jù)特定的客戶需求來(lái)查詢服務(wù),這是無(wú)法用gRPC提供便利的。

因此作為一般實(shí)踐,我們可以將gRPC用于內(nèi)部微服務(wù)之間的所有同步通信。其他同步消息傳遞技術(shù)(比如充分利用REST的服務(wù)和GraphQL)更適合面向外部的服務(wù)。

作者簡(jiǎn)介:WSO2架構(gòu)團(tuán)隊(duì)負(fù)責(zé)該公司集成平臺(tái)的開(kāi)發(fā)工作,Kasun Indrasiri是該團(tuán)隊(duì)的重要成員。之前,他作為產(chǎn)品主管參與開(kāi)發(fā)了WSO2企業(yè)服務(wù)總線(ESB)。他撰有《WSO2 ESB入門》一書,并與人合著了《企業(yè)級(jí)微服務(wù)》。他是Apache軟件基金會(huì)的當(dāng)選成員,還是Apache Synapse開(kāi)源ESB項(xiàng)目的項(xiàng)目管理委員會(huì)成員和提交者。

原文標(biāo)題:Build Real-World Microservices with gRPC,作者:Kasun Indrasiri

【51CTO譯稿,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文譯者和出處為51CTO.com】

責(zé)任編輯:龐桂玉 來(lái)源: 51CTO
相關(guān)推薦

2022-06-07 08:19:30

gRPCBallerina微服務(wù)

2017-08-07 08:41:13

Java微服務(wù)構(gòu)建

2024-09-30 14:38:47

2025-02-04 13:53:18

NixGogRPC

2022-09-05 08:00:00

Java微服務(wù)AuraDB

2020-02-17 16:28:49

開(kāi)發(fā)技能代碼

2023-06-01 15:14:55

架構(gòu)Python微服務(wù)

2023-01-11 15:17:01

gRPC.NET 7

2021-12-29 08:30:48

微服務(wù)架構(gòu)開(kāi)發(fā)

2018-09-12 09:00:00

數(shù)據(jù)庫(kù)Redis微服務(wù)

2022-10-10 08:00:00

微服務(wù)Spring Boo容器

2022-08-22 07:26:32

Node.js微服務(wù)架構(gòu)

2018-04-23 14:31:02

微服務(wù)GraphQLBFF

2022-02-20 22:10:20

微服務(wù)框架gRPC

2022-10-17 00:14:55

微服務(wù)稅mock代理服務(wù)

2022-09-12 15:58:50

node.js微服務(wù)Web

2021-12-05 23:14:24

微服務(wù)GolanggRPC

2022-03-29 10:36:32

技術(shù)架構(gòu)微服務(wù)

2016-06-03 09:59:43

微服務(wù)架構(gòu)敏捷

2018-07-09 09:27:10

Spring Clou微服務(wù)架構(gòu)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)