当前位置 : 主页 > 网络编程 > 其它编程 >

微服务间的通信--Protobuf

来源:互联网 收集:自由互联 发布时间:2023-07-31
1. 概述 上图是一个被拆解的 SONY 相机,里面的元器件在工作的时候各司其职,只做自己擅长的领域。他们可以来自于不同的厂家甚至国家,在全球化的今天,大部分优秀的产品都在针对

1. 概述

微服务间的通信--Protobuf

上图是一个被拆解的 SONY 相机,里面的元器件在工作的时候各司其职,只做自己擅长的领域。他们可以来自于不同的厂家甚至国家,在全球化的今天,大部分优秀的产品都在针对某个单点进化,寻求更优质的服务和技术。

其实对于软件技术来说也是一样,并且更像全球化的一个缩影。

Microservices 没有固定且单一的定义,随着时间的流逝以及技术的不断演进,业界却已经默默的形成了一些共识,可以总结出的特征包括以下下几点。

  • 具体的微服务在整个架构中,通过通信协议相互传递信息 例如 HTTP。

  • 微服务是可以独立部署的。

  • 微服务是围绕业务组织具体的功能的。

  • 微服务不限语言、数据库、硬件和软件环境来实现服务。

  • 服务颗粒度小,支持消息传递,受上下文限制并通过自动化流程来构建和发布。

从以上总结来看,微服务间的信息交互是整个 MSA ( Microservice Architecture ) 的基础,通信 协议 的质量决定了基于此建立的服务是否简洁、高效、稳定、可扩展、易于维护。最终体在产品中就是用户体验,尤其是针对需要快速响应的服务,比如:支付、广告竞价等。而 Protocol Buffers ( 通常称为 Protobuf ) 正是此中的佼佼者。

至于为什么,我们可以参考以下这篇文章,这里不赘述。

Beating JSON performance with Protobuf LINK
2. 快速使用2.1 定义通信协议

让我们先来看一个非常简单的例子,假设我们需要定义一个登录请求,这个登录请求需要有 用户名密码重试次数。我们可以将这个请求定义在一个后缀为.proto 的文件中。信息的内容如下:

/* LoginRequest represents a login request
* user_name: user name 
* password: password 
* retry_time: retry times, can not over 3 times */

syntax = "proto3";  // proto3 syntax
option go_package = "pb/request";

message LoginRequest {
 string user_name = 1;
 string password = 2;
 int32 retry_times = 3;
}
协议版本

第一行定义了当前使用语法版本,最新的版本就是 proto3。也可以使用 proto2

协议字段类型

LoginRequest 消息体定义了具体的三个参数,每个参数都有具体的类型以及名字。每个字段都可以按照以下表格中的 .proto Type 来定义 – 并且最终应用在特定语言(Java + Go)中的类型也可在表中找到。

.proto TypeNotesJava TypeGo Typedouble
doublefloat64float
floatfloat32int32Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead.intint32int64Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead.longint64uint32Uses variable-length encoding.intuint32uint64Uses variable-length encoding.longuint64sint32Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s.intint32sint64Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s.longint64fixed32Always four bytes. More efficient than uint32 if values are often greater than 228.intuint32fixed64Always eight bytes. More efficient than uint64 if values are often greater than 256.longuint64sfixed32Always four bytes.intint32sfixed64Always eight bytes.longint64bool
booleanboolstringA string must always contain UTF-8 encoded or 7-bit ASCII text, and cannot be longer than 232.StringstringbytesMay contain any arbitrary sequence of bytes no longer than 232.ByteString[]byte
注释

Protobuf 支持 C/C++ 中的两种注释风格

  1. 斜线加星号 /* ... */

  2. 双斜线 //

2.2 代码生成Golang 代码生成
  1. 到 Protobuf 官方 Repo 下载对应平台的 protoc 工具

  2. 首先用 go命令安装生成Go代码的工具, 此工具为生成Golang代码的插件

    go install google.golang.org/protobuf/cmd/protoc-gen-go
  3. 生成最终的代码

    SRC_DIR: 源目录

    DST_DIR: 生成的代码目录

    protoc -I=$SRC_DIR --go_out=$DST_DIR $SRC_DIR/request.proto

    最终生成 request.pb.go文件,该文件不用修改,后期有任何更新可以重新生成。

  4. 将上述代码保存到 request.proto 文件中

Golang 代码使用

生成的代码可以直接在项目中使用

func main() {
 // 创建请求
loginRequest := request.LoginRequest{
UserName: "Gavin.Yang",
Password: "92d273941d98a8e1c1bb13ac163f0d4e40c5aa70",
RetryTimes: 0}

 // 序列化
out, err := proto.Marshal(&loginRequest)
if err == nil{
fmt.Println(out)
}
}

网友评论