当前位置: 首页 > 后端技术 > Node.js

第三篇--gRPC使用初探

时间:2023-04-03 13:08:13 Node.js

背景介绍:gRPC是google提供的一个rpc开发框架,什么是RPC(remoteprocedurecall),rc--remotecall,日常调用的APIwebserver是其中的远程调用首先,如果把p理解为函数,也就是说像调用本地函数一样调用远程函数,rpc框架为调用者(client)提供了一套工具和代码库)和被调用者(服务器)以方便rpc目标。本文一方面以简单的例子(对官方例子的增删改)来说明grpc的使用,辅以protobuffer的例子,另一方面,不同于传统的介绍性文章,调用者和被调用者使用同样的语言和环境,本例中调用者本地使用python,服务端使用node,部署在linux虚拟机上。这有望更清楚地描述整个过程。本文目标读者:期望了解protocolbuffer、rpc、grpc的使用或对环境感兴趣的初中级web后端开发者。准备调用者(客户端),windows10,安装标准Python,pb工具和grpc框架稍作调整,被调用方(服务器)debian8.9安装了node、pb工具和grpc框架。参考debian的官网。直接从git下载,除了include库,examples目录下还有examples。apt-getinstall-ygitgitclone-bv1.25.0https://github.com/grpc/grpc定义数据和流程因为涉及到跨服务器调用,所以需要定义数据传输的格式和流程定义。我们都知道可以通过使用xml或者json等格式来达到这个目的。灵活、高效、自动化的结构化数据序列化机制——想想XML,但更小、更快、更简单。packagehelloworld;serviceGreeter{rpcSayHello(HelloRequest)返回(HelloReply){}rpcSendIm(ImMsg)返回(ImRet){}}messageHelloRequest{stringname=1;}messageHelloReply{stringmessage=1;}messageImMsg{int32来自用户=1;int32touser=2;字符串内容=3;弦面=16;字符串imgs=17;}消息ImRet{int32retcode=1;字符串retmsg=2;字符串extdata=16;stringerrmsg=17;}上面就是我们定义的一个简单的helloworld.proto文件,里面定义了两个流程(函数),一个是官方的SayHello,一个是本例中新发送的IM消息SendIM,然后定义两个消息结构,我是发送消息和发送消息后服务器返回的结构。ImRet工具链使用客户端python:python-mgrpc_tools.protoc-I./protos--python_out=。--grpc_python_out=。./protos/helloworld.proto以上命令注意文件的目录路径执行后会在该目录下生成两个文件,分别是pb和grpc的代码文件。服务器nodejs:nodejs使用grpc框架有两种方式,静态导入和动态导入。所谓静态就是像上面那样提前生成pb文件和gprc。文件,dynamic就是在代码中直接读取.proto文件,框架读取后会自动编译。如果我比较懒,使用静态加载,下面的可以跳过。npminstall-ggrpc-tools安装可能会失败,报错如下:权限不足,网上搜索找到npm安装权限问题,添加命令参数npminstall--unsafe-permgrpc_tools然后grpc_tools_node_protoc--js_out=import_style=commonjs,二进制:。...route_guide/--grpc_out=../node/static_codegen/route_guide/--plugin=protoc-gen-grpc=`whichgrpc_tools_node_protoc_plugin`route_guide.proto的核心代码本例中使用的代码是官方例子编辑的,顺序为了减少文章的长度和无用代码的数量,特意去掉了结尾和注释。如有侵权或给读者带来不适,敬请谅解。客户端导入grpcimporthelloworld_pb2_grpcimporthelloworld_pb2defrun():channel=grpc.insecure_channel('192.168.220.129:50051')stub=helloworld_pb2_(channel)response=stub.SayHello(helloworld_pb2.HelloRequest(name='you'))print("欢迎客户端收到:"+response.message)response=stub.SendIm(helloworld_pb2.ImMsg(fromuser=2059,touser=3088,content='你收到转账了吗?[#F]',faces='显示可爱表情'))print("sendmsgresponsedata:\n",response)run()注意生成的两个py文件和这个代码文件放在同一个目录下。运行成功的结果:serversideconstPROTO_PATH=__dirname+'/../../protos/helloworld.proto';constgrpc=require('grpc');constprotoLoader=require('@grpc/proto-loader');让packageDefinition=protoLoader.loadSync(PROTO_PATH,{keepCase:true,longs:String,enums:String,defaults:true,oneofs:true});lethello_proto=grpc.loadPackageDefinition(packageDefinition).helloworld;/***实现SayHelloRPC方法。*/functionsayHello(call,callback){callback(null,{message:'Hello'+call.request.name});}/**lwy为演示添加*/functionsendIm(call,callback){console.日志(调用。请求);回调(null,{retcode:10100,retmsg:“发送成功”});}functionmain(){varserver=newgrpc.Server();//server.addService(hello_proto.Greeter.service,{sayHello:sayHello});server.addService(hello_proto.Greeter.service,{sayHello:sayHello,sendIm:sendIm});server.bind('0.0.0.0:50051',grpc.ServerCredentials.createInsecure());server.start();}main();运行成功截图:你在劝吗?整个过程很清楚,但是完全执行起来还是很容易踩坑的。我们在用vs开发webservices的时候,服务端写好后,在调用者上右击添加引用(类比导入包),客户端会在代码和数据全部生成后,直接调用函数就好本地人。ms太贴心了至于grpc,我的理解是分为三个步骤(三层),定义数据和流程,使用工具链生成,写代码。这样降低了开发协作的流畅度,但是程序效率很高。一方面,文本的pb格式会被两端编译使用,使得数据的序列化和反序列化非常高效。另一方面,它采用自动二进制编码定义,数据占用空间小,保证高频网络调用时节省大量数据传输。想要实现深入的使用,深入学习protocolbuffer是必不可少的。它的指南只是一本小册子,而grpc本身的框架本身就是学医的成本,所以,增加了大量的时间和成本。综上所述,如果你的项目需要高频远程调用(1s至少100级),传输的数据比较丰富,那么grpc栈是一个非常高效的选择。否则,使用普通的微服务框架或者常规的httprestful服务会让开发和使用更加方便。