从.proto扩展到API发布:Big Plus
从.proto扩展到API发布:Big Plus
从.proto描述到API发布与发现
从.proto文件到API发布与发现
关键词
- protobuf
- gRPC
- 客户端
- 服务端
- 注册中心,registry
- 注册器,register
- 发现,discovery
- 发布,publisher
- 服务化,service
- 服务端发现代理
- 服务端注册代理,这两个来进一步简化客户端与服务端的使用。
概述
上节提到的大多数关键词,已经出现在前面几篇文章当中,在此不再重述。
本文将从.proto API描述文件开始,逐步展开形成一个完整系统。
.proto文件作为简单的API描述语言,能够依赖其提供的相关工作,生成不同语言的API实现封装代码,很大程度上实现了自动化工作,减少接下来的编码工作,从很多角度来说是个不错的开始。
本篇文章旨在希望能够系统化描述这么一种服务系统的整体概念,把系统中的点通过某些机制串联起来,并补充一些没有抽出来独立成文的点,所以可能包含有不够详细的地方,可以看情况抽出来相应细化点做详细说明。
系统流程
==> others ==> client ==> etcd <==
|| || ||
.proto => go source => gobuild => server => register ==
|| ||
==> php source => server ==> ==> apidemo
|| ||
==> apidoc ==> deploy ==> ==> apiview
整个系统流程从开发到运行主要包括三条主线,
- 生成纯go语言的标准grpc服务框架代码
- 生成php语言的封装代码,或者其他语言封装代码。
- 生成供展示的文档,以及嵌入在文档中的演示代码。
从技术角度看,在主线上存在编辑、编译、运行、浏览环节。
不过由于只有一个源头,那就是.proto文件,后续的处理只是均依赖于此,
整体流程虽然比较长,还算比较清晰。
在理解整体流程的基础上,逐步实现不同模块,整合形式完整系统。
整合过程,尽量能够确保自动化的同时,兼顾系统流程灵活性与扩展性,以适应不同的应用需求场景。
API列表元信息与API发现标准规范
支持的元信息包括四个级别,包级别,服务级别,方法级别,字段级别
包级别和服务级别,有以下两个字段,版本,描述,示例URL,
方法级别,元信息更多一些,除了版本,描述之外,还需要定义方法类型,
字段级别,只有描述元信息字段。
当服务作为HTTP REST使用时,目录规范为,/version/package.service/method,并且默认使用POST提交API调用请求。并且,客户端实现应该包括这个路径的规范,不应该让调用端直接传递此规范格式的路径值,而是只让调用端传递其关心信息,版本号,方法名等,剩下的封装成规范路径的工作应该由客户端封装实现。
版本号,非常建议使用majar.minor两级方式,如1.0,1.5,2.0等。更多级别的版本号对于已经是细粒度的服务的情况下,个人认为不再需要了。
描述信息,非常建议不仅要一句话,而是非常详细的,达到能够直接提取完善的文档说明。
.proto API描述文件
.proto文件是整个系统的源头,也是系统的中心,其他部分都是为了.proto文件中描述的API更好的运行提供辅助。
.proto文件是一个规范,proto的意思是原型的意思,表示这个API实现和调用规范信息,
包括API名字,调用参数名字与数类型,返回值的参数与数据类型。
这些概念对于开发人员来说并不陌生,通过维护这个文件修改API,也还是比较容易接受的。
当然,.proto文件还是需要手写的,不过好在protobuf的文档还是非常好,即使用原有的语法描述,
还是能够提取到一些有用信息的,至少能够让服务运行起来,后面的API描述信息可以分步完成,逐步完善。
多服务组织模式的支持
服务组的拆分与合并。
需要构建工具链接实现。
每个服务,像开发时的每个函数/方法一样,可能隶属于某个类或者组中。
这些服务要组织起来,也需要和函数/方法一样分组,分模块,分包。
同一组里的服务API,在组织上,可以写在同一个.proto文件中,这是工具在打包时组织的最小粒度,即同一个.proto文件中的服务,会打包到一个服务进程中,要么全启动,要么全部禁用。但是请注意,这并不是API调用的最小粒度,因为一个.proto文件中完全可能包含多个API方法。
总的来说,该系统目前支持四级组织模式,
- 包级
- 模块级
- 服务级
- API级
该四级组织模式为树形结构,不支持交叉隶属于多个上级组织。
虽然在运行态时,不同的服务API可以按不同组合部署在不同的服务器上,但是对于源代码的组织,仍旧放在一个目录。这主要是为了打包工具的方便,能够把不同组合的服务API编译打包进不同的可执行程序,以便部署到不同的服务器提供服务。
当然目前的代码虽然存放在同一源码仓库中,实际上服务API的代码仍旧是按照插件式编写的,只是工具还不够完善,无法支持编译该仓库之外的服务API插件。
后续还考虑添加对本源码仓库之外的、符合本系统支持的服务API插件的编译打包工具的支持。
多协议的支持
- gRPC,
- HTTP
- WebSocket(暂不支持)
websocket,让API可以直接在页面上调用。
多协议支持,指的是在gRPC实现的服务的基础上,通过其他协议代理模块,
透明转发不同协议发送来的API调用请求,最终执行代码只有gRPC的实现。
这种方式,减少不同协议实现时的重复代码,同时减少了可能出现的系统缺陷。
但是由于不同协议支持的通讯功能的不同,可能不是所有的API都能够支持所有协议的访问。
这要求实现上至少应该能够检测到不支持的情况,通过错误号告诉调用端正确的使用方法。
比如,对于长链接的服务,可以使用gRPC协议,却不能使用http协议。
从实现上来说,不同协议支持有一个简易扩展接口模块,可以让不同协议的实现更清晰。
传输格式支持
- protobuf3
- json
- xml(暂未实现)
这是两种常用的通用通信传输格式,但这是与通信协议相关联的,比如gRpc协议仅支持protobuf3格式,而HTTP Rest协议仅支持json格式。
为了尽量重用服务的实现代码,不同的传输格式之间,需要格式转换模块,转换到gRPC的数据格式,从而对非gRPC协议实现服务的调用。
至于为什么是转换到gRPC协议数据格式,是因为gRPC使用的二进制协议,而且功能强大,能够很容易的兼容json格式,甚至其他的二进制协议数据格式。
虽然数据格式表现形式不一样,但数据格式应该都支持类似字段概念的表达形式,这样在实现的才能够在格式转换时根据所有字段名一一对应转换,对应关系参照.proto中定义的结构,转换部分并不做太多工作,一旦转换失败将响应失败。
转换实现目前支持所有的protobuf3支持的数据类型,包括原始类型,也包容器类型和嵌套类型。但是需要注意,字段数据类型间除了整数类型外并不做类型转换,比如在弱类型的json中: {"a": 123},那么.proto如果定义为string a = 1;则会导致转换失败;但是.proto中定义为int32,int64都是可以的。
流程扩展情况
添加扩展外围编译打包规范及工具的需求,以及流程扩展的工作范围与影响。
详见前面的”服务API组织“一节。
服务化进程实例管理
灵活的需求,对此并没有什么特别的,手动管理或者一些自动管理工具皆可以。
比如mesos等。
为了更灵活的进行服务进程的管理,在实现时做了一些小功能作为辅助手段。比如,实现时设计了一个命令行参数,service-port,用于指定服务使用的服务端口号,而不是使用默认的自动选择的端口号。
服务API 列表演示
上图 =============
========
关于Big Plus
其实想表达的含义就是一个大加号: +
纵向多服务支持,横向多协议支持,http/gRPC,让系统灵活扩展。
附后:实现功能点
模块列表与TODO
- 浏览 505 次
添加新评论