Protobuf与GRPC

安装

https://github.com/protocolbuffers/protobuf/releases

已经有构建好的运行文件,可以下载压缩包在bin/目录下找到,如果想自己构建请访问https://github.com/protocolbuffers/protobuf/blob/main/src/README.md

安装完成后运行protoc --version查看是否成功。

protoc作用是将.proto文件转换,至于转换成什么语言需要我们指定参数,比如Go语言需要指定–go_out ,指定完参数我们还不能实现proto->go的转换,因为我们还缺少protoc-gen-go运行文件

旧版本:运行go install github.com/golang/protobuf/protoc-gen-go对protoc-gen-go进行安装,当然也可以下载源码手动构建(go get -u 就是这么做的)

新版本:go install google.golang.org/grpc/cmd/protoc-gen-go-grpc

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

注意,protobuf有两个重要的版本区别,旧版本github.com/golang/protobuf/protoc-gen-go 它带有protoc-gen-go,它生成protobuf消息的序列化和 grpc代码(使用–go_out=plugins=grpc时)

新版本 google.golang.org/protobuf/ 不再支持生成 gRPC 服务定义,如果想要生成grpc代码需要使用新插件protoc-gen-go-grpc。

plugins参数 是旧版本,新版本已弃用。新版本方法是 --go-grpc_out=。这里我们使用新版本。

为什么要安装protoc-gen-go那?因为protoc没有内置go生成器,所以在生成时会去系统bin/中查询protoc-gen-go,然后使用protoc-gen-go生成go文件。

语法

protobuf语法

使用

注意 --I可以指定.proto依赖包,如果在.proto文件中使用import的话。

protoc --go_out=:./ *.proto
protoc --go-grpc_out=. *.proto

该指令意思是,生成go代码。

第二行生成与grpc相关操作的代码

注意:如果预见helloworld.proto:23:1: Import “google/api/annotations.proto” was not found or had errors.这种错误,请下载google/api包

url-> grpc

protoc采用插件式所以,有很多插件可以方便我们的工作,下面讲解两个插件的使用

gateway

gateway的作用是将restful与grpc请求建立映射关系,让用户可以通过restful调用grpc

go get -u github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gatewayprotoc -I . --grpc-gateway_out . --grpc-gateway_opt logtostderr=true helloworld.proto

使用-i是因为 .proto文件中使用了import “google/api/annotations.proto”;

-I的作用是指定要搜索的目录,并且可以指定多个。

syntax = "proto3";//文件输出路径一定要有/否则报错
option go_package = "./helloworld";package helloworld;//引入依赖包
import "google/api/annotations.proto";// 接口
service Greeter {// 方法rpc SayHello (HelloRequest) returns (HelloReply) {//配置gatewayoption (google.api.http) = {get:"/v1/examples/sayhello"};}
}
// 类
message HelloRequest {string name = 1;
}// 类
message HelloReply {string message = 1;
}

swagger

swagger这个没什么好说的,懂的都懂

go get -u github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2protoc   --openapiv2_out . --openapiv2_opt logtostderr=true *.proto

如果go get 安装不行就需要手动源码安装https://github.com/grpc-ecosystem/grpc-gateway/

会自动生成一个swagger.json文件。

注意:在运行时可能报找不到*.protoc文件一般是annotations.proto等,请自行下载文件放入目录中。

有啥用?

那么对于生成的文件我们应该怎么用,他们每个文件又有什么含义那?

首先*.pb.go 为纯go语言生成类与方法(这里有版本区别,新版本意思不变,旧版本的话如果配置了grpc插件会将grpc相关的操作也会在这个文件生成)。

那么对于新版本来说 类文件与grpc操作分开存放,*_grpc.pb.go为grpc操作的文件。

我们在使用的时候,如果某些功能不建议使用grpc的情况下该怎么办那,这时候gateway就出厂了,gateway作用是使用ServeMux将grpc操作封装成restful接口。

Grpc

上面我们讲解了protoc如何生成文件,以及每个文件有什么用,接下来我们将讲解GRPC使用方法。

在https://github.com/grpc/grpc-go.git examples目录下有grpc的测试DEMO

接下来让我们使用官方实例Helloworld进行代码讲解

客户端

package main
import ("context""flag""log""time""google.golang.org/grpc""google.golang.org/grpc/credentials/insecure"pb "google.golang.org/grpc/examples/helloworld/helloworld"
)
const (defaultName = "world"
)
var (addr = flag.String("addr", "localhost:50051", "the address to connect to")name = flag.String("name", defaultName, "Name to greet")
)
func main() {flag.Parse()// 创建grpc连接,第一参数为服务器地址,第二个参数是配置conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))// 封装成GreeterClient,目的是达到调用方法就能发送请求的目的。(嗯本质就是客户端服务器呗RPC也是)。c := pb.NewGreeterClient(conn)ctx, cancel := context.WithTimeout(context.Background(), time.Second)// 调用方法,请求,原理是使用上面创建的conn发送请求。这里需要注意传入的类时我们通过proto生成的类,r, err := c.SayHello(ctx, &pb.HelloRequest{Name: *name})
}

客户端配置

 conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
// 第二个参数为配置参数
//我们不需要传入整个Option类
//GRPC给我们封装成了方法形式代用配置,
//具体方法可以根据下面的配置类转换(将首字母转换成大写,智能提示应该就可以提示出来)
type dialOptions struct {// 拦截器,在invoke方法中调用/*if cc.dopts.unaryInt != nil {return cc.dopts.unaryInt(ctx, method, args, reply, cc, invoke, opts...)}return invoke(ctx, method, args, reply, cc, opts...)*/unaryInt  UnaryClientInterceptor// 流拦截器streamInt StreamClientInterceptor// 拦截链chainUnaryInts  []UnaryClientInterceptor// 拦截链chainStreamInts []StreamClientInterceptor// 定义GRPC失败策略bs                          internalbackoff.Strategy// 拨号阻塞block                       bool// 超时时间timeout                     time.Duration// 连接方式 默认是ServerNameauthority                   string//  transport.ConnectOptionscopts                       transport.ConnectOptions// 前后置处理器callOptions                 []CallOption// channelz数据库标识channelzParentID            *channelz.Identifier//disableServiceConfig        bool//disableRetry                bool//disableHealthCheck          bool//healthCheckFunc             internal.HealthChecker// minConnectTimeout           func() time.Duration//resolvers                   []resolver.Builder
}

服务端

package mainimport ("context""flag""fmt""log""net""google.golang.org/grpc"pb "google.golang.org/grpc/examples/helloworld/helloworld"
)var (port = flag.Int("port", 50051, "The server port")
)// 我们需要实现接口类,但是这里并没有,而是继承了UnimplementedGreeterServer类,目的是可以不实现接口的所有方法,而另一个目的,在生成时UnimplementedGreeterServer类实现了SayHello方法,其功能就是返回没有实现当前方法信息,提醒我们需要去主动重构。
type server struct {pb.UnimplementedGreeterServer
}// 实现方法,返回值使用生成的类
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {log.Printf("Received: %v", in.GetName())return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
}func main() {flag.Parse()// 创建监听事件lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))if err != nil {log.Fatalf("failed to listen: %v", err)}// 创建grpc服务器s := grpc.NewServer()// 注册grpc服务器,将请求服务名与方法绑定// 这里是 服务名helloworld.Greeter,方法 SayHello// 客户端在请求的时候就是根据服务名进行请求的。pb.RegisterGreeterServer(s, &server{})log.Printf("server listening at %v", lis.Addr())// 启动监听事件if err := s.Serve(lis); err != nil {log.Fatalf("failed to serve: %v", err)}
}

在使用过程中,proto插件已经将我们需要的grpc操作生成完成,我们只需要对其进行调用即可。

服务端配置

下面我们讲一下创建GRPC时可以进行的配置

// NewServer(opt ...ServerOption)
s := grpc.NewServer()
//但是我们不需要传入整个ServerOption类
//GRPC给我们封装成了方法形式代用配置,例如   NewServer(grpc.WriteBufferSize(1))
//具体方法可以根据下面的配置类转换(将首字母转换成大写,智能提示应该就可以提示出来)
type serverOptions struct {// 定义协议支持,比如TLS、SSLcreds                 credentials.TransportCredentials//包含了Codec and encoding.Codeccodec                 baseCodec/*拦截器,在即将调用SayHello方法时调用,handler := func(ctx context.Context, req interface{}) (interface{}, error) {return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest))}return interceptor(ctx, in, info, handler)*/unaryInt              UnaryServerInterceptor//拦截流器streamInt             StreamServerInterceptor//拦截链,GRPC内部会将其处理成链chainUnaryInts        []UnaryServerInterceptor//拦截链,GRPC内部会将其处理成链chainStreamInts       []StreamServerInterceptor//inTapHandle           tap.ServerInHandle//处理连接接口statsHandler          stats.Handler//限制最大并发流  通过MaxConcurrentStreams(n uint32)设置maxConcurrentStreams  uint32// 默认1024 * 1024 * 4  最大接收消息大小maxReceiveMessageSize int// 默认math.MaxInt32 最大发送消息大小maxSendMessageSize    int// 设置一个404处理unknownStreamDesc     *StreamDesc//服务器设置 keepalive 和 max-age 参数keepaliveParams       keepalive.ServerParameters//keepalive 强制策略keepalivePolicy       keepalive.EnforcementPolicy// 流设置窗口大小 窗口大小的下限是 64K,任何小于该值的值都将被忽略。initialWindowSize     int32//连接窗口大小 窗口大小的下限是 64K,任何小于该值的值都将被忽略。initialConnWindowSize int32//默认32 * 1024 写缓存writeBufferSize       int//默认32 * 1024 读缓存readBufferSize        int// 连接超时时间 默认120 * time.Second connectionTimeout     time.DurationmaxHeaderListSize     *uint32headerTableSize       *uint32// 设置处理传入流的并发数 设置0则每个都创建一个并发numServerWorkers      uint32
}

Grpc gateway

我们生成了gateway那么应该怎么使用它那?

ctx := context.Background()
mux := http.NewServeMux()
muxgw := runtime.NewServeMux()// http到grpc映射,添加到muxgw中
helloworld.RegisterGreeterHandlerServer(ctx, muxgw, &server{})mux.Handle("/", muxgw)
mux.HandleFunc("/test", func(writer http.ResponseWriter, request *http.Request) {writer.Write([]byte("fewafa"))
},
)
fmt.Println("开始监听")
http.ListenAndServe("localhost:8090", mux)

我们请求http://localhost:8090/v1/examples/sayhello查看是否返回正确的信息

Protoc与GRPC的使用相关推荐

  1. golang安装protoc和gRPC步骤

    golang安装protoc和gRPC步骤 1. 将gopath/bin目录添加系统的环境变量中 2. 安装protoc 3. 对应的插件安装 4. 安装完成 1. 将gopath/bin目录添加系统 ...

  2. gRPC 基础概念详解

    作者:jasonzxpan,腾讯 IEG 运营开发工程师 gRPC (gRPC Remote Procedure Calls) 是 Google 发起的一个开源远程过程调用系统,该系统基于 HTTP/ ...

  3. java中使用grpc和protobuf

    第一步 使用maven,比较简单.依赖项中添加: <dependency><groupId>io.grpc</groupId><artifactId>g ...

  4. grpc istio_在皮质数据湖中使用grpc envoy和istio进行大规模数据摄取

    grpc istio Cortex Data Lake collects, transforms and integrates your enterprise's security data to e ...

  5. php使用grpc简单教程

    GRPC PHP客户端实现教程 依赖工具 本demo要实现的是通过php-fpm(非cli)调用grpc与远程服务进行交互.- nginx 1.8.0+ - gcc 4.8+ - php5.6+ - ...

  6. iOS的 gRPC 之路

    作者: iOS 团队 - 王玎 ##为什么要用? 网络层代码直接按照定义好的proto 文件生成,简单方便 而从用户角度来看,可以节省流量,网络请求速度更快了 翁伟要求的 ##我们的期望 支持 swi ...

  7. grpc协议_gRPC和协议缓冲区简介

    grpc协议 gRPC is a burgeoning piece of technology that allows you to build web services where you can ...

  8. Visual Studio环境编译和使用grpc框架

    参考链接:https://blog.csdn.net/weixin_28927079/article/details/97262243 作者:melon-gaga gRPC 是一个高性能.通用的开源R ...

  9. gRPC(3)- Go使用gRPC

    前言 上一节讲了proto的安装和php如何使用gRPC,使用gRPC需先安装protoc工具,没看过的小伙伴先移步看上一节的内容. 本文主要讲Go如何启动gRPC服务和如何使用客户端请求gRPC. ...

  10. QT+GRPC环境搭建

    链接:https://www.cnblogs.com/MakeView660/p/11532192.html 遇到的问题: 1.下面这两个可以不安装: pacman -S mingw-w64-x86_ ...

最新文章

  1. Unreal Engine 4 优化教程
  2. 百度要造什么车?汽车依然逃不出 BAT 的手掌心 | 撩车
  3. IBM 存储RAID硬盘离线和数据库损坏的恢复处理办法
  4. vlayout 1.2.20 发布,阿里 LayoutManager 定制化布局
  5. PyQt5-菜单栏工具栏状态栏的使用(QMenuBar、QToolBar、QStatusBar)
  6. hdu 4501 多维0-1背包
  7. hexo 菜单_Hexo 搭建个人博客教程 - 6 - 设置菜单,发布博客 - 2018
  8. linux运维需要哪些网络知识,Linux运维学习笔记-网络技术知识体系总结
  9. ubuntu 修改 ssh默认端口号
  10. 【算法学习】B-Tree编程实现(C++模板类封装)
  11. arch 安装准备--包管理的使用pacman
  12. iphone换机数据迁移_怎么一键换机?换新机迁移数据必看教程!
  13. BOW(opencv源码)
  14. Spring Boot入门篇-默认安全配置
  15. 关于 WMV、WMA、ASF、ASX 等格式和 Windows Media Player 的说明
  16. 015-包、crate、模块
  17. 计算机桌面调音量的图标不见了,电脑声音图标不见了win7怎么办_win7电脑调音量的图标不见了如何找回-win7之家...
  18. 做人做事箴言录(3)
  19. filco的pin码_一把强行帮你退烧的键盘 plum niz atom66静电容
  20. win ce车载系统刷机包_华为EMUI系统手机密码忘记了怎么办,

热门文章

  1. 怎么设置creative cloud的应用禁止自动更新
  2. 《自己动手写网络爬虫》读书笔记——队列与集合
  3. web视频播放器videojs
  4. Win10外接显示频黑屏解决
  5. Vue3使用echarts教程
  6. 获取dm数据库基本信息
  7. html五子棋游戏(附源码)
  8. 解决Nvivo自动编码问题,nvivo自动编码语言包
  9. 开源扫描仪软件_适用于Windows的优秀开源免费扫描仪软件?
  10. Redis安装到Windows系统上的详细步骤