上图是一个被拆解的 SONY 相机,里面的元器件在工作的时候各司其职,只做自己擅长的领域。他们可以来自于不同的厂家甚至国家,在全球化的今天,大部分优秀的产品都在针对某个单点进化,寻求更优质的服务和技术。
其实对于软件技术来说也是一样,并且更像全球化的一个缩影。
Microservices 没有固定且单一的定义,随着时间的流逝以及技术的不断演进,业界却已经默默的形成了一些共识,可以总结出的特征包括以下下几点。
具体的微服务在整个架构中,通过通信协议相互传递信息 例如 HTTP。
微服务是可以独立部署的。
微服务是围绕业务组织具体的功能的。
微服务不限语言、数据库、硬件和软件环境来实现服务。
服务颗粒度小,支持消息传递,受上下文限制并通过自动化流程来构建和发布。
从以上总结来看,微服务间的信息交互是整个 MSA ( Microservice Architecture ) 的基础,通信 协议 的质量决定了基于此建立的服务是否简洁、高效、稳定、可扩展、易于维护。最终体在产品中就是用户体验,尤其是针对需要快速响应的服务,比如:支付、广告竞价等。而 Protocol Buffers ( 通常称为 Protobuf ) 正是此中的佼佼者。
至于为什么,我们可以参考以下这篇文章,这里不赘述。
Beating JSON performance with Protobuf LINK2. 快速使用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)中的类型也可在表中找到。
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) } }