上图是一个被拆解的 SONY 相机,里面的元器件在工作的时候各司其职,只做自己擅长的领域。他们可以来自于不同的厂家甚至国家,在全球化的今天,大部分优秀的产品都在针对某个单点进化,寻求更优质的服务和技术。
其实对于软件技术来说也是一样,并且更像全球化的一个缩影。
Microservices 没有固定且单一的定义,随着时间的流逝以及技术的不断演进,业界却已经默默的形成了一些共识,可以总结出的特征包括以下下几点。
具体的微服务在整个架构中,通过通信协议相互传递信息 例如 HTTP。
微服务是可以独立部署的。
微服务是围绕业务组织具体的功能的。
微服务不限语言、数据库、硬件和软件环境来实现服务。
服务颗粒度小,支持消息传递,受上下文限制并通过自动化流程来构建和发布。
从以上总结来看,微服务间的信息交互是整个 MSA ( Microservice Architecture ) 的基础,通信 协议 的质量决定了基于此建立的服务是否简洁、高效、稳定、可扩展、易于维护。最终体在产品中就是用户体验,尤其是针对需要快速响应的服务,比如:支付、广告竞价等。而 Protocol Buffers ( 通常称为 Protobuf ) 正是此中的佼佼者。
至于为什么,我们可以参考以下这篇文章,这里不赘述。
Beating JSON performance with Protobuf LINK
让我们先来看一个非常简单的例子,假设我们需要定义一个登录请求,这个登录请求需要有 用户名
、密码
、重试次数
。我们可以将这个请求定义在一个后缀为.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 类型 | 注释 | Java 类型 | Go 类型 |
---|---|---|---|
双 | 双 | float64 | |
浮动 | |
浮点 | float32 |
int32 | 使用可变长度编码。编码负数效率低下 – 如果您的字段可能有负值,请改用 sint32。 | int | int32 |
int64 | 使用可变长度编码。编码负数效率低下 – 如果您的字段可能有负值,请改用 sint64。 | long | int64 |
uint32 | 使用可变长度编码。 | int | uint32 |
uint64 | 使用可变长度编码。 | long | uint64 |
sint32 | 使用可变长度编码。有符号 int 值。这些比常规 int32 更有效地编码负数。 | int | int32 |
sint64 | 使用可变长度编码。有符号 int 值。这些比常规 int64 更有效地编码负数。 | long | int64 |
fixed32 | 始终为四个字节。如果值通常大于 228,则比 uint32 更高效。 | int | uint32 |
fixed64 | 始终是八个字节。如果值通常大于 256,则比 uint64 更高效。 | long | uint64 |
sfixed32 | 始终为四个字节。 | int | int32 |
sfixed64 | 始终为八个字节。 | long | int64 |
布尔 | 布尔值 | 布尔 | |
字符串 | 字符串必须始终包含 UTF-8 编码或 7 位 ASCII 文本,且长度不能超过 232。 | 字符串 | 字符串 |
字节 | 可以包含不超过232的任意字节序列。 | ByteString | []字节 |
Protobuf 支持 C/C++ 中的两种注释风格
斜线加星号 /* ... */
双斜线 //
到 Protobuf 官方 Repo 下载对应平台的 protoc
工具
首先用 go
命令安装生成Go代码的工具, 此工具为生成Golang代码的插件
go install google.golang.org/protobuf/cmd/protoc-gen-go
生成最终的代码
SRC_DIR: 源目录
DST_DIR: 生成的代码目录
protoc -I=$SRC_DIR --go_out=$DST_DIR $SRC_DIR/request.proto
最终生成 request.pb.go
文件,该文件不用修改,后期有任何更新可以重新生成。
将上述代码保存到 request.proto
文件中
生成的代码可以直接在项目中使用
func main() { // 创建请求 loginRequest := request.LoginRequest{ UserName: "Gavin.Yang", Password: "92d273941d98a8e1c1bb13ac163f0d4e40c5aa70", RetryTimes: 0} // 序列化 out, err := proto.Marshal(&loginRequest) if err == nil{ fmt.Println(out) } }
以上是微服务间的通信--Protobuf的详细内容。更多信息请关注PHP中文网其他相关文章!