(4)go-micro微服务proto开发
一 Protobuf介绍
Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准,目前已经正在使用的有超过 48,162 种报文格式定义和超过 12,183 个 .proto 文件。他们用于 RPC 系统和持续数据存储系统。Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化、或者说序列化。它很适合做数据存储或RPC数据交换格式。可以用于即时通讯、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式
protobuf的核心内容包括:
定义消息:消息的结构体,以message标识。
定义接口:接口路径和参数,以service标识。
通过protobuf提供的机制,服务端与服务端之间只需要关注接口方法名(service)和参数(message)即可通信,而不需关注繁琐的链路协议和字段解析,极大降低了服务端的设计开发成本。
二 安装Protobuf
1、下载
下载所需的安装包,地址为: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层开发了,希望大家关注博主和关注专栏,第一时间获取最新内容,每篇博客都干货满满。
欢迎大家加入 夏沫の梦的学习交流群 进行学习交流经验,点击
(4)go-micro微服务proto开发的更多相关文章
- 流量染色与gRPC服务托管 微服务协作开发、灰度发布之流量染色 灰度发布与流量染色
大规模微服务场景下灰度发布与流量染色实践 https://mp.weixin.qq.com/s/UBoRKt3l91ffPagtjExmYw [go-micro]微服务协作开发.灰度发布之流量染色 - ...
- Apollo-open-capacity-platform 微服务能力开发平台 (转)
来自大佬的apollo整合微服务的教程:欢迎大家点评和star,链接如下:https://gitee.com/owenwangwen/open-capacity-platform 官方demo链接:h ...
- 微服务项目开发学成在线_day02 CMS前端开发
1 Vue.js与Webpack研究 开发版的浏览器:https://www.google.cn/intl/zh-CN/chrome/dev/ 前端的开发框架:微服务项目开发学成在线_Vue.js与W ...
- Dapr微服务应用开发系列2:Hello World与SDK初接触
题记:上篇介绍了Dapr的环境配置,这次我们来动手尝试一下Dapr应用的开发 Hello World Dapr应用的Hello World其实和其他的Hello World一样简单: 首先用你喜欢的语 ...
- 在微服务系统开发部署中使用Azure RBAC自定义角色
Azure的官方文档介绍了如何创建用于Azure基于角色的访问控制的自定义角色(RBAC Role). 我们也可以根据同样的原理把RBAC细粒度资源管理运用于微服务产品的开发部署中.(https:// ...
- Aooms_微服务基础开发平台实战_002_工程构建
一.关于框架更名的一点说明 最近在做年终总结.明年规划.还有几个项目需要了结.出解决方案,事情还比较多,死了不少脑细胞,距离上一篇文章发出已经过了3天,是不是有些人会认为我放弃了又不搞了,NONO,一 ...
- go micro 微服务框架温习
go mod edit -require="github.com/chromedp/chromedp@v0.1.0" @后面加上你需要的版本号.就可以 已经修改go.mod 里的依 ...
- 微服务项目开发学成在线_day01_CMS服务端开发
05-CMS需求分析-什么是CMS 什么是CMS?CMS (Content Management System)即内容管理系统,不同的项目对CMS的定位不同.CMS有哪些类型? 每个公司对每个项目的C ...
- 一个轻量级的.Net Core微服务快速开发的轮子
前言 Adnc是一个轻量级的.Net Core微服务快速开发框架,同时也可以应用于单体架构系统的开发.框架基于JWT认证授权.集成了一系列微服务配套组件,代码简洁.易上手.学习成本低.开箱即用 ...
- Dapr微服务应用开发系列0:概述
题记:Dapr是什么,Dapr包含什么,为什么要用Dapr. Dapr是什么 Dapr(Distributed Application Runtime),是微软Azure内部创新孵化团队的一个开源项目 ...
随机推荐
- 个人音乐博客 h5、css和js等
浅说一下吧 这个小项目由h5和css还有js和jq写的 主题内容为个人音乐 博客等 首页一级导航栏 以及侧边栏 整合部分图标(侧边栏未添加收起操作 时间原因 会的朋友们可以自行添加一个动画就可以 在m ...
- 如何在IDEA中自定义模板、快速生成完整的代码?
文章目录 1.修改现有的模板 2.自定义模板 3.在代码中测试自定义模板 1.修改现有的模板 打开设置面板- settings 2.自定义模板 选择定义模板组 选择创建模板 define 代表应用的范 ...
- 一步一图带你深入理解 Linux 虚拟内存管理
写在本文开始之前.... 从本文开始我们就正式开启了 Linux 内核内存管理子系统源码解析系列,笔者还是会秉承之前系列文章的风格,采用一步一图的方式先是详细介绍相关原理,在保证大家清晰理解原理的基础 ...
- 机器学习实战-AdaBoost
1.概念 从若学习算法出发,反复学恶习得到一系列弱分类器(又称基本分类器),然后组合这些弱分类器构成一个强分类器.简单说就是假如有一堆数据data,不管是采用逻辑回归还是SVM算法对当前数据集通过分类 ...
- vulnhub靶场之THALES: 1
准备: 攻击机:虚拟机kali.本机win10. 靶机:THALES: 1,网段地址我这里设置的桥接,所以与本机电脑在同一网段,下载地址:https://download.vulnhub.com/th ...
- 5 why 分析法,一种用于归纳抽象出解决方案的好方法
最近在看了<微信背后的产品观 - 张小龙手抄版>,其中有段话如下: 用户需求是零散的,解决方案是归纳抽象的过程 那如何归纳抽象呢?是否有一定的实践方法论呢?经过一轮探讨和学习,有这些答案: ...
- FlinkSQL之Windowing TVF
Windowing TVF 在Flink1.13版本之后出现的替代之前的Group window的产物,官网描述其 is more powerful and effective //TVF 中的tu ...
- redis的缓存穿透、击穿、雪崩以及实用解决方案
今天来聊聊redis的缓存穿透.击穿.雪崩以及解决方案,其中解决方案包括类似于布隆过滤器这种网上一搜一大片但是实际生产部署有一定复杂度的,也有基于spring注解通过一行代码就能解决的,其中各有优劣, ...
- WPF之MVVM实践中的Command与CommandParameter
先记录一下,方便以后复习. https://www.cnblogs.com/babietongtianta/p/3474101.html
- 关于软件物料清单(SBOM),你所需要了解的一切
在此前的多篇文章中,我们已经详细地介绍了软件物料清单(SBOM)对于保障软件供应链安全的重要性以及一些注意事项.在本文中,我们将会更深入地介绍SBOM,包括最低要求元素.格式.使用场景以及如何对其进行 ...