媒体处理开放平台
功能定位
在互联网时代,将算法、模型的处理能力,封装成一系列业务能理解的接口开放出去,供第三方开发者使用,这种行为就叫做Open
API,提供开放API的平台本身就被称为开放平台。
需求梳理
如:从0到1搭建媒体处理体系的架构图所示,开放平台包括以下功能:
功能 | 优先级 | 功能说明 | 备注 |
---|---|---|---|
协议转换 | T0 | 将千变万化的用户协议,转成内部的标准文件处理协议 | |
参数校验 | T2 | 确保入参满足要求 | |
鉴权 | T0 | 确保接入请求都合法,没有所谓的:水平越权 or 垂直越权 | |
计费 | T1 | 统计:调用次数、输入视频时长、使用cpu、gpu的时长等 | |
同步转异步 | T0 | 详见:同步转异步 |
协议转换
业务需求千变万化,很难通过定义一套标准,让所有人都按照固定的方式接入。因此,需要有一个系统去承接:将千变万化的用户个性化报文,转成内部的标准文件处理报文。
网关形态
站在用户视角来看:所见即所得,是比较好的用户体验方式。用技术术语来说,就是用户同步等待结果的显示。但是,对于大图片计算,长视频计算,往往也是非常费时的操作,极容易超时,因此,这就产生了2种产品形态:
形态1:同步等待结果模式。这个就不用展示了,太常见了。
形态2:任务列表模式。相关产品形态如下图所示:
备注:
1、任务列表模式中,前端处有一个后台线程,定时轮训后端的一个接口,获取处理结果。
2、虽然:云处理的网关,按照调用方式,分为:同步网关和异步网关。但这并不是说一定要搞2个代码库,大部分情况下,只有一个代码库,多个接口,不同的部署模式。
鉴权
本文不谈:为啥需要对接口进行鉴权?(毕竟,网上一搜有一坨的答案)。本文探讨下:媒体处理下的鉴权应该解决以下几个问题?
如何确保接口参数不被修改?
常用的解决方案是:将所有入参,按照一定的规律,计算一个HMAC摘要值。公式如下:
算法a(api_secret,参数1,参数2,参数3…) = sign_value,
客户端将sign_value放入到请求参数列表中去。
服务端使用同样的算法,再计算一遍,得出sign_value2,然后,对比客户端上传上来的sign_value1,是否一致,即可知道:是否有人篡改请求参数。
开放平台最好能提供sdk,方便计算sign_value。
如何确保接口访问者的合法性?
请求链接中带有:api_key,服务端根据api_key,获取到api_secret,再根据同样算法a算出: sign_value,跟客户端的上传过来的sign_value进行对比。
其中:api_secret得保密,得确保只有客户端 + 服务端知道。
如何确保请求的唯一性?
需要一uuid标记当前请求,假设客户端再次带上uuid时,服务端采用类似redis的技术方案,去判断uuid是否曾经访问过。若访问过,则拒绝请求。
1、通过http请求参数中,带上uuid
2、也可以通过带有ts的:query_string,一整串当做:uuid来处理
注意:要先检验请求的合法性,后再确保请求的唯一性
如何确保请求的有效期?
参数中,带上ts(当前时间戳),服务端收到请求后,通过计算时间差,若超过一定的阈值,则直接拒绝。
如何避免水平越权?
api_key与开通的接口(path),需做一个映射关系,避免越权行为的存在。
如何避免key过期失效?
api_key + api_secret,服务端得有效期 or 调用次数的设计,并且每隔一段时间,维护用户与api_key、api_secret之间的关系。
计费
功能 | 优先级 | 功能说明 | 备注 |
---|---|---|---|
按调用次数计费 | T0 | 例如:1000次/30元 | |
包月 | T0 | 月均: 30元 |
备注:
1、当然了,上面2种只是最简单的计费方式。另外,会有单独的文章,专门描述如何计费。ß
同步转异步
在分配计算资源触发计算之前,只有:文件url、文件大小等少量信息,不足于决策:分配合理核数的cpu or gpu。
因此,比较好的方式是:由机器自身根据当前自身负载情况去决策:应该计算多少量的视频个数,以确保整个集群资源负载更加均衡些,具体流程如下图所示:
备注:
1、在物理机时代,更是如此,若无:同步转异步功能,非常容易导致:部分机器非常忙,部分机器非常闲。
2、在容器化时代,通过cgroup的方式,在本业务场景下,虽说能够缓解一部分机器负载不均的问题,但是,不能解决根本问题,极容易造成成本的浪费。
3、底层计算域,最好统一通讯范式:异步回调。
4、底层cpu or gpu可以根据自己的实际负载来拖取相关任务发起计算。
5、当业务量大时,需采用:2阶段以上的资源分配机制,其中,第一阶段:可以由网关根据请求入参,去初步:分配使用哪个配置的:cpu池子 or
gpu池子去处理,然后,第二阶段:再由底层机器,根据当前负载决策并发处理:几个计算任务。
建议:单独搞一个:资源主动调度服务来处理, 相关章节,将会在:资源调度详细阐述,这里面只是粗浅地介绍下。
解决方案
经过抽象,想要搭建一套开放平台,包括以下模块,如下图所示:
鉴权设计
redis中keys设计
库表设计
接口设计
类别 | 通讯模式 | http请求方式 | 使用场景 | 耗时 | 备注 |
---|---|---|---|---|---|
处理类 | 同步 | Get | 针对单个文件做简单处理 | 耗时一般在300ms以内 | |
处理类 | 异步 | POST | 针对多个文件做复杂处理 | 耗时比较久 | |
状态查询 | 同步 | Get | 结果查询、进度查询 | 耗时一般在10ms以内 | |
控制类 | 同步 | DELETE、POST | 取消 | 耗时一般在10ms以内 |
处理类之同步请求
处理步骤:获取存储在小文件存储系统中的文件,触发cpu or gpu计算后,得到的文件的二进制信息。
GET请求:
1、图片处理:/api/v1/sync/image/{fn_code}?api_key=&ts=&sign=&url=
2、视频处理:/api/v1/sync/video/{fn_code}?api_key=&ts=&sign=&url=
响应报文:
1、二进制,处理后的图片 or 视频的二进制信息,一般情况下,可以直接在浏览器上展示
2、meta的json信息
处理类之异步请求
POST请求:
1、图片处理:/api/v1/async/image/{fn_code}?api_key=&ts=&sign=
2、视频处理:/api/v1/async/video/{fn_code}?api_key=&ts=&sign=
1 | { |
3、文生图:/api/v1/async/text/{fn_code}?api_key=&ts=&sign=
4、文生视频:/api/v1/async/text/{fn_code}?api_key=&ts=&sign=
1 | { |
异步接口响应报文
1 | { |
异步接口回调报文
1 | { |
状态查询
GET请求:
1、结果查询:/api/v1/result?api_key=&ts=&sign=&msg_id=
注意:此类情况下,无需做唯一性检测
响应报文
1 | { |
2、状态查询:/api/v1/status?api_key=&ts=&sign=&msg_id=
响应报文
1 | { |
控制类
1、取消
DELETE请求:/api/v1/cancel?api_key=&ts=&sign=&msg_id=
响应报文
1 | { |