首页 > 其他分享 >(4)go-micro微服务proto开发

(4)go-micro微服务proto开发

时间:2023-01-08 08:33:19浏览次数:56  
标签:string proto int micro rpc int64 go message

目录

一 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

image.png

下载完成之后解压

image.png

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文件,这就是自动生成好的编译之后的文件。
  • 命令讲解:
  1. --go_out 指定当前的目录./
  2. --micro_out 指定当前micro目录./
  3. ./proto/account/account.proto 指定要编译的.proto文件地址

效果图:

image.png

六 最后

  • 至此,go-micro微服务项目proto开发工作就正式完成。
  • 接下来就开始domain层开发了,希望大家关注博主和关注专栏,第一时间获取最新内容,每篇博客都干货满满。

欢迎大家加入 夏沫の梦的学习交流群 进行学习交流经验,点击 夏沫の梦学习交流

标签:string,proto,int,micro,rpc,int64,go,message
From: https://www.cnblogs.com/qi66/p/17034076.html

相关文章

  • Go 自定义序列化
    实现MarshalJSON()([]byte,error)方法,序列化后可以把原来的枚举数转化为枚举数对应的字符串实现UnmarshalJSON([]byte)error方法,可以把byte中的枚举的字符串转化为对......
  • Go结构体数据校验
    github.com/go-playground/validator范围约束对于字符串、切片、数组和map,约束其长度。len=10,min=6,max=10,gt=10。对于数值,约束其取值。min,max,eq,ne,g......
  • Go实现String方法
    给结构体实现String()sting方法,方便按照我们想看的方式打印出来fmt.Println(),类似与python的__str__和__repr__packagemain_testimport( "fmt" "github.com/byteda......
  • Go语言学习day2
    1.go的结构体没有构造函数,但是可以自己实现一个。由于值拷贝的开销比较大,所以返回的是结构体指针类型packagemainimport"fmt"typepersonstruct{ name,citystr......
  • go in action学习,go语法一些特殊点
    1.如果接口类型只包含一个方法,那么这个类型的名字以er结尾。如果接口类型内部声明了多个方法,其名字需要与其行为关联。2.如果要让一个用户定义的类型实现一个接口,这个用......
  • 适合编程初学者的开源项目:小游戏2048(Go语言版)
    目标为编程初学者打造入门学习项目,使用各种主流编程语言来实现。2048游戏规则一共16个单元格,初始时由2或者4构成。1、手指向一个方向滑动,所有格子会向那个方向运动。2......
  • JavaScript学习笔记—原型对象prototype
      创建的每个函数,解析器都会向函数中添加一个属性prototype,这个属性对应着一个对象就是我们所谓的原型对象。  函数作为普通函数调用prototype没有任何作用  当函......
  • go自学笔记
    自己啃官网,搞成能用的系统;]golang语言环境下载地址:http://go.p2hp.com/#google_vignette一直下一步安装,完成cmd:goversion看版本,是否安装成功在文件管理器......
  • .net core操作MongoDB
    前言现实中认识的一个搞java(百万富婆)的大佬,已经转行做抖音主播了,搞技术的只能赶在年前再水一篇博客,不足之处欢迎拍砖,以免误人子弟,呔,真是太难受了环境准备.ne......
  • mysql 连接时报错 :Client does not support authentication protocol requested by se
      错误原因:登录mysql 查看登录的用户的加密方式:  目前用的时最新版的mysql8 用户信息加密方式用的是caching_sha2_password实现的,  将其改为mysql......