一、protobuf介绍
protobuf是谷歌开源的一种数据格式,适合高性能,对响应速度有要求的数据传输场景。因为profobuf是二进制数据格式,需要编码和解码。数据本身不具有可读性。因此只能反序列化之后得到真正可读的数据。
优势:
-  序列化后体积相比Json和XML很小,适合网络传输 
-  支持跨平台多语言 
-  消息格式升级和兼容性还不错 
-  序列化反序列化速度很快 
二、安装
第一步:下载通用编译器
地址:Releases · protocolbuffers/protobuf · GitHub
根据不同的操作系统,下载不同的包,我是windows电脑,解压出来是protoc.exe
 
 
第二步:配置环境变量
 
 
第三步:安装go专用的protoc的生成器
go get github.com/golang/protobuf/protoc-gen-go安装后会在GOPATH目录下生成可执行文件,protobuf的编译器插件protoc-gen-go,执行protoc命令会自动调用这个插件
第四步、使用protobuf
-  定义了一种源文件,扩展名为 .proto,使用这种源文件,可以定义存储类的内容(消息类型)
-  protobuf有自己的编译器 protoc,可以将.proto编译成对应语言的文件,就可以进行使用了
四、proto样例
// 指定的当前proto语法的版本,有2和3
syntax = "proto3";
//option go_package = "path;name"; ath 表示生成的go文件的存放地址,会自动生成目录的
// name 表示生成的go文件所属的包名
option go_package="../service";
// 指定等会文件生成出来的package
package service;
message User {
  string username = 1;
  int32 age = 2;
}运行protoc命令编译成go中间文件
# 编译user.proto之后输出到service文件夹
 protoc --go_out=../service user.proto
五、构建rpc服务
5.1 项目结构

5.2、编写protobuf文件
// 这个就是protobuf的中间文件
// 指定的当前proto语法的版本,有2和3
syntax = "proto3";
option go_package="../service";
// 指定等会文件生成出来的package
package service;
// 定义request model
message ProductRequest{
	int32 prod_id = 1; // 1代表顺序
}
// 定义response model
message ProductResponse{
	int32 prod_stock = 1; // 1代表顺序
}
// 定义服务主体
service ProdService{
    // 定义方法
    rpc GetProductStock(ProductRequest) returns(ProductResponse);
}5.3 利用proto生成
protoc --go_out=plugins=grpc:./ .\product.proto值得注意的是,上面的生成命令中需要指定 grpc ,这样我们在文件中定义的 service 部分会生成对应的接口,我们只需要在服务端中实现这个接口即可。
5.4 服务端代码
接口实现:

启动方法代码
import "google.golang.org/grpc"
func main()  {
	server := grpc.NewServer()
	service.RegisterProdServiceServer(server,service.ProductService)
	listener, err := net.Listen("tcp", ":8002")
	if err != nil {
		log.Fatal("服务监听端口失败", err)
	}
	_ = server.Serve(listener)
}
5.4 客户端代码
新建client目录,把上述生成的product.pb.go copy过来,因为生成的时候会把服务端和客户端一并生成。
func main()  {
	// 1. 新建连接,端口是服务端开放的8002端口
	// 没有证书会报错
	conn, err := grpc.Dial(":8002", grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		log.Fatal(err)
	}
	// 退出时关闭链接
	defer conn.Close()
	// 2. 调用Product.pb.go中的NewProdServiceClient方法
	productServiceClient := service.NewProdServiceClient(conn)
	// 3. 直接像调用本地方法一样调用GetProductStock方法
	resp, err := productServiceClient.GetProductStock(context.Background(), &service.ProductRequest{ProdId: 233})
	if err != nil {
		log.Fatal("调用gRPC方法错误: ", err)
	}
	fmt.Println("调用gRPC方法成功,ProdStock = ", resp.ProdStock)
}


![[java]云HIS:检验字典维护](https://img-blog.csdnimg.cn/d730fb41e95b486b8a33e80ce6e09836.png)








![[Android Studio Tool]如何将AS的gradle文件迁移到D盘](https://img-blog.csdnimg.cn/36aa27b098794c5bbdb11ba80e47a03e.png)







