[TOC]
gRPC
gRPC介绍
gRPC是什么?
RPC和RESTful的区别是什么?
RPC的音讯传输能够是TCP,能够是UDP,也能够是HTTP,当RPC音讯传输是HTTP时,它的构造与RESTful的架构相似
RPC和RESTful有什么不同呢:
- 操作的对象不一样的,RESTful会更加灵便
RPC操作的是办法对象, RESTful操作的是资源
RPC的客户端和服务器端是紧耦合的,客户端须要晓得服务端的函数名字,参数类型、程序等,能力近程过程调用。
RESTful基于 http的语义操作资源,参数的程序个别没有关系
RCP更适宜定制化
RESTful执行的是对资源的操作,次要都是CURD(增删改查)的操作,若须要实现一个特定的性能,如计算一个班级的平均分,这个时候应用RPC定义服务器的办法(如:Stu.CalAvg)供客户端调用则显得更有意义
gRPC的个性是什么?
- gRPC是能够跨语言开发的
在gRPC客户端能够间接调用不同服务器上的近程程序,应用姿态看起来就像调用本地过程调用一样,很容易去构建分布式应用和服务。客户端和服务端能够别离应用gRPC反对的不同语言实现。
基于HTTP2规范设计,比其余框架更优的中央有
- 反对
长连贯,双向流、头部压缩、多复用申请
等 节俭带宽
、升高TCP链接次数
、节俭CPU应用
和缩短电池寿命
- 进步了云端服务和Web利用的性能
- 客户端和服务端交互通明
- gRPC默认应用protobuf来对数据序列化
- 反对
gRPC的数据交互模式是怎么样的?
申请应答式
客户端收回一次申请,能够从服务端读取一系列的音讯
客户端写一系列音讯给到服务端,期待服务端应答
客户端和服务端都能够通过读写数据流来发送一系列音讯
数据的序列化形式 - protobuf
protobuf 是一个对数据序列化的形式,相似的有JSON,XML等
简略介绍protobuf的构造定义蕴含的3个关键字
- 以.proto做为后缀,除构造定义外的语句以分号结尾
- 构造定义能够蕴含:message、service、enum,三个关键字
- rpc办法定义结尾的分号可有可无
Message命名采纳驼峰命名形式,字段是小写加下划线
message ServerRequest { required string my_name = 1; }
Enums类型名采纳驼峰命名形式,字段命名采纳大写字母加下划线
enum MyNum { VALUE1 = 1; VALUE2 = 2; }
Service与rpc办法名对立采纳驼峰式命名
service Love { // 定义Confession办法 rpc MyConfession(Request) returns (Response) {}}
对于prtobuf的装置能够看看之前写的一个装置步骤《5个步骤搞定PROTOBUF的装置》
在proto文件中应用package
关键字申明包名,默认转换成go中的包名与此统一,能够自定义包名,批改go_package
即可:
test.proto
syntax = "proto3"; // proto版本package pb; // 指定包名,默认go中包名也是这个// 定义Love服务service Love { // 定义Confession办法 rpc Confession(Request) returns (Response) {}}// 申请message Request { string name = 1;}// 响应message Response { string result = 1;}
装置好protoc环境之后,进入到proto文件的目录下,(例如关上window git
)执行如下命令,将proto
文件编译成pb.go
文件
protoc --go_out=plugins=grpc:. test.proto
转换后果:
// Code generated by protoc-gen-go. DO NOT EDIT.// versions:// protoc-gen-go v1.25.0// protoc v3.13.0// source: test.protopackage testimport ( context "context" proto "github.com/golang/protobuf/proto" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync")const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) // Verify that runtime/protoimpl is sufficiently up-to-date. _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20))// This is a compile-time assertion that a sufficiently up-to-date version// of the legacy proto package is being used.const _ = proto.ProtoPackageIsVersion4type Request struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`}type Response struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Result string `protobuf:"bytes,1,opt,name=result,proto3" json:"result,omitempty"`}// LoveServer is the server API for Love service.type LoveServer interface { Confession(context.Context, *Request) (*Response, error)}
一个DEMO
目录构造为:
-------------------------------| mygrpc| ---------pb| -------------test.proto| ---------client.go| ---------srv.go-------------------------------
client.go
package mainimport ( "context" "log" "mygrpc.com/pb" "google.golang.org/grpc")func main() { // 连贯grpc服务 conn, err := grpc.Dial(":8888", grpc.WithInsecure()) if err != nil { log.Fatal(err) } // 很要害 defer conn.Close() // 初始化客户端 c := pb.NewLoveClient(conn) // 发动申请 response, err := c.Confession(context.Background(), &pb.Request{Name: "小魔童哪吒"}) if err != nil { log.Fatal(err) } log.Println(response.Result)}
server.go
package mainimport ( "context" "log" "net" "google.golang.org/grpc" "mygrpc.com/pb")// 定义Love服务type Love struct {}// 实现Love服务接口func (l *Love) Confession(ctx context.Context, request *pb.Request) (*pb.Response, error) { resp := &pb.Response{} resp.Result = "your name is " + request.Name return resp, nil}func main() { // 监听8888端口 listen, err := net.Listen("tcp", ":8888") if err != nil { log.Fatal(err) } // 实例化grpc server s := grpc.NewServer() // 注册Love服务 pb.RegisterLoveServer(s, new(Love)) log.Println("Listen on 127.0.0.1:8888...") s.Serve(listen)}
下一次介绍对于gRPC的认证
技术是凋谢的,咱们的心态,更应是凋谢的。拥抱变动,背阴而生,致力向前行。
我是小魔童哪吒,欢送点赞关注珍藏,下次见~