Jump to Navigation

从.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

添加新评论

Plain text

  • 不允许HTML标记。
  • 自动将网址与电子邮件地址转变为链接。
  • 自动断行和分段。
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.


Main menu 2

Story | by Dr. Radut