grpc:
正常客户端发送数据(以字节流的方式),服务器接受并解析,根据约定知道要执行什么,然后把结果返回给客户
rpc将上述过程封装,使其操作更加优化,使用一些大家都认可的协议,使其规范化,做成一些框架,直接或间接产生利益
基础知识:
单体架构:一旦某个服务出现错误,整体不可用,微服务架构解决了单体架构的弊端
grpc使用的是protobuf谷歌开源的成熟的数据结构序列化机制
序列化:将数据结构或对象转化成二进制串的过程
反序列化:将二进制串转化成数据结构或对象的过程
对称加密:加密和解密时候使用的都是同一个密码
非对称加密:加密和解密的时候使用的不是同一个密码
操作流程
安装
推荐看grpc官方或者中文文档;
首先安装protobuf,并把安装目录bin加入环境变量中,然后安装加载grpc的核心配置和运行工具(是带谷歌那个),准备工作已经完全完了
proto文件配置
分别创建客户端和服务端,创建以proto为后缀的文件,然后编写相关配置,
例如: 类似的文件配置
syntax = "proto3"; //这部分的内容是关于最后生成的go文件是在哪个目录哪个包中 //.代表在当前文件生成,server表示生成的go文件的包名为server option go_package = ".;server"; // 定义一个服务,可以接收客户端的参数,在返回服务端去响应 service Greeter { rpc SayHello (HelloRequest) returns (HelloResponse){} } // The request message containing the user's name. message HelloRequest { string requestName = 1; int64 age = 2; repeated string name =3; } // message关键词 可以理解为go中的结构体 //=后面的值不是赋值,是在结构体中的位置 message HelloResponse { string message = 1; }
在配置过之后,可以在终端运行:即可以生成两个程序
protoc --go_out=. hello.proto
protoc --go-grpc_out=. hello.proto
在server会生成两个go程序,此时往client中也要复制一份
服务端和客户端代码示例:
我们只需要在客户端和服务端实现相关操作即可,proto底层已经帮我们实现好了大部分方法
服务端:
package main import ( "context" "github.com/sirupsen/logrus" "google.golang.org/grpc" "net" haha "rpc/server/proto" ) type server struct { haha.UnimplementedGreeterServer } func main() { //开启端口 listen, err := net.Listen("tcp", ":9090") if err != nil { logrus.Info("listen port is fail") } //创建grpc服务 grpcServer := grpc.NewServer() //在grpc中去注册 haha.RegisterGreeterServer(grpcServer, &server{}) //启动服务 err = grpcServer.Serve(listen) if err != nil { logrus.Info("fail to start server") } } func (s *server) SayHello(ctx context.Context, req *haha.HelloRequest) (*haha.HelloResponse, error) { return &haha.HelloResponse{Message: "hello" + req.RequestName}, nil }
客户端:
syntax = "proto3"; //这部分的内容是关于最后生成的go文件是在哪个目录哪个包中 //.代表在当前文件生成,server表示生成的go文件的包名为server option go_package = ".;server"; // 定义一个服务,可以接收客户端的参数,在返回服务端去响应 service Greeter { rpc SayHello (HelloRequest) returns (HelloResponse){} } // The request message containing the user's name. message HelloRequest { string requestName = 1; int64 age = 2; repeated string name =3; } // message关键词 可以理解为go中的结构体 //=后面的值不是赋值,是在结构体中的位置 message HelloResponse { string message = 1; }
但是此时服务端和客户端之间的连接是不安全的,需要通过制定协议SSL/TSL协议来保证安全。