今年,个人任务是为公司的私有云平台( PaaS )开发对应的云服务平台(咱们称之为插件平台),这个云服务平台的主要任务,是为云平台接入一些服务,服务包括但不限于mysql、redis、cdn等存储服务,天气预报等http服务。这个系列文章,但愿总结本人在开发这个平台时的得与失。
下面将云服务平台简称为平台(插件平台),所接入的服务,简称为第三方服务(插件)html
统一接入方案,是指能够帮助插件平台更快接入第三方服务的一种统一方案mysql
首先要回答的第一个问题,是为何须要插件平台:web
云平台,是一个强大的开发平台,帮助开发人员完成从机器申请,项目部署,维护(动态扩容……)等一系列操做,像阿里云、腾讯云,都是国内这方面作的比较大的平台。一个完整的云平台,必然会接入一些第三方服务。简单的作法,固然是云平台本身完成这个事情。但随着平台及人员规模的扩大,一个很合理的分工,是将接入、管理、维护第三方服务的功能,做为一个独立的模块、平台。这样符合软件开发的解耦原则,具体来说,会有如下收益:redis
当云平台要升级改造时,不会直接影响到第三方服务。过往的逻辑链路,是云平台绑定了 N 个第三方服务,而有了插件平台,这个链路变成:云平台-> 插件平台 -> N个第三方服务。过往的状况是,云平台的一些变更,N个第三方服务可能要跟着修改。而如今,只须要由插件平台统一作变动,而插件平台到N个第三方服务这条链路,能够保持以前约定的规则不变。另外,云平台的一些部署、变动,也能尽可能少地影响到插件服务。sql
插件平台更专一于插件这个事情,能够把插件接入、维护这件事情作得更加极致。json
一个插件平台,能够对接多个云平台 。做为一个中间站,插件平台能够按照它和每一个云平台的约定进行对接,而后再按照插件平台本身的标准流程,和多个第三方服务进行对接。这样,每一个云平台上,等于都能接入插件平台提供的第三方服务。安全
能与开源社区结合,打造闭环“广大开发人员开源组件->孵化成熟->成为云平台第三方服务”,从而提供更多丰富的插件。这是咱们的实践结果。插件平台不只为云平台提供第三方服务,同时,咱们还开发了这么一个网站,每一个开发人员,能够到这个网站开源本身写的组件,若是以为合适,还能够将这个组件转成云平台适用的第三方服务。markdown
其次,解答统一接入方案的重要性和必要性:说究竟是为了两个字,"效率"。没有统一接入方案时,每来一个新的第三方服务,云平台开发人员就须要和第三方服务开发人员讨论肯定接口,而后一方(第三方服务)写接口,一方(平台)写调用逻辑,最后进行联调,很是麻烦。有没办法改善呢?固然是有,就是提供一个统一的接入方案,不论是什么第三方服务,都按照这套规范。平台的逻辑是通用的,要接入新的第三方服务时,无需开发。第三方服务要按照规范开发几个接口,再经过页面配置信息,而后就能接入了。从以前的两方联调模式,变成单边适配。app
首先作第一层抽象,以一个MySql服务为例,用户可能须要:建立、删除、变动、查看(基本参数)一个MySql实例。MySql服务在插件平台正式上线前,平台须要知道,如何调用MySql服务的哪些接口以作增删改差服务资源。所以,统一接入,其实就是解决平台和第三方服务如何对接这四个接口的问题。编辑器
调用第三方服务这几个接口时,如何断定操做是成功的(特别是建立、删除操做)
建立一个第三方服务实例,不一样的用户,须要建立的实例类型,多是不同的。如何统一?例如,有些项目须要建立带从库的 MySql ,有些项目不用。
平台发送请求时,要带上哪些参数。不一样服务,所需参数不同,怎么在不改平台带代码的状况下,让平台根据服务的不一样,带上不一样的参数。
操做成功及失败时,分别要返回哪些信息给用户。如何从第三方服务的接口响应内容中,提取对应的信息
如何让第三方服务开发者能够本身调试协议,而无需平台开发介入
在第三方服务正式上线时,平台管理员如何快速检查接口是否符合约定
既然称之为统一方案,那么一定就是要作这几件事情:制订一套行之有效的标准流程,定义简洁清晰的接口规范,提供相关的接入工具。
最终的流程以下
开发者按照约定,开发服务的增删改查接口
在云服务平台填写服务信息,使用测试工具测试ok后,提交管理员审核
管理员审核并上线
这是很常见的一个接入流程。下面咱们具体看看,咱们是如何更简洁解决上面提到的问题。
第三方服务在收到请求时,固然须要断定请求来源是否合法,是否来自插件平台。咱们提供了两种鉴权方式,供第三方服务开发者选择:
keystone
插件平台、公司的私有云平台,鉴权都基于 openstack 自身的 keystone 模块,该模块为服务间交互的鉴权,提供了一种统一方案。所以,和平台交互的第三方服务,也能够采用该方式。
这样有两个好处:
从云平台、插件平台、第三方服务,自上而下,鉴权都是统1、标准、可信任
不用本身造轮子
password
平台和服务之间约定一个密码,平台发起请求时,会在 Header 中带上该密码,服务在收到请求时,判断该密码是否和约定一致
这两个方式,前者略重,但安全可靠,后者略轻,却快速简单。 keystone 是 openstack 的标准方式,它的好处自没必要说,而 password 这个方式,是考虑到咱们是个私有云,能够减低安全要求,同时更要尽可能快速简单地接入第三方服务。
和下面要展开的“请求参数格式"同样,这里的关键,是如何抽离区分,平台的统一参数及不一样服务之间的差别参数。什么意思呢?哪些是统一的参数,哪些是差别参数。例如,不论是何种第三方服务,建立一个资源后,都须要返回操做的明确结果,资源的id。而其余的返回参数,则存在差别,例如一个 mysql 服务,还须要告知,资源的 url ,端口号,用户名,密码等,而图片服务,则可能提供一个存储路径 url 便可。
咱们是这样作的:请求、响应设计,遵循 RESTful 设计。RESTful 的特色:经过 HTTP 状态码能知道操做结果,经过 HTTP 方法能知道操做类型(增删改查),经过 Url 能知道操做的资源对象。这些特色,恰好和服务接入的标准不谋而合。所以,咱们约定:
请求响应码,操做成功返回200,不然返回4xx,5xx。平台只经过状态码来判断操做成功与否。
标准的返回内容(示例)以下:
{ "id": "68788943-d109-416b-983d-e3df70a9463b", "config_vars": { "port": "3306", "host": "d9888.mysql.oa.com", "slave_host": "fd9888.slave.mysql.oa.com", "default_db": "db_name", "user": "a742e2fe34d6", "password": "12345678" }, "message": "success!!!" }
上面是 MySql 服务的返回例子。对于全部服务,咱们都约定,返回格式统一使用 json,json第一级要包含 id ,message ,config_vars 这三个属性。其中,id 为资源 id,后续对该资源的删除,变动,都经过该id进行。message 为附带的消息,特别是操做失败时,方便告知用户失败的缘由。config_vars 中,会包含跟服务相关的差别参数,不一样服务的参数,是不同的。在最终的信息配置页面,提供了以下的配置功能
在该页面中,开发者能够配置 config_vars 中的参数。而平台在收到实际请求时,也会去验证 config_vars 中是否包含这些参数,以确保请求有效性。
上面咱们提到,同一个第三方服务,会有不一样的类型,并对应不一样的请求参数。仍是以MySql为例,假设咱们将参数的配置直接扔给用户,例如用户须要一个 MySql,页面提供好几个填写项:是否带从库、buffer 内容要多大,是否为 SSD 硬盘等等,用户本身填写,而后才能建立一个 MySql。这样是否会让用户以为很懵呢?用户能懂怎么填吗?用户是否真的须要这些选项呢?
为了让用户选择更加简易,咱们加入了套餐的概念。由第三方服务开发者定义几个套餐,例如,高级套餐对应配置比较高的服务,中级、低级套餐则配置低些。用户在选择时,能够先了解每一个套餐对应哪些参数,而后再肯定用哪一个套餐。当用户选择套餐(无需输入参数值)后,平台在后台组装对应套餐的实际参数,并调用第三方服务的接口。
做用 | Url | HTTP 方法 |
---|---|---|
添加插件(服务)到用户项目 | {url} | POST |
从用户项目中删除指定插件资源 | {url}/{id} | DELETE |
修改指定的用户插件资源参数 | {url}/{id} | PUT |
查看指定插件资源参数 | {url}/{id} | GET |
无论服务如何变化,总有一些信息是不变的,都要带上的。对于这些通用的信息,咱们会将其放在Header中。请求参数( request param )中不包含这些信息,更专一于跟服务相关的参数。
这些通用信息包括:
鉴权串。如上文提到的 keystone 串,password 串等
用户ID。哪一个用户在控制台要求插件平台发起这次请求
项目ID。例如,告知 MySql 服务,是哪一个项目要求建立一个 MySql 资源。
来源。控制台(前台)页面,是哪一个系统。用户能够在私有云平台上建立一个第三方服务资源,也能够在插件平台界面上建立。这是个辅助信息,没前三个那么重要。
一份请求内容示例:
{ "plan": "xxxx", "config": { "DISK": "SSD", "plan": "BASIC02", "MEMORY": "2", "REPLICATION": "0" } }
在调用POST(建立)请求时,会带上如上参数。和响应格式的约定同样,也是采用 json,第一级是约定的参数名plan,config。全部自定义参数会放在config中。在平台管理页面,提供了对应的配置能力。
经过下图所示,配置请求的参数名
经过下图所示,配置套餐及各个参数对应的参数值。支持配置接口参数值及在页面显示给用户的文本值。
用户在使用第三方服务前,能够经过页面了解该服务。咱们定义了一些关键信息,要求服务开发者填写:
插件名称。包含中文、英文名字。英文名字用于程序、接口的交互
类别
摘要。几十个字归纳说明
插件特色。对摘要的简单补充
图标。能够美化页面,一开始担忧开发者抱怨图标很差找。后来发现偏偏相反,不少很赞的图标。
套餐。
文档。详细的说明、使用文档。文档约定使用markdown,以带来更统一的文档阅读体验。
咱们提供了一个页面,帮助第三方服务开发者管理本身的插件(服务),包括了如下模块:
信息管理
基础信息编辑
服务配置,包括接口url,请求参数,响应参数,套餐配置
一个基于markdown的说明文档编辑器
接口测试工具
贡献率图表。经过云平台总项目数、插件数、使用量等,按公式计算贡献率,以反映该插件的价值
用户列表。使用该插件的项目列表。
第三方服务接入的一个痛点,就是两方要一块儿调试,这会浪费双方不少时间。所以,咱们设计了一个简单易用的web测试工具。
先晒一下界面
这个工具能够帮助开发者、平台管理员,快速测试第三方服务接口。打开该工具,能够看到:
请求url
请求body
指望返回
实际返回
测试结论
当用户点击右上角的“测试"按钮时,将按照图中所示的url及请求body进行测试,测试完毕后,将显示实际返回,并和指望返回作对比,得出测试结论。
实践证实,该工具备效提升了联调的效率。第三方服务经过该工具能够本身检查接口是否符合规范,而无需平台管理员介入。
首先,开篇提出现状,咱们须要为云平台提供一个平台,专门用于管理、接入第三方服务。当平台和第三方服务联调相应接口后,服务才能正式上线,普通用户才能经过平台来建立对应的第三方服务资源。为了更快地测试、接入第三方服务,平台须要定义一套对全部第三方服务都行之有效的规范。
而后,展开解决思路以下:
咱们先是梳理了不一样服务在接入时,接口、操做类型、请求参数、响应格式的相同点及不一样点,发现了RESTful设计理念和咱们接口设计至关契合,所以引入了RESTful来定义接口规范:同个服务的不一样操做类型(增删改查)对应同个Url,经过HTTP 方法来表达具体的操做类型。
请求参数、响应格式设计,努力求同存异,经过HTTP状态码来表达操做的结果,简单明了;而内容则约定为json格式——当前最流行的HTTP内容格式;在请求及响应内容的第一级,都是约定的参数名,将有差别,自定义的内容都指定放于某个指定参数中的第二级中,从而在内容格式上取得统一。
开发者经过页面填写自定义参数、各类套餐。这样平台就不用为了新接入一个第三方服务写代码,直接读配置,就能组装对应的请求格式。当用户选择套餐时,平台将把套餐对应的参数值发给第三方服务。
最后,为了方便联调,提升效率,还提供了一个强大的在线测试工具。固然,若是没有上述的规范,也没有办法造成标准的测试流程,没办法打造这款测试工具。