微服务_protobuf配置及语法

二.protobuf

1.介绍

Google Protocol Buffer (简称 Protobuf)是google旗下的一款轻便高效的结构化数据存储格式

相比于json和xml:

  • 优点: 体积小,速度快,支持跨平台多语言,消息格式升级和兼容性好;
  • 缺点: 应用不够广,二进制格式可读性差,缺乏自描述.

2.环境配置

  1. protobuf 编译工具安装
1、下载 protoBuf:
git clone https://github.com/protocolbuffers/protobuf.git

2、安装依赖库
sudo apt-get install autoconf  automake  libtool curl make  g++  unzip libffi-dev -y

3、进入目录
cd protobuf/ 

4、自动生成configure配置文件:
./autogen.sh 

5、配置环境:
./configure

6、编译源代码(时间比较长)make 

7、安装
sudo make install

8、刷新共享库
sudo ldconfig 

9、成功后需要使用命令测试
protoc -h  
  1. protobuf 的go语言插件安装
1.获取go语言的proto包 API接口
go get  -v -u github.com/golang/protobuf/proto
go get  -v -u github.com/golang/protobuf/protoc-gen-go

2.编译
cd $GOPATH/src/github.com/golang/protobuf/protoc-gen-go/
go build

3.将生成的protoc-gen-go可执行文件,放到/bin目录下
sudo cp protoc-gen-go /bin/

3.语法

protobuf 通常会把用户定义的结构体类型叫做一个消息,写在一个以 .proto 结尾的文件中.

消息格式:
(字段修饰符)数据类型 字段名称 = 唯一的编号标签值;

  • 字段修饰符-例如: repeated…
  • 字段名称: protobuf建议以下划线命名而非驼峰式
  • 唯一的编号标签: 在同一个消息里不可以重复
  • 注释格式: 使用//,但是不要写在代码右侧,编译后会消失
  • 写一个person.proto的demo
//版本号
syntax = "proto3" ;
//包名
package pb ;

//消息体
message Person{
    string name = 1 ;
    int32 age = 3 ;
//repeated是重复的,类似go中的切片
    repeated string emails = 4 ;
//Phone_number 变量类型
    repeated  Phone_number phones = 5 ;
}

//Phone_number 是消息体名
message Phone_number {
    string number = 1;
    int64  type = 2;
}

//enum 是枚举类型的关键字
//Phone_type 枚举名称
enum Phone_type{
//后面的数值并不是序列 而是枚举的编号 一般是从0开始
    Mobile = 0 ;
    Home = 1 ;
    Work  = 2 ;
}

数据类型

.proto类型 Go类型 介绍
double float64 64位浮点数
float float32 32位浮点数
int32 int32 使用可变长度编码。编码负数效率低下——如果你的字段可能有负值,请改用sint32。
int64 int64 使用可变长度编码。编码负数效率低下——如果你的字段可能有负值,请改用sint64。
uint32 uint32 使用可变长度编码。
uint64 uint64 使用可变长度编码。
sint32 int32 使用可变长度编码。符号整型值。这些比常规int32s编码负数更有效。
sint64 int64 使用可变长度编码。符号整型值。这些比常规int64s编码负数更有效。
fixed32 uint32 总是四字节。如果值通常大于228,则比uint 32更有效
fixed64 uint64 总是八字节。如果值通常大于256,则比uint64更有效
sfixed32 int32 总是四字节。
sfixed64 int64 总是八字节。
bool bool 布尔类型
string string 字符串必须始终包含UTF - 8编码或7位ASCII文本
bytes []byte 可以包含任意字节序列

4.编译

可以通过定义好的.proto文件来生成go格式的代码

 protoc --proto_path=IMPORT_PATH --go_out=DST_DIR path/to/file.proto

protoc [OPTION] PROTO_FILES

–proto_path=IMPORT_PATH //IMPORT_PATH指定了 .proto 文件导包时的路径,如果忽略则默认当前目录。如果有多个目录则可以多次调用–proto_path,它们将会顺序的被访问并执行导入。

–go_out=DST_DIR //指定生成的go语言代码文件放入的文件夹

注意:

  1. 允许使用 protoc --go_out=./ *.proto 的方式一次性编译多个 .proto 文件

  2. 编译时,protobuf 编译器会把 .proto 文件编译成 .pd.go 文件

  • 对person.proto进行编译protoc --go_out=./ *.proto

在这里插入图片描述

这时文件夹中生成一个194行代码的person.pb.go文件.

5.使用编译文件进行编码

  • 根据person.proto中的参数进行拼写
package main

import (
	"fmt"
	"github.com/golang/protobuf/proto"
	"github.com/12-testProto"  //注意这个是包含person.pb.go文件的包
)

func main() {
	person := &pb.Person{
		Name:"tom",
		Age:18,
		Emails:[]string{"[email protected]"},
		Phones:[]*pb.PhoneNumber{
			&pb.PhoneNumber{
				Number:"12312341234",
				Type: int64(pb.PhoneType_Work),
			},
			&pb.PhoneNumber{
				Number:"32143214321",
				Type:int64(pb.PhoneType_Home),
			},
		},
	}

	fmt.Println("第一次打印",person)

	//进行序列化
	data,err :=proto.Marshal(person)
	if err !=nil{
		fmt.Println("proto序列化失敗",err)
	}
	fmt.Println("第二次打印",string (data))

	//反序列化
	newdata :=&pb.Person{}
	err =proto.Unmarshal(data,newdata)
	if err !=nil{
		fmt.Println("proto反序列化失敗",err)
	}
	fmt.Println("第三次打印",newdata)
	fmt.Println("姓名",newdata.Name)

}

Output:

第一次打印 name:"tom" age:18 emails:"[email protected]" phones:<number:"12312341234" type:2 > phones:<number:"32143214321" type:1 > 
第二次打印 
tom"123456@163.␌⎺└*

12312341234*

32143214321
第三次打印 name:"tom" age:18 emails:"123456@163.com" phones:12312341234" type:2 > phones:32143214321" type:1 > 
姓名 tom

你可能感兴趣的:(微服务,#,微服务)