当前位置: 首页 > 科技观察

使用gRPC构建实用微服务_0

时间:2023-03-19 18:16:31 科技观察

【.com快译】早期的微服务实现利用具象状态传输(REST)架构作为事实上的通信技术。但是,充分利用REST的服务通常适用于直接向消费??者公开的面向外部的服务。由于它们基于传统的基于文本的消息传递(JSON、XML和基于HTTP的CVS等)——针对人类进行了优化,因此它们不是服务间通信的理想选择。相反,使用基于文本的消息传递协议,我们可以利用针对服务间通信优化的二进制协议。云原生计算基金会的gRPC(一种高性能开源通用远程过程调用框架)非常适合服务间通信,因为它使用协议缓冲区作为服务间通信的二进制数据交换格式。当我们使用不同的技术和编程语言构建多个微服务时,有一个标准的方法来定义服务接口和底层消息交换格式是很重要的。gRPC提供了一种简洁而强大的方式来使用协议缓冲区指定服务契约。因此,gRPC可能是构建微服务间通信最合适的解决方案。在本文中,我们将深入探讨为什么gRPC是构建微服务间通信的绝佳选择。gRPC的基础使用gRPC,客户端可以直接在不同机器上的服务器应用程序上调用方法,就好像该机器是本地对象一样。gRPC建立在传统远程过程调用(RPC)技术的基础上,但在现代技术栈(如HTTP2和协议缓冲区等)上实现,确保了最佳的互操作性。gRPC本身支持此功能:使用gRPC接口定义语言(IDL)来定义服务契约。因此,作为服务定义的一部分,您可以指定可以远程调用的方法以及参数和返回类型的数据结构。图1说明了gRPC在在线零售应用程序中作为库存和产品搜索服务的一部分的使用。Inventory服务的合同是使用inventory.proto文件中指定的gRPCIDL定义的。因此,Inventory服务的开发者应该首先使用该服务定义所有的业务功能,然后使用proto文件生成服务端框架代码。同样,可以使用同一个原型文件生成客户端代码(stub,stub)。图1由于gRPC与语言无关,因此您可以使用异构语言来构建服务和客户端。在此示例中,我们使用Ballerina(ballerina.io)生成库存服务代码,并使用Java生成客户端代码。您可以使用GitHub(https://github.com/kasun04/grpc-microservices)上的此源代码试用该示例。inventory(inventory.proto)的服务契约如下:谷歌.protobuf.StringValue)返回(项目);rpcaddItem(Item)returns(google.protobuf.BoolValue);}messageItems{stringitemDesc=1;repeatedItemitems=2;}messageItem{stringid=1;stringname=2;stringdescription=3;}服务契约简单易懂,可以分享客户和服务之间。如果服务契约有任何变化,服务代码和客户端代码都必须重新生成。例如,以下代码片段显示了Ballerina生成的gRPC服务的代码。对于gRPC服务定义中的每个操作,都会生成相应的Ballerina代码。(Ballerina提供了开箱即用的功能,使用“ballerinagrpc–inputinventory.proto–outputservice-skeleton–modeservice”或者“ballerinagrpc–inputinventory.proto–outputbal-client–modeclient”来生成服务代码或客户端代码)。importballerina/grpc;importballerina/io;endpointgrpc:Listenerlistener{host:"localhost",port:9000};@grpc:ServiceConfigserviceInventoryServicebindlistener{getItemByName(endpointcaller,stringvalue){//Implementationgoeshere.//YoushouldreturnaItems}getItemByID(endpointvaluecaller){string//CreatingadummyinventoryitemItemrequested_item;requested_item.id=value;requested_item.name="SampleItem"+value;requested_item.description="SampleItemDescfor"+value;_=caller->send(requested_item);_=caller->complete();}addItem(endpointcaller,Itemvalue){//Implementationgoeshere.//Youshouldreturnabooolean}}客户端,再次使用Inventory服务的gRPC服务定义生成产品搜索服务,这是一个Java(SpringBoot)服务。您可以使用maven插件为SpringBoot/Java服务(嵌入在SpringBoot服务中的客户端代码)生成客户端存根。调用生成的客户端存根的客户端代码如下所示:=ManagedChannelBuilder.forAddress("127.0.0.1",9000).usePlaintext().build();InventoryServiceGrpc.InventoryServiceBlockingStubstub=InventoryServiceGrpc.newBlockingStub(channel);Inventory.Itemitem=stub.getItemByValue(StringValue)set.newBuilder"123")。建造());System.out.println("Response:"+item.getDescription());}}底层通信客户端调用服务时,客户端gRPC库使用protocolbuffer和编组(marshal)远程过程调用,然后发送通过HTTP2。在服务器端,请求被取消编组,并使用协议缓冲区执行相应的过程调用。响应遵循从服务器到客户端的类似执行流程。使用gRPC开发服务和客户端的主要优点是您的服务代码或客户端代码不需要解析JSON或类似的基于文本的消息格式(无论是在代码内还是隐式地在底层库中,例如Jackson,但对于服务代码)。隐藏的话)担心。二进制格式被解组并转换为对象。此外,当我们处理多个微服务并确保和维护互操作性时,完全支持通过IDL定义服务接口是一个强大的功能。使用gRPC构建微服务的示例基于微服务的应用程序由多个服务组成,并使用多种编程语言构建。根据业务使用场景,您可以选择最合适的技术来构建服务。gRPC在这种多语言架构中扮演着非常重要的角色。如图2所示,产品搜索服务与其他几个使用gRPC作为通信协议构建的服务进行通信。因此,我们可以为每个服务定义服务契约:库存、电子产品类别、服装类别等。现在,如果你想构建一个多语言架构,你可以使用不同的实现技术来生成服务骨架。图2显示了一个用Ballerinalang编写的库存服务、一个用Golang编写的电子服务和一个用Vert.x(Java)编写的服装服务。客户端还可以为每个服务合同生成存根。图2仔细观察图2中的微服务通信方式,可以看出所有内部通信都使用gRPC,而面向外部的通信可以基于REST或GraphQL。当我们使用REST进行面向外部的通信时,大多数外部客户端可以将该服务用作API(利用OpenAPI等API定义技术),因为大多数外部客户端都知道如何与充分利用REST的HTTP服务进行通信。此外,我们可以使用GraphQL等技术,让消费者根据特定的客户需求查询服务,这是gRPC无法做到的。所以作为一般的做法,我们可以使用gRPC来进行内部微服务之间的所有同步通信。其他同步消息传递技术(例如利用REST和GraphQL的服务)更适合面向外部的服务。关于作者:KasunIndrasiri是WSO2架构团队的主要成员,负责公司集成平台的开发。此前,他作为产品负责人参与了WSO2企业服务总线(ESB)的开发。他是《WSO2 ESB入门》的作者,也是《企业级微服务》的合著者。HeisanelectedmemberoftheApacheSoftwareFoundationandaprojectmanagementboardmemberandcommitterfortheApacheSynapseopensourceESBproject.原标题:BuildReal-WorldMicroserviceswithgRPC,作者:KasunIndrasiri