现在非常流行微服务,而 RPC 框架是微服务中不可或缺的一环,gRPC 是其中一个非常出色的 RPC 框架,所以借此机会来记录一下 gRPC 在 Go 语言中的安装使用以及运用。

PS.刚弄好 WSL 开发环境不久,所以这次都是在 WSL 环境下进行的。

gRPC 是什么

RPC

RPC 是远程过程调用(Remote Procedure Call)的缩写形式。SAP 系统 RPC 调用的原理其实很简单,有一些类似于三层构架的 C/S 系统,第三方的客户程序通过接口调用 SAP 内部的标准或自定义函数,获得函数返回的数据进行处理后显示或打印。

gRPC

更多人可能接触的更多的是基于 REST 的通信。我们已经看到,REST 是一种灵活的体系结构样式,它定义了对实体资源的基于CRUD的操作。 客户端使用请求/响应通信模型跨 HTTP 与资源进行交互。尽管 REST 是广泛实现的,但一种较新的通信技术 gRPC 已在各个生态中获得巨大的动力。

gRPC,其实就是 RPC 框架的一种,前面带了一个 g ,代表是 RPC 中的大哥,龙头老大的意思,另外 g 也有 global 的意思,意思是全球化比较 fashion ,是一个高性能、开源和通用的 RPC 框架,基于 ProtoBuf(Protocol Buffers) 序列化协议开发,且支持众多开发语言。面向服务端和移动端,基于 HTTP/2 设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。

在 gRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来处理客户端调用。在客户端拥有一个存根能够像服务端一样的方法。

gRPC的安装

在了解完 RPC 以及 gRPC 之后我们就要开始进行 gRPC 的安装,其实 gRPC 的安装非常简单,直接拉取第三方包就可以了,难点是 protobuf 的安装

protobuf (protocol buffer) 是谷歌内部的混合语言数据标准。通过将结构化的数据进行序列化(串行化),用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

//go mod拉一下这两个库
google.golang.org/grpc
google.golang.org/protobuf
wget https://github.com/protocolbuffers/protobuf/releases/download/v21.1/protoc-21.1-linux-x86_64.zip

将解压后得到的protoc二进制文件移动到$GOPATH/bin

PS.一定要配置好 GOPATH ,不然无法使用 protoc

go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

在安装好这两个之后检查一下 $GOPATH/bin 路径中是否有相对应的二进制文件,如果没有就去 /pkg/mod 中找到这两个包,运行 go build 编译成二进制文件再放进 $GOPATH/bin

此时基本已经大功告成,我们在终端输入 protoc --version 检查版本,若没问题就表明我们 protobuf 安装成功了

现在我们就可以打开一个新项目,愉快的使用 gRPC 进行开发

gRPC 的使用

为了让大家更加清楚,这次我会在之前使用 http 框架 gin 的项目上进行开发,并且使用更改密码这个功能来进行示范。

首先我们要创建一个 rpc 文件夹,然后其中还会有 server client pd文件夹,分别放有服务端,客户端以及 protobuf 自动生成的代码。

编写 proto 文件

关于 proto 文件的语法就不在这里赘述了,感兴趣可以上网查一下

syntax = "proto3";package changePW;option go_package = "./changePW";message changeReq {string old_password = 1;string new_password = 2;string username = 3;
}message changeRes {bool status = 1;string msg = 2;
}service changePW {rpc changePW (changeReq) returns (changeRes);
}

因为每次都输入命令行语句非常麻烦,所以我使用的是一个 sh 脚本,在文件中放下面的代码

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative ./changePW.proto

在终端中 ./build.sh.cmd 后自动生成代码

编写服务端代码

type server struct {changePW.UnimplementedChangePWServer
}func main() {err := dao.InitDB()listen, err := net.Listen("tcp", ":50002")if err != nil {log.Println("net.Listen ERR: ", err)return}s := grpc.NewServer()changePW.RegisterChangePWServer(s, &server{}) //注册这一个服务if err = s.Serve(listen); err != nil { //监听log.Println(err)return}
}func (s *server) ChangePW(ctx context.Context, req *changePW.ChangeReq) (res *changePW.ChangeRes, err error) {res = &changePW.ChangeRes{Status: false,Msg:    "更改密码错误",}user, err := dao.SelectUserByUsername(req.Username)if err != nil {if err == sql.ErrNoRows {return res, nil}return res, err}if user.Password != req.OldPassword {return &changePW.ChangeRes{Status: false,Msg:    "密码不符",}, nil}err = dao.UpdatePassword(req.Username, req.NewPassword)if err != nil {return &changePW.ChangeRes{Status: false,Msg:    "更改密码错误",}, nil}return &changePW.ChangeRes{Status: true,Msg:    "成功",}, nil
}

其中数据访问层的代码需要自行编写,值得一提的是必须在服务端中有初始化数据库的动作,不然会报 panic 。

客户端

func CallChangePw(endpoint string, oldPassword string, newPassword string, username string) (res *changePW.ChangeRes) {conn, err := grpc.Dial(endpoint, grpc.WithTransportCredentials(insecure.NewCredentials()))if err != nil {log.Println(err)return &changePW.ChangeRes{Status: false,Msg:    err.Error(),}}defer conn.Close()client := changePW.NewChangePWClient(conn)res, err = client.ChangePW(context.Background(),&changePW.ChangeReq{OldPassword: oldPassword,NewPassword: newPassword,Username:    username,},)if err != nil {log.Println(err)return &changePW.ChangeRes{Status: false,Msg:    err.Error(),}}fmt.Println("res = ", res)return res
}

API层

在此层使用 gin 框架。

func changePasswordRPC(ctx *gin.Context) {oldPassword := ctx.PostForm("old_password")newPassword := ctx.PostForm("new_password")iUsername, _ := ctx.Get("username")username := iUsername.(string)l1 := len([]rune(newPassword))if l1 > 16 {tool.RespErrorWithDate(ctx, "密码请在16位以内")return}res := client.CallChangePw("127.0.0.1:50002", oldPassword, newPassword, username)if res.Status == true {tool.RespSuccessfulWithDate(ctx, res.Msg)return}tool.RespErrorWithDate(ctx, res.Msg)return
}

最后在路由中进行调用

userGroup := engine.Group("/user")
{userGroup.Use(auth)userGroup.POST("/password", changePassword) //修改密码userGroup.POST("/rpc/password", changePasswordRPC)
}

结语

如果有没弄清楚的地方欢迎大家向我提问,我都会尽力解答

这是我的GitHub主页 github.com/L2ncE

欢迎大家Follow/Star/Fork三连

参考

https://zhuanlan.zhihu.com/p/411315625

gRPC 在 Go 语言中的安装与简单实践相关推荐

  1. r语言barplot函数图中加标签_R语言中绘制条形图的简单方法

    原标题:R语言中绘制条形图的简单方法 条形图(bar chart)是用宽度相同的条形的高度或长短来表示数据多少的图形.它主要用来展示不同分类(横轴)下某个数值型变量(纵轴)的取值.在实际中,条形图主要 ...

  2. %6f 在c语言中的作用,最简单的C程序设计 1.实验目的 ①掌握C语言中使用最多的一种语..._考试资料网...

    最简单的C程序设计 1.实验目的 ①掌握C语言中使用最多的一种语句--赋值语句的使用方法. ②掌握各种类型数据的输入输出的方法,能正确使用各种格式转换符. 2.实验内容和步骤 掌握各种格式转换符的正确 ...

  3. c语言中的加减乘除字母,简单的c语言加减乘除运算

    简单的c语言加减乘除运算 答案:6  信息版本:手机版 解决时间 2019-10-03 12:11 已解决 2019-10-03 00:06 简单的c语言加减乘除运算 最佳答案 2019-10-03 ...

  4. c#语言中读取txt文件,简单的c#文本文件读写-.NET教程,C#语言

    system.io命名空间中的类为托管应用程序提供文件以及其他形式的输入输出.托管i/o的基本构件是流,而流是字节导向的数据的抽象表示.流通过system.io.stream类表示. system.i ...

  5. webbench 下载_Ubuntu中webbench安装及简单使用

    Webbench是Linux下的一个网站压力测试工具,能测试处在相同硬件上,不同服务的性能以及不同硬件上同一个服务的运行状况.webbench的标准测试可以向我们展示服务器的两项内容:每分钟相应请求数 ...

  6. c语言中生日蛋糕图片大全,简单生日蛋糕图片大全

    蛋糕是一种面食,通常是甜的,典型的蛋糕是以烤的方式制作出来.下面是学习啦为大家准备的简单生日蛋糕图片,希望可以帮助大家! 生日祝福语: 1.摇曳的烛光,点亮你的生日;深情的吟唱,寄予我无限的祝福;漫天 ...

  7. c语言中求奇数的简单代码

    #include <stdio.h> int main() {int a = 0;while(a<100){if(a%2 != 0)//%表示求余数printf("%d & ...

  8. Flume监控之Ganglia安装与简单实践

    写在前面: 博主是一名大数据的初学者,昵称来源于<爱丽丝梦游仙境>中的Alice和自己的昵称.作为一名互联网小白,写博客一方面是为了记录自己的学习历程,一方面是希望能够帮助到很多和自己一样 ...

  9. c语言 r语言 java,R语言rJava包安装载入及JAVA环境配置

    rJava 包的安装与载入 一般文本分词的教程都会贴出: install.packages("rJava") library(rJava) 来引导我们装载rJava包,运行inst ...

最新文章

  1. linux之xargs详解
  2. 撰写实施方案注意事项
  3. Qt Creator添加Qt版本
  4. ActiveMQ 实现消息接收发送
  5. OpenStack安装Neutron组件最后进行验证后发现Metadata agent ct节点不显示
  6. dataframe scala 修改值_python – 使用Scala的API替换DataFrame的值
  7. php gettext 为空,PHP Gettext
  8. 理想汽车CEO李想晒11月理想ONE成绩
  9. Keras一些基本概念
  10. 智能音箱扎堆的技术红海,Rokid 如何杀出一条血路?
  11. Python脚本-导出SQL查询结果到Excel文件
  12. kafka reblance入门
  13. Win11更改微软应用商店下载路径
  14. 基于python微信群聊机器人开题报告
  15. 人声歌姬语音合成器+11个歌手音源-Yamaha Vocaloid 5.2.1 + Libraries WiN
  16. 计算机丢失msvcp90dll怎么办,msvcp90.dll
  17. dump_stack介绍以及内核符号表的生成和查找过程
  18. Linux copy命令 omitting directory
  19. c++直角空心三角形_2019秋人教版八年级数学上册三角形教材全解读
  20. 面试:MySQL篇,详尽知识点总结

热门文章

  1. Apache 、Nginx 、Squid 的区别
  2. 解决win7自带天气小工具不能使用
  3. Sublime Text 显示菜单栏
  4. 题目:企业网络方案设计
  5. linux系统怎么共享网络,在Linux操作系统的网络上共享计算机
  6. 六顶帽子思考法的好处
  7. Linux烤机脚本测试io,烤机轻松压到56度!RTX3060 iCraft OC评测
  8. 5. PostCSS
  9. Java超市收银系统(连接数据库实现具体功能)(源码——即搬可用)
  10. c语言----击鼓传花