摘要:程序员常会说:我最讨厌别人写的代码没有文档,我也最讨厌本身须要写文档。
有一个很老的梗: 我最讨厌别人写的代码没有文档,我也最讨厌本身须要写文档。前端
有这种想法的程序员应该算是一个老鸟了,对于大多数程序员来讲,对于他们来讲: 文档是什么。python
对于大规模,超大规模的项目,而且历时很长,须要大量人员协同开发的项目,没有文档简直不可想象。可是因为时间紧,任务重,大多数的项目中的开发者都没时间写文档,并且,文档也不计入考核指标,致使开发者也没有动机写文档。这就形成了不少项目都缺乏规范化文档,项目的交接和接口的对齐都是靠口口相传,接口定义准确度低,而且项目的总体开发效率低下。程序员
做为一个文档爱好者的笔者来讲,日常很重要的一件事儿就是将本身的工做概括总结并整理成文档。即使如此,笔者也面临着不少问题:正则表达式
- 需求很快就变了,光是改代码就已经耗尽了个人精力了,哪有时间同步文档。
- 要么先改代码,要么先改文档,总之文档和代码之间存在一个不一致错位期。
除此以外,因为咱们主要从事AI相关能力的研发,因此在开发过程当中还存在如下特殊的问题:编程
- 开发者不得不写大量重复的网络编程相关的业务代码,这些代码的质量一般不高,而且在后期的反复修改中变得愈来愈臃肿,从而难以维护。
- 由于重复的业务代码开发工做占比过大,严重压缩智能化研发人员在AI方面的精力投入,这就致使了企业投入大量人力却没法获得好的效果。
通过不断的摸索和实践,AIMS项目组采起了一套文档驱动的开发模式,能够有效地解决上述在项目中普遍存在的问题。flask
1. AI接口开发的特色
不一样于传统API的CRUD接口的开发,AI的开发模式一般包含了如下步骤:后端
- 数据清洗;
- 模型训练;
- 参数调优;
- API上线。
前三项都是咱们组的强项,也是咱们的工做重点。可是在实际工做中,倒是API上线消耗了咱们的大部分精力。AIMS项目组大都从事的是AI方向相关的工做,对于API的相关库flask、tornado也不是很熟悉,这就致使开发人员须要花大量时间去了解网络编程相关内容,开发出来的程序质量可能也不是很高。并且,在接口开发后,还须要准备一份Swagger UI给前端的开发人员,这又是一项繁重的工做。为了解决如上所述的痛点问题,AI接口开发就须要知足如下两个特色和需求:api
- API的核心函数是现成的;
- 须要将API开发工做量降到最低。
2. 文档驱动的开发模式
咱们发现API的接口文档中已经包含了实现API接口的全部信息。也就是说,API接口文档的信息熵和API接口代码的信息熵是同样的。所以,咱们只须要完成代码或者文档中的一项便可,另一项能够交给框架自动生成,这就避免了把一样一件事情重复作两遍的问题。考虑到文档不论从可读性、易写性仍是可维护性都赛过代码,咱们决定写文档,而后根据文档生成对应的代码。网络
咱们参考了OpenAPI Specification3.0.1标准,以及JSON Schema定义了一套API描述语言,开发者基于这个API描述语言撰写API文档。当完成文档时,API的开发工做也随之完成,大大节省了API接口的开发工做量。通过初步估计,使用文档驱动模式开发一个API接口,一般能够减小40%–70%的工做量。架构
3. AIMS框架介绍
为了实现文档驱动的开发模式,AIMS基于tornado实现了一套Web后端框架,以下图所示。
3.1. Application Router组件
每个API都会有一个路径,即一个正则表达式[1]。一个微服务中的多个API的全部路径会组成一个API路径列表。
当Application Router接收到请求时,会根据请求中的URI在路由表中查找。若是匹配到某一个Request Handler,路由模块会将请求转发给响应的Request Handler。若是全部的路径都不匹配,则返回404结果[2]。
3.2. Request Handler组件
Request Handler处理来自Application Router的响应,是AIMS架构的核心,而Document则是Request Handler的核心。在AIMS架构中,Document是指函数的文档,即__doc__。Request Handler是在服务的启动阶段动态生成的。
事实上,在AIMS架构图中,只有Document是开发者必须写的[3]。其它的组件都是由AIMS提供的,或者是由Document自动生成的,因此AIMS开发模式也被称为文档驱动型开发模式。开发者只须要维护Document便可,从而实现减小开发者工做量的目的。
3.3. Watchman组件
Watchman组件能够经过设置来订阅某些接口的异常,当被订阅接口出现任何异常时,Exception Handler便会触发Watchman组件。
由于Recorder组件记录了Arguments,Watchman甚至能够自动产生一个能够复现该问题的测试用例,方便开发人员定位问题。
3.4. Recorder组件
Recorder是一个采集器,能够采集每一次请求的全部细节信息,包括请求ID、请求参数、远程IP、被调用的接口、响应时间、工做目录和进程号等各类信息。这些数据具备如下两个做用:
- 系统的维护者能够利用Recorder中的数据快速定位,复现现网问题,能够看作是一个更强大的日志系统。
- 经过请求ID,训练数据收集系统能够将请求参数、响应数据与用户反馈数据关联起来,这就至关因而一条有标记的数据。
3.5. Logger组件
Logger是AIMS封装的日志模块,用法和python自带的logging.Logger使用方式一致,最大限度地下降开发者的学习成本。
4. 补充说明
咱们注意到,在AIMS架构图中,Argument Parser、Schema Checker、Swagger UI和OpenAPI Specification是同源的,即都是来自Document。这就不会出现文档(Swagger UI、OpenAPI Specification)与函数实现(Argument Parser、Schema Checker)不一致的状况。开发者也不须要同时维护Argument Parser、Schema Checker、Swagger UI和OpenAPI Specification相关代码。
以上就是文档驱动开发在AIMS框架中的优点,既下降了开发者的工做量,又解决了一致性的问题。事实证实,自动产生的组件质量也是优于开发者自行开发的代码,而且不易出错,从而提高总体服务的质量以及稳定性。
[1] 在AIMS开发中,这个字段是写在__doc__中的api_path字段中。
[2] 事实上,路由模块会将请求转发给NotFoundRequestHandler,而后由NotFoundRequestHandler进行响应。
[3] 在AI相关微服务开发过程当中,Function,也就是核心功能函数,是已经准备好的。
本文分享自华为云社区《文档驱动开发模式在 AIMS 中的应用与实践》,原文做者:zqmillet 。