(4)go-micro微服务proto开发
目录
- https://github.com/protocolbuffers/protobuf/releases
下载完成之后解压
2、将bin目录将入环境变量
3、查看安装是否成功
protoc --version
三 Protobuf语法
1.1 基本规范
-
文件以.proto做为文件后缀,除结构定义外的语句以分号结尾
-
结构定义可以包含:message、service、enum
-
rpc方法定义结尾的分号可有可无
-
Message命名采用驼峰命名方式,字段命名采用小写字母加下划线分隔方式
message SongServerRequest { required string song_name = 1; }
-
Enums类型名采用驼峰命名方式,字段命名采用大写字母加下划线分隔方式
enum Foo { FIRST_VALUE = 1; SECOND_VALUE = 2; }
-
Service与rpc方法名统一采用驼峰式命名
1.2 字段规则
-
字段格式:
限定修饰符 | 数据类型 | 字段名称 | = | 字段编码值 | [字段默认值]
-
限定修饰符包含 required\optional\repeated
- Required: 表示是一个必须字段,必须相对于发送方,在发送消息之前必须设置该字段的值,对于接收方,必须能够识别该字段的意思。发送之前没有设置required字段或者无法识别required字段都会引发编解码异常,导致消息被丢弃
- Optional:表示是一个可选字段,可选对于发送方,在发送消息时,可以有选择性的设置或者不设置该字段的值。对于接收方,如果能够识别可选字段就进行相应的处理,如果无法识别,则忽略该字段,消息中的其它字段正常处理。---因为optional字段的特性,很多接口在升级版本中都把后来添加的字段都统一的设置为optional字段,这样老的版本无需升级程序也可以正常的与新的软件进行通信,只不过新的字段无法识别而已,因为并不是每个节点都需要新的功能,因此可以做到按需升级和平滑过渡
- Repeated:表示该字段可以包含0~N个元素。其特性和optional一样,但是每一次可以包含多个值。可以看作是在传递一个数组的值
-
数据类型
- Protobuf定义了一套基本数据类型。几乎都可以映射到C++\Java等语言的基础数据类型
.proto C++ Java Python Go Ruby C# double double double float float64 Float double float float float float float32 Float float int32 int32 int int int32 Fixnum or Bignum int int64 int64 long ing/long[3] int64 Bignum long uint32 uint32 int[1] int/long[3] uint32 Fixnum or Bignum uint uint64 uint64 long[1] int/long[3] uint64 Bignum ulong sint32 int32 int intj int32 Fixnum or Bignum int sint64 int64 long int/long[3] int64 Bignum long fixed32 uint32 int[1] int uint32 Fixnum or Bignum uint fixed64 uint64 long[1] int/long[3] uint64 Bignum ulong sfixed32 int32 int int int32 Fixnum or Bignum int sfixed64 int64 long int/long[3] int64 Bignum long bool bool boolean boolean bool TrueClass/FalseClass bool string string String str/unicode[4] string String(UTF-8) string bytes string ByteString str []byte String(ASCII-8BIT) ByteString -
字段名称
- 字段名称的命名与C、C++、Java等语言的变量命名方式几乎是相同的
- protobuf建议字段的命名采用以下划线分割的驼峰式。例如 first_name 而不是firstName
-
字段编码值
- 有了该值,通信双方才能互相识别对方的字段,相同的编码值,其限定修饰符和数据类型必须相同,编码值的取值范围为
1~2^32
(4294967296) - 其中 1~15的编码时间和空间效率都是最高的,编码值越大,其编码的时间和空间效率就越低,所以建议把经常要传递的值把其字段编码设置为1-15之间的值
- 1900~2000编码值为Google protobuf 系统内部保留值,建议不要在自己的项目中使用
- 有了该值,通信双方才能互相识别对方的字段,相同的编码值,其限定修饰符和数据类型必须相同,编码值的取值范围为
-
字段默认值
- 当在传递数据时,对于required数据类型,如果用户没有设置值,则使用默认值传递到对端
1.3 service如何定义
- 如果想要将消息类型用在RPC系统中,可以在.proto文件中定义一个RPC服务接口,protocol buffer编译器会根据所选择的不同语言生成服务接口代码
- 例如,想要定义一个RPC服务并具有一个方法,该方法接收SearchRequest并返回一个SearchResponse,此时可以在.proto文件中进行如下定义:
service SearchService { rpc Search (SearchRequest) returns (SearchResponse) {} }
- 生成的接口代码作为客户端与服务端的约定,服务端必须实现定义的所有接口方法,客户端直接调用同名方法向服务端发起请求,比较麻烦的是,即便业务上不需要参数也必须指定一个请求消息,一般会定义一个空message
1.4 Message如何定义
- 一个message类型定义描述了一个请求或响应的消息格式,可以包含多种类型字段
- 例如定义一个搜索请求的消息格式,每个请求包含查询字符串、页码、每页数目
- 字段名用小写,转为go文件后自动变为大写,message就相当于结构体
syntax = "proto3"; message SearchRequest { string query = 1; // 查询字符串 int32 page_number = 2; // 页码 int32 result_per_page = 3; // 每页条数 }
- 首行声明使用的protobuf版本为proto3
- SearchRequest 定义了三个字段,每个字段声明以分号结尾,.proto文件支持双斜线 // 添加单行注释
四 proto代码编写
- 在account.proto文件中写入以下代码
syntax = "proto3"; import "google/protobuf/timestamp.proto"; package go.micro.service.account; option go_package="/proto/account"; service Account { //登录 rpc Login(LoginRequest) returns (LoginResponse) {} //注册 rpc Register(RegisterRequest) returns (RegisterResponse) {} //查询用户信息 rpc GetUserInfo(UserIdRequest) returns (UserInfoResponse) {} //修改信息 rpc UpdateUserInfo(UserInfoRequest) returns (Response) {} //发送注册邮件 rpc SendRegisterMail(SendMailRequest) returns (SendMailResponse) {} //发送重置密码邮件 rpc SendResetPwdMail(SendMailRequest) returns (SendMailResponse) {} //重置密码 rpc ResetPwd(ResetPwdRequest) returns (Response) {} //获取权限 rpc GetUserPermission(UserIdRequest) returns (GetPermissionResponse) {} //修改权限 rpc UpdateUserPermission(UpdatePermissionRequest) returns (Response) {} //退出账号 rpc Logout(UserIdRequest) returns (Response) {} //删除账号 rpc DelUser(UserIdRequest) returns (Response) {} //禁用账号 rpc DisableUser(UserIdRequest) returns (Response) {} //启用账号 rpc EnableUser(UserIdRequest) returns (Response) {} } message UserInfoResponse{ int64 user_id = 1; string username = 2; string first_name = 3; string password = 4; int64 permission = 5; google.protobuf.Timestamp create_date = 6; google.protobuf.Timestamp update_date = 7; int64 is_active = 8; string email = 9; string last_name = 10; } message UserInfoRequest{ UserInfoResponse user_info =1; } message UserIdRequest{ int64 user_id = 1; } message Response{ string message = 1; } message RegisterRequest{ UserInfoResponse register_request = 1; string code = 2; } message LoginRequest{ string username = 1; string password = 2; } message LoginResponse{ bool is_success = 1; int64 user_id = 2; string token = 3; } message RegisterResponse{ bool is_success = 1; int64 user_id = 2; } message SendMailRequest{ string email = 1; } message SendMailResponse{ string code = 1; string msg = 2; } message GetPermissionResponse{ int64 permission = 1; } message UpdatePermissionRequest{ int64 user_id = 1; int64 permission = 2; } message ResetPwdRequest{ int64 user_id = 1; string code = 2; string password = 3; }
五 生成.go文件
-打开终端,输入以下命令:
protoc --go_out=./ --micro_out=./ ./proto/account/account.proto
- 命令执行后,会发现同级目录多了两个go文件,这就是自动生成好的编译之后的文件。
- 命令讲解:
- --go_out 指定当前的目录./
- --micro_out 指定当前micro目录./
- ./proto/account/account.proto 指定要编译的.proto文件地址
效果图:
六 最后
- 至此,go-micro微服务项目proto开发工作就正式完成。
- 接下来就开始domain层开发了,希望大家关注博主和关注专栏,第一时间获取最新内容,每篇博客都干货满满。
欢迎大家加入 夏沫の梦的学习交流群 进行学习交流经验,点击
-