【Go系列】RPC和grpc

承上启下

介绍完了Go怎么实现RESTFul api,不可避免的,今天必须得整一下rpc这个概念。rpc是什么呢,很多人都想把rpc和http一起对比,但是他们不是一个概念。RPC是一种思想,可以基于tcp,可以基于udp也可以基于http。我们详细学习下把。

开始学习

RPC,听起来是不是有点像“人品差”?别误会,这里的RPC可是“远程过程调用”的缩写,它可是一个让我们的代码能够隔空打牛、远程操控的神奇技能!

什么是RPC?

简单来说,RPC就是让你在本地调用一个函数,却能够远程执行另一台机器上的代码。想象一下,你在家里的沙发上按了一个遥控器,结果远在千里之外的咖啡机开始给你煮咖啡,是不是很神奇?RPC就是这么个神奇的“遥控器”。

Go如何实现RPC?

在Go语言中,实现RPC就跟泡方便面一样简单。以下是泡面的步骤:

  1. 准备调料包(定义服务):首先,你需要定义一个服务,也就是你的远程函数。这就像把调料包准备好,等着加水泡。
type HelloService struct{}func (p *HelloService) Hello(request string, reply *string) error {*reply = "hello, " + requestreturn nil
}

烧开水(注册服务):然后,你需要把服务注册到RPC服务器上,就像把调料包放进烧开的水里。

rpc.RegisterName("HelloService", new(HelloService))

泡方便面(启动服务器):接下来,启动RPC服务器,等待客户端调用。

lis, _ := net.Listen("tcp", ":1234")
rpc.Accept(lis)

品尝美味(调用服务):最后,客户端就可以远程调用你的服务了,就像品尝美味的方便面。

client, _ := rpc.Dial("tcp", "localhost:1234")
var reply string
err := client.Call("HelloService.Hello", "world", &reply)

grpc库的使用

说到RPC,怎能不提/grpc/这个库呢?它可是RPC界的“老干妈”,让RPC变得更加美味。

gRPC,这个由Google开发的高性能、开源的RPC框架。gRPC基于HTTP/2协议,使用Protocol Buffers作为接口定义语言,支持多种编程语言。以下是gRPC的详细介绍:

1. gRPC的特点

  • 多语言支持:gRPC支持多种编程语言,包括C++、Java、Python、Go、Ruby、C#、Node.js等。
  • 基于HTTP/2:gRPC使用HTTP/2作为传输协议,支持双向流、流控、头部压缩等特性,使得通信更加高效。
  • 协议缓冲(Protocol Buffers):gRPC使用Protocol Buffers来定义服务接口和消息格式,它是一种轻量级的数据交换格式,可以跨平台和语言使用。
  • 同步和异步:gRPC客户端提供了同步和异步的API,可以根据需要选择不同的调用方式。
  • 负载均衡:gRPC原生支持负载均衡,可以通过名称解析来发现服务实例。
  • 认证:gRPC支持多种认证机制,如SSL/TLS、JWT等。

2. gRPC的工作流程

  1. 定义服务:使用Protocol Buffers定义服务接口和消息类型。

    syntax = "proto3";service YourService {rpc YourMethod (YourRequest) returns (YourResponse);
    }message YourRequest {// request fields
    }message YourResponse {// response fields
    }
    
  2. 生成代码:使用Protocol Buffers编译器protoc生成服务端和客户端的代码。

    protoc --go_out=plugins=grpc:. your_service.proto
    
  3. 实现服务端:实现生成的服务端接口。

    type server struct{}func (s *server) YourMethod(ctx context.Context, in *pb.YourRequest) (*pb.YourResponse, error) {// implement the method
    }func main() {lis, err := net.Listen("tcp", ":50051")if err != nil {log.Fatalf("failed to listen: %v", err)}s := grpc.NewServer()pb.RegisterYourServiceServer(s, &server{})if err := s.Serve(lis); err != nil {log.Fatalf("failed to serve: %v", err)}
    }
    
  4. 实现客户端:使用生成的客户端代码调用服务。

    conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure(), grpc.WithBlock())
    if err != nil {log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()
    c := pb.NewYourServiceClient(conn)ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()
    r, err := c.YourMethod(ctx, &pb.YourRequest{})
    if err != nil {log.Fatalf("could not greet: %v", err)
    }
    log.Printf("Response: %s", r.GetField())
    

3. gRPC的四种调用类型

  • 简单RPC:客户端发送一个请求到服务器,并等待响应,就像普通的函数调用。
  • 服务器流式RPC:客户端发送一个请求到服务器,并获取一个流来读取一系列消息。客户端读取直到没有更多的消息。
  • 客户端流式RPC:客户端写入一系列消息并发送到服务器,一旦客户端完成消息写入,它等待服务器读取这些消息并返回一个响应。
  • 双向流式RPC:双方使用读写流发送一系列消息。两个流独立操作,因此客户端和服务器可以按照自己喜欢的顺序读写。

4. gRPC的安全性和认证

gRPC支持以下安全性措施:

  • 传输安全性:通过TLS/SSL来保证传输过程中的数据加密。
  • 认证:gRPC支持基于Token的认证机制,如OAuth 2.0。
  • 权限和审计:可以通过中间件来添加权限检查和审计日志。

5. gRPC的负载均衡

gRPC支持以下负载均衡策略:

  • 名称解析:gRPC客户端可以使用名称解析来发现服务实例。
  • 轮询:简单的轮询策略,将请求轮流分配到不同的服务器。
  • 基于权重的轮询:根据服务器的权重分配请求。
  • 故障转移:在主服务器故障时,请求会被转发到备用服务器。

restful与rpc

通过以上的介绍,我们都了解RPC(远程过程调用)和HTTP(超文本传输协议)是完全不同的概念,我们反倒是可以跟Restful API进行对比,:

RPC与HTTP的区别:

1. 目的与设计哲学:

  • RPC:旨在实现远程函数调用,让远程服务调用看起来像本地函数调用一样简单。
  • HTTP:是一种用于传输超媒体文档的应用层协议,主要用于Web浏览器和服务器之间的通信。

2. 通信方式:

  • RPC:通常采用二进制协议,数据传输效率较高。
  • HTTP:采用文本格式(如JSON、XML),可读性较好,但传输效率相对较低。

3. 传输协议:

  • RPC:可以使用多种传输协议,如TCP、UDP,甚至HTTP。
  • HTTP:默认使用HTTP/1.1或HTTP/2,基于TCP。

4. 性能:

  • RPC:通常提供更低的延迟和更高的吞吐量,因为它通常使用更高效的序列化/反序列化机制。
  • HTTP:由于HTTP协议的文本特性,性能通常不如RPC。

5. 客户端和服务端实现:

  • RPC:需要特定的客户端和服务端库来处理消息的序列化和反序列化。
  • HTTP:可以直接使用标准的HTTP客户端和服务器,如Web浏览器和Web服务器。

RPC与RESTful API的优缺点:

RPC的优点:

  • 性能:通常RPC框架提供更高效的序列化/反序列化机制,如Protocol Buffers或MessagePack,性能更优。
  • 简单性:RPC让远程调用看起来像本地函数调用,开发体验更接近于本地编程。
  • 强类型:许多RPC框架支持静态类型,有助于在编译时发现错误。

RPC的缺点:

  • 耦合性:RPC可能导致客户端和服务端之间的强耦合,因为它们需要共享接口定义。
  • 标准化:相比RESTful API,RPC的标准化程度较低,不同框架之间可能不兼容。

RESTful API的优点:

  • 无状态:RESTful API是无状态的,有助于构建可伸缩的系统。
  • 标准化:基于HTTP协议,有广泛的工具和库支持。
  • 可缓存:HTTP的缓存机制可以用于优化性能。

RESTful API的缺点:

  • 性能:由于HTTP的文本特性,性能可能不如二进制的RPC协议。
  • 复杂性:对于复杂的操作,RESTful API可能需要多个请求来完成任务,而RPC可以一个调用完成。

总的来说,RPC和RESTful API各有适用场景。RPC更适合内部服务之间的通信,特别是对性能有高要求的场景。而RESTful API更适合面向资源的Web服务,尤其是需要被Web浏览器直接访问的场景。选择哪种协议取决于具体的应用需求、性能要求和开发团队的偏好。

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

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

相关文章

【STM32嵌入式系统设计与开发---拓展】——1_10矩阵按键

这里写目录标题 1、矩阵按键2、代码片段分析 1、矩阵按键 通过将4x4矩阵按键的每一行依次设为低电平,同时保持其它行为高电平,然后读取所有列的电平状态,可以检测到哪个按键被按下。如果某列变为低电平,说明对应行和列的按键被按下…

Android焦点之FocusWindow切换流程

关键调用是setInputWindows InputDispatcher::dispatchFocusLocked:在这里打印日志"Focus entering" 或 "Focus leaving" SurfaceFlinger::updateInputFlingernotifyWindowInfos();mWindowInfosListenerInvoker->windowInfosChanged(windo…

深度学习落地实战:识别火车票信息

前言 大家好,我是机长 本专栏将持续收集整理市场上深度学习的相关项目,旨在为准备从事深度学习工作或相关科研活动的伙伴,储备、提升更多的实际开发经验,每个项目实例都可作为实际开发项目写入简历,且都附带完整的代码与数据集。可通过百度云盘进行获取,实现开箱即用 …

高阶面试-hw算法整理

坚持最近一个星期把每道题搞熟悉 文章目录 1154一年中的第几天[125. 验证回文串](https://leetcode.cn/problems/valid-palindrome/)[344. 反转字符串](https://leetcode.cn/problems/reverse-string/)[20. 有效的括号](https://leetcode.cn/problems/valid-parentheses/)[392.…

【Java】详解抽象类和接口的区别

一、抽象类和接口的主要区别表格 特性抽象类接口声明关键字abstractinterface声明访问修饰符public、protected、default(不能用private)public、default继承关键字extendsimplements变量跟普通类一样,可以包含实例变量、静态变量等 只能包含…

excel表怎么增乱序单词表 和正序单词表四六级要来了?!Excel帮你构建自己的单词库

excel表怎么增乱序单词表 和正序单词表四六级要来了?!Excel帮你构建自己的单词库 1.背单词的第一步,当然是先上网找电子版的单词集。 盘搜搜 2. 建立 xls 格式的表格 3. 把下载的单词数据 复制到 表格 粘贴 4.新建一列 辅助列 生成随机数来…

murmurhash3算法的go语言实现

MurmurHash的定义 MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。由Austin Appleby在2008年发明,并出现了多个变种,都已经发布到了公有领域(public domain)。与其它流行的哈希函数相比,对于规律性较强的key&…

网络编程-TCP/IP

网络概述 网络采用分而治之的方法设计,将网络的功能划分为不同的模块,以分层的形式有机组合在一起。 每层实现不同的功能,其内部实现方法对外部其他层次来说是透明的。每层向上层提供服务,同时使用下层提供的服务 网络体系结构…

SpringMVC注解全解析:构建高效Web应用的终极指南 (上)

SpringMVC 是一个强大的 Web 框架,广泛应用于 Java Web 开发中。它通过注解简化了配置,增强了代码的可读性。本文将全面解析 SpringMVC 中常用的注解及其用法,帮助你构建高效的 Web 应用。 一. MVC介绍 MVC 是 Model View Controller 的缩写…

数字通云平台 智慧政务OA PayslipUser SQL注入漏洞复现

0x01 产品简介 数字通云平台智慧政务OA产品是基于云计算、大数据、人工智能等先进技术,为政府部门量身定制的智能化办公系统。该系统旨在提高政府部门的办公效率、协同能力和信息资源共享水平,推动电子政务向更高层次发展。 0x02 漏洞概述 数字通云平台 智慧政务OA Paysli…

在vue2中引入一个js文件, 在模版中不能使用js中的变量解决

在 Vue 2 中,如果你引入一个 JavaScript 文件,并希望在模板中使用该文件中的变量,通常有几个常见的问题和解决方法: 1. 作用域问题 在 Vue 模板中,只能访问到 Vue 实例中的数据和方法,而无法直接访问外部…

使用百度语音技术实现文字转语音

使用百度语音技术实现文字转语音 SpringBootVue前后端分离项目 调用api接口需要使用AK和SK生成AccessToken,生成getAccessToken的接口有跨域限制,所以统一的由后端处理了 部分参数在控制台->语音技术->在线调试里面能找到 Controller RestController RequestMapping(&q…

差分进化(Differential Evolution)算法

一、差分进化(Differential Evolution)算法的起源 差分进化算法(DE)是一种基于群体的进化算法,由Rainer Storn和Kenneth Price在1995年提出。它是一种全局优化算法,适用于处理多种优化问题,包括…

PostgreSQL的引号、数据类型转换和数据类型

一、单引号和双引号(重要): 1、在mysql没啥区别 2、在pgsql中,实际字符串用单引号,双引号相当于mysql的,用来包含关键字; -- 单引号,表示user_name的字符串实际值 insert into t_user(user_nam…

浏览器跨tab页面通信方式总结

需求: 浏览器不同 tab 标签页之间是独立的, 如果要通信必须通过特殊手段来实现跨标签页通信。 1.StorageEvent 事件 当一个标签页 localStorage 变化时(sessionStorage 无效),同源下另一个或其他所有标签页使用 DO…

python多级表头汇总

需求:将图一的数据展示为图二样式 图一: 图二: 图一具体的Excel截图 图二具体样式 python解决办法: # 导入 pandas 库,用于数据处理 import pandas as pd# 加载 Excel 文件 file_path 多级表头读取实例.xl…

科研绘图系列:R语言circos图(circos plot)

介绍 Circos图是一种数据可视化工具,它以圆形布局展示数据,通常用于显示数据之间的关系和模式。这种图表特别适合于展示分层数据或网络关系。Circos图的一些关键特点包括: 圆形布局:数据被组织在一个或多个同心圆中,每个圆可以代表不同的数据维度或层次。扇区:每个圆被划…

【BUG】已解决:SyntaxError invalid syntax

SyntaxError invalid syntax 目录 SyntaxError invalid syntax 【常见模块错误】 错误原因: 解决办法: 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰,211科班出身,就职于…

C?C++?

c和C的区别主要是: 1、语言使用难度不同C难度大于C#大于C语言。 2、面向的对象不同C 语言是面向过程的,而 C 是面向对象的,C# 是一种完全面向对象的语言。 3、函数形式不同C 语言有标准的函数库,它们松散的,只是把功能…

图书馆定位导航:RFID、VR与AR技术在图书馆中的应用

图书馆作为知识的宝库,承载着无数求知者的梦想与期待,随着馆藏书籍数量的激增与图书馆布局的日益复杂,读者在寻找目标书籍往往有许多困难。传统的索引号查询方式虽能提供书籍的基本信息,但在寻找过程中,因不熟悉图书馆…