nodejs微服务:RPC与GRPC框架

news2024/10/4 21:23:36

RPC

  • RPC(Remote Procedure Call Protocol),是远程过程调用的缩写
  • 通俗的说就是调用远处的一个函数,与之相对应的是本地函数调用
    • 本地函数调用:参数,返回值,代码段都在本地的一个进程空间内
    • 远程函数调用:远程,即跨进程,这个进程部署在另一台服务器上,也就是调用另一台服务器上的函数
    • 远程函数调用是rpc主要实现的功能,也是微服务的的主要功能
  • 所谓微服务的实现,通俗而言,就是让我们可以像调用本地函数一样调用远程函数
  • 注意
    • RPC并不是一种具体的技术框架,而是一种技术思想
    • 广义上讲,任何通过网络,远程调用另一个进程中的方法的技术,都可以称为RPC
    • 随着时代的发展,越来越多优秀的RPC微服务框架进入我们的视野
    • 比如谷歌的GRPC框架、阿里的dubbo框架、Facebook的Thrift、腾讯的Tars等
    • 我们主要关注GRPC框架实现nodejs微服务

GRPC

  • gRPC 官方文档中文版:http://doc.oschina.net/grpc
  • gRPC官网:https://grpc.io/
  • gRPC 是一个高性能、开源和通用的 RPC 框架,面向移动端和 HTTP/2 设计
  • 目前提供 C、Java 和 Go语言版本,分别是:grpc, grpc-java, grpc-go
  • 其中 C版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP和C#
  • 特点
    • 1、提供几乎所有主流语言的实现,打破语言隔阂
    • 2、基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等待
    • 3、默认使用Protocol Buffers序列化,性能相较于RESTful Json好很多
    • 4、工具链成熟,代码生成便捷,开箱即用
    • 5、支持双向流式的请求和响应,对批量处理、低延时场景友好
  • 总结
    • 这些特性使得其在移动设备上表现更好,更省电和节省空间占用
    • 有了GRPC,我们可以一次性的在一个.proto文件中定义服务
    • 并使用任何支持它的语言去实现客户端和服务端
    • GRPC默认使用protocol buffers
    • 它是google开源的一套成熟的结构数据序列化机制(当然也可以使用其他数据格式如JSON)
    • 可以用proto files创建gRPC服务
    • 用protocol buffers消息类型来定义方法参数和返回类型
    • 在GRPC客户端可以直接调用不同服务器上的远程程序,就像调用本地程序一样, 很容易构建分布式应用和服务
    • 和很多RPC系统一样,服务负责实现定义好的接口并处理客户端请求
    • 客户端根据接口描述直接调用需要的服务, 客户端和服务器可以分别使用gRPC支持的不同语言实现

官方example解析

  • 文档:https://grpc.io/docs/languages/node/quickstart/

1 )下载示例体验

# Clone the repository to get the example code
$ git clone -b v1.53.0 --depth 1 --shallow-submodules https://github.com/grpc/grpc
# Navigate to the node example
$ cd grpc/examples/node
# Install the example's dependencies
$ npm install
# Navigate to the dynamic codegen "hello, world" Node example:
$ cd dynamic_codegen

2 )运行示例程序

2.1 先启动服务端

$ node greeter_server.js

2.2 后启动客户端

$ node greeter_client.js
  • 会直接返回 Hello world

3 ) gRPC代码解析

  • 在上述 dynamic_codegen 目录中的代码就是微服务的代码

  • 3.1 greeter_server.js

    /*
    *
    * Copyright 2015 gRPC authors.
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    *     http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    *
    */
    
    var PROTO_PATH = __dirname + '/../../protos/helloworld.proto';
    
    // 1. 引入工具文件
    var grpc = require('@grpc/grpc-js');
    var protoLoader = require('@grpc/proto-loader');
    // 2. 加载proto文件
    var packageDefinition = protoLoader.loadSync(
        PROTO_PATH,
        {keepCase: true,
        longs: String,
        enums: String,
        defaults: true,
        oneofs: true
        });
    // 固定写法
    var hello_proto = grpc.loadPackageDefinition(packageDefinition).helloworld; // 注意这里的 helloworld 是包名
    
    // 3. 定义远程调用方法: 名称,入参,返参,需要按照proto的约束来
    /**
     * Implements the SayHello RPC method.
     */
    function sayHello(call, callback) {
      callback(null, {message: 'Hello ' + call.request.name});
    }
    
    // 4. 启动微服务
    /**
     * Starts an RPC server that receives requests for the Greeter service at the
     * sample server port
     */
    function main() {
      var server = new grpc.Server(); // 4.1 创建 server 实例
      server.addService(hello_proto.Greeter.service, {sayHello: sayHello}); // 4.2 增加 服务, 第二个参数是绑定远程调用方法
      // 4.3 绑定端口 createInsecure 可以理解为通信的协议凭证
      server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => {
        server.start();
      });
    }
    
    main();
    
  • 3.2 greeter_client.js

    	/*
    	 *
    	 * Copyright 2015 gRPC authors.
    	 *
    	 * Licensed under the Apache License, Version 2.0 (the "License");
    	 * you may not use this file except in compliance with the License.
    	 * You may obtain a copy of the License at
    	 *
    	 *     http://www.apache.org/licenses/LICENSE-2.0
    	 *
    	 * Unless required by applicable law or agreed to in writing, software
    	 * distributed under the License is distributed on an "AS IS" BASIS,
    	 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    	 * See the License for the specific language governing permissions and
    	 * limitations under the License.
    	 *
    	 */
    	
    	var PROTO_PATH = __dirname + '/../../protos/helloworld.proto';
    	
    	// 1. 引入工具文件
    	var parseArgs = require('minimist');
    	var grpc = require('@grpc/grpc-js');
    	var protoLoader = require('@grpc/proto-loader');
    	// 2. 加载proto文件
    	var packageDefinition = protoLoader.loadSync(
    	    PROTO_PATH,
    	    {keepCase: true,
    	     longs: String,
    	     enums: String,
    	     defaults: true,
    	     oneofs: true
    	    });
    	// 固定写法
    	var hello_proto = grpc.loadPackageDefinition(packageDefinition).helloworld; // 注意这里的 helloworld 是包名
    	
    	function main() {
    	  // 获取客户端传入参数
    	  var argv = parseArgs(process.argv.slice(2), {
    	    string: 'target'
    	  });
    	  // 处理 target参数
    	  var target;
    	  if (argv.target) {
    	    target = argv.target;
    	  } else {
    	    target = 'localhost:50051';
    	  }
    	  // 这里创建 Greeter 服务实例, 这里target是远程服务
    	  var client = new hello_proto.Greeter(target, grpc.credentials.createInsecure());
    	  // 这里是返回的名称处理
    	  var user;
    	  if (argv._.length > 0) {
    	    user = argv._[0]; 
    	  } else {
    	    user = 'world';
    	  }
    	  // 客户端调用远程sayHello,传入name参数,并在回调中拿到服务端返回数据
    	  client.sayHello({name: user}, function(err, response) {
    	    console.log('Greeting:', response.message);
    	  });
    	}
    	
    	main();
    
  • 上述服务端和客户端中均引入了 helloworld.proto 这个文件有特定的书写语法

    // 这里是定义版本
    syntax = "proto3";
    
    // 以下java相关配置可以删除
    option java_multiple_files = true;
    option java_package = "io.grpc.examples.helloworld";
    option java_outer_classname = "HelloWorldProto";
    option objc_class_prefix = "HLW";
    
    // 这里是定义包名
    package helloworld;
    
    // 这里是定义服务 对应生成接口
    service Greeter {
      // Sends a greeting
      // 这里要求微服务中必须实现 SayHello 方法,在此方法中接收一个参数叫 HelloRequest,返回是 HelloReply
      // 可见对方法名,接收和返回都进行了约束
      rpc SayHello (HelloRequest) returns (HelloReply) {}
    
      rpc SayHelloStreamReply (HelloRequest) returns (stream HelloReply) {}
    }
    
    // The request message containing the user's name.
    // HelloRequest 是一个 message 对应js中的一个对象
    message HelloRequest {
      string name = 1;
    }
    
    // The response message containing the greetings
    message HelloReply {
      string message = 1;
    }
    
  • 还有两个工具: grpc、protoLoader

    var grpc = require('@grpc/grpc-js'); // 这里提供 grpc 服务
    var protoLoader = require('@grpc/proto-loader'); // 这里是 proto文件 加载器
    
  • 有上述服务端代码中,我们看到有几个必要的步骤

    • 1 ) 引入工具
    • 2 ) 加载proto文件 (服务端和客户端对应的都是一个proto文件,需要注意的是,实际上client和server可能在不同服务器上)
    • 3 ) 定义远程调用方法
      • 注意:外部proto文件中是 SayHello, 定义远程调用方法时写的是 sayHello
      • 是因为protoLoader.loadSync 方法中的配置 keepCase
      • 还是统一起来比较好
    • 4 ) 启动微服务
      • 创建 server 实例
      • 增加 服务, 第二个参数是绑定远程调用方法
      • 绑定端口 createInsecure 可以理解为通信的协议凭证
  • 客户端代码中,注意事项同上并参考注释

  • 后面自己要写的时候,可以将上述客户端和服务端,以及proto文件拷贝出去,写自己的业务需求

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/421714.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【pan-sharpening 攻击:目标检测】

Adversarial pan-sharpening attacks for object detection in remote sensing (对抗性泛锐化攻击在遥感目标检测中的应用) 全色锐化是遥感系统中最常用的技术之一,其目的是将纹理丰富的PAN图像和多光谱MS图像融合,以获得纹理丰…

docker上面安装mysql

一、docker安装mysql 新建配置 /data/mysql3306/conf/my.cnf(新建logs,data,conf/my.cnf 后面要用) 详情: [mysql] #设置mysql客户端默认字符集 default-character-setUTF8MB4[mysqld] #设置3306端口 port3306#允许最大连接数 max_connections200#允许连接失败的次…

Spring事务(3)-TransactionInterceptor实际事务执行

Spring事务(2)-EnableTransactionManagement实现源码解析 中介绍了Spring事务开启和代理的实现,现在了解实际事务执行TransactionInterceptor。 TransactionInterceptor TransactionInterceptor类图 MethodInterceptor:AOP代理后…

vue 高德地图设置鼠标样式

高德地图JS API 2.0 设置鼠标样式在线示例 首先&#xff0c;在 index.html 中引入图标&#xff1a; <link rel"stylesheet" href"https://at.alicdn.com/t/font_873139_0v65kqy674.css" >封装工具文件 utils/map.js &#xff1a; export default …

itop-3568开发板驱动学习笔记(9)高级字符设备(三)信号驱动 IO

《【北京迅为】itop-3568开发板驱动开发指南.pdf》 学习笔记 文章目录应用层信号机制应用层开启异步通知驱动层异步通知接口实验代码信号驱动 IO 不需要像 poll 一样查询设备的状态&#xff0c;一旦设备有目标事件发生&#xff0c;就会触发 SIGIO 信号&#xff0c;然后处理信号…

网卡的 Ring Buffer 详解

1. 网卡处理数据包流程 网卡处理网络数据流程图&#xff1a; 图片来自参考链接1 上图中虚线步骤的解释&#xff1a; 1 DMA 将 NIC 接收的数据包逐个写入 sk_buff &#xff0c;一个数据包可能占用多个 sk_buff , sk_buff 读写顺序遵循FIFO&#xff08;先入先出&#xff09;原…

Redis(四)事务 multi、exec

哈喽&#xff0c;大家好&#xff0c;我是有勇气的牛排&#xff08;全网同名&#xff09;&#x1f42e;&#x1f42e;&#x1f42e; 有问题的小伙伴欢迎在文末评论&#xff0c;点赞、收藏是对我最大的支持&#xff01;&#xff01;&#xff01;。 文章目录1 前言1.1 什么是Redi…

从零开始的Web渗透:信息收集步骤详解

一、域名信息收集 1.获取域名的whois信息是、 什么是Whois Whois是一种传输协议&#xff0c;用于查询域名注册所有者等信息。它可以帮助您查询域名是否已被注册&#xff0c;以及获取有关已注册域名的详细信息&#xff0c;例如域名注册商和域名所有人。 早期的Whois查询通常…

Docker 部署Jira8.1.0

Jira与Confluence一样&#xff0c;都需要用到独立的数据库&#xff0c;对于数据库的安装我们不做介绍&#xff0c;主要介绍如何用Docker部署Jira以及对Jira进行破解的操作。 1、数据库准备 关于数据库官方文档说明&#xff1a;https://confluence.atlassian.com/adminjiraserv…

【Spring6】| Spring对事务的支持

目录 一&#xff1a;Spring对事务的支持 1. 事务概述 2. 引入事务场景 3. Spring对事务的支持 3.1 Spring实现事务的两种方式 3.2 Spring事务管理API 3.3 声明式事务之注解实现方式 3.4 事务属性 3.5 事务传播行为propagation 3.6 事务的隔离级别isolation 3.7 事务…

【Android安全】Soot 静态分析教程

参考教程 https://github.com/noidsirius/SootTutorial Windows Soot 环境配置 下载代码 git 拷贝仓库 git init git clone https://github.com/noidsirius/SootTutorial.git ./gradlew.bat build 报错&#xff1a;Unsupported class file major version 57 ./gradlew.b…

JDK定时/延迟任务实现原理

刚刚好点进去看了,做个笔记 先读 这样子的延迟任务代码很常见,在保持心跳、延迟确认等等场景 从源码的角度看他是怎么实现的 Testpublic void delayTest() throws InterruptedException {Executors.newScheduledThreadPool(1).schedule(() -> {System.out.println("一…

Baumer工业相机堡盟工业相机如何联合BGAPISDK和OpenCVSharp实现图像的拉普拉斯算法增强(C#)

Baumer工业相机堡盟工业相机如何联合BGAPISDK和OpenCVSharp实现图像的拉普拉斯算法增强&#xff08;C#&#xff09;Baumer工业相机Baumer工业相机使用图像算法增加图像的技术背景Baumer工业相机通过BGAPI SDK联合OpenCV使用图像增强算法1.引用合适的类文件2.BGAPI SDK在图像回调…

数学与应用数学有哪些SCI期刊推荐? - 易智编译EaseEditing

以下是数学与应用数学领域的几个知名SCI期刊&#xff1a; Annals of Mathematics&#xff1a; 成立于1884年&#xff0c;是数学领域最古老和最著名的期刊之一&#xff0c;由普林斯顿大学出版。 该期刊发表了许多重要的数学成果&#xff0c;如Gdel不完全定理、费马大定理证明…

景点VR全景虚拟体验系统定制

为深度挖掘行业特色&#xff0c;利用5G、VR&#xff0c;AI&#xff0c;AR等数字化技术&#xff0c;为行业领域量身打造数字化解决方案已成趋势 VR内容定制可包括: VR旅游、VR展馆、VR教育、VR汽车、VR电商、VR地产等等。我们是国内较早从事沉浸式VR内容开发的企业&#xff0c;在…

Python将Excel文件内容写入Word文件

在日常办公中我们经常需要将Excel文件中的数据写入Word中&#xff0c;如果是手动一个一个进行复制粘贴&#xff0c;那将会非常的耗时且繁琐&#xff01; 遇到这种问题我们首先想到就是利用b编程解决&#xff0c;今天我分享一个excel转word的小方法&#xff01; 首先我有一个E…

儿童乙肝的预防和治疗,看这一篇就够了

儿童乙肝治疗应早期进行从1967年发现乙型肝炎&#xff08;以下简称乙型肝炎&#xff09;病毒&#xff0c;1969年开发乙型肝炎疫苗&#xff0c;到乙型肝炎治疗药物不断出现&#xff0c;乙型肝炎的防治取得了显著成效。目前&#xff0c;乙型肝炎的预防已经取得了积极的效果。儿童…

配置FTP/TFTP协议的ASPF

在多通道协议和NAT的应用中&#xff0c;ASPF是重要的辅助功能。通过配置ASPF功能&#xff0c;实现内网正常对外提供FTP和TFTP服务&#xff0c;同时还可避免内网用户在访问外网Web服务器时下载危险控件。 组网需求 如图1所示&#xff0c;FW部署在某公司的出口&#xff0c;公司提…

Jenkins Harbor

Harbor 环境搭建 https://github.com/goharbor/harbor/releases/tag/v2.5.6 点击下载地址安装包 安装 解压安装包 [rootlocalhost ~]# tar -zxvf harbor-offline-installer-v2.5.6.tgz -C /usr/local/修改harbor.yml配置 [rootlocalhost harbor]# cp harbor.yml.tmpl ha…

VMware vSphere中三种磁盘模式:精简置备/厚置备置零/厚置备延迟置零

在VMware vSphere中&#xff0c;不管是以前的5.1版本&#xff0c;或者是现在的6.5版本&#xff0c;创建虚拟机时&#xff0c;在创建磁盘时&#xff0c;都会让选择磁盘的置备类型&#xff0c;如下图所示&#xff0c;分为&#xff1a; Thick ProvisionedLazy Zeroed(厚置备延迟置…