高德文件直传能力建设

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,恶意文件检测 1000次 1年
对象存储 OSS,内容安全 1000次 1年
简介: 1.文件上传之痛在没有这个基础能力之前,客户端要实现文件上传有这么几种方式:业务服务端通过对接OSS SDK搭建文件上传的能力,通过高德网关(或SNS网关)暴露对端的接口实现文件上传客户端直接本地写死AK、SK对接OSS的SDK实现文件上传这两种方式都有很明显的弊端。网关在设计上本身不适合做大文件的上传,影响网关的吞吐量,容易给网关带来很大的稳定性风险。另外对于业务服务内部也是不友好的,大文件长时

1.文件上传之痛

在没有这个基础能力之前,客户端要实现文件上传有这么几种方式:

  1. 业务服务端通过对接OSS SDK搭建文件上传的能力,通过高德网关(或SNS网关)暴露对端的接口实现文件上传
  2. 客户端直接本地写死AK、SK对接OSS的SDK实现文件上传

这两种方式都有很明显的弊端。

  1. 网关在设计上本身不适合做大文件的上传,影响网关的吞吐量,容易给网关带来很大的稳定性风险。另外对于业务服务内部也是不友好的,大文件长时间阻塞线程,造成系统吞吐量下降,如果是C端大流量应用的话,这个影响更加明显,高耗时和低耗时接口应该做隔离。
  2. 容易造成AK泄漏,有很大的安全性风险。OSS资源一般都是后端维护的资源,把密钥暴露给前端,也是不太合理的做法
  3. 同时也无法做大文件上传,断点续传这样的能力

高德作为一个日活过亿的国民级APP,有很多场景都有文件上传的诉求,每天都在经历着类似如上的各种问题,有没有一种更高效的方式实现文件上传,为业务方提效?

2.方案调研

经过调研发现,OSS提供了一种临时授权的方案,可以让客户端在保证安全的情况下和OSS做直连,这样就不需要服务端提供上传接口同时客户端很容易使用OSS提供的大文件上传、断点续传等能力。方案如下图所示:

您可以通过STS服务给其他用户颁发一个临时访问凭证。该用户可使用临时访问凭证在规定时间内访问您的OSS资源。临时访问凭证无需透露您的长期密钥,使您的OSS资源访问更加安全。

这个方案的优点也很明显:

  • 服务端持有AK,加密存储防止泄漏
  • 服务端下发临时Token,安全性更高
  • 客户端直连OSS,避免服务端性能瓶颈,可以很方便做大文件上传,断点续传等能力

这个方案里最大的不确定性就是在诺曼底走通STS认证的完整流程。刚入职不太清楚内部申请阿里云资源都是通过诺曼底,就直接在阿里云上申请,一路走下来很顺利。后来发现需要在诺曼底申请资源,才发现这里面的坑相当多,各种账号权限的不通,花了整整一周才搞定整个流程。

根据踩过的坑,整理了一个OSS对接STS认证模式接入的文档。有需要的可以看下(看过的都说靠谱^^)

参见:OSS对接-STS认证模式接入参考文档 

3.设计目标

满足各多场景的用户资源(视频、图片等)上传诉求,为客户端以及业务服务提供统一的平台化文件上传服务。架构设计上联合客户端,对上层业务屏蔽资源上传的技术细节,提供统一的上传方式,同时平台能力上提供断点续传、回调通知等系统能力,以及 提供业务维度的准入管控、资源管控等资源维护能力。

4.方案设计

4.1.方案概述

我们需要搭建一个文件上传的服务,处理STS授权相关的事情,比如临时token的生成、下发以及缓存更新的事情。还需要搭建一个文件上传的后台,进行业务方注册申请,oss相关的配置。后期提供基于bizId的统计分析功能。

对端SDK能力的支持,提供多种上传下载的能力包括

  • 简单上传
  • 断点续传上传及下载
  • 分片上传

4.2.上下游整体链路

主要分为三大部分:

  • 客户端基础SDK。主要做凭证获取、Token过期自动刷新、断连重试、文件上传下载等能力
  • 文件上传服务。承载凭证下发的核心能力,通过读取业务配置,从OSS获取临时Token,过期自动刷新,保证Token的可用性
  • 服务管控平台。主要做管控相关的能力,业务方的接入、配置上下线。对接MTEE,风险挖掘识别。

4.3.文件上传交互流程

一个文件上传的完整流程。这个流程是基础SDK和服务端的交互流程,对于业务客户端来说是无感的。

4.4.AK托管如何保证安全性?

在这套方案里,需要业务方申请OSS资源,提供AK、SK给到文件服务进行配置,分配对应的bizId。所以需要保证AK的安全性。集团有提供无AK化托管的方案。但是经过调研发现没法满足当前的场景。集团无AK化方案只能跟应用绑定,但是在文件服务里,资源都是业务方申请的,绑定的应用各不相同,文件服务也不好提供统一的应用供业务方绑定。所以这条路走不通。最终采用最常规的方案,利用KeyCenter实现AK的托管。

业务方申请配置中保存ak的密文,在获取token时调用KeyCenter接口解密获取明文,再调用OSS的认证接口获取临时token。实际测试发现KeyCenter解密的耗时在200ms左右,对接口的吞吐量影响很大。因此做了一些优化:在项目启动时,通过对密文解密,生成明文AK,加载到内存中,后续使用ak时直接从内存中获取。大大降低了接口RT。

4.5.临时Token缓存方案设计

获取临时Token,OSS限制了一个账号每秒最多只能请求100次。如果客户端频繁请求临时令牌,会导致oss封禁接口。

解决方案,服务端缓存token。缓存过期时间可配置,要比真实的过期时间早过期。这样可以保证客户端拿到的token的最小可用时间(比如10分钟)。同时为了避免缓存失效时所有请求都打到OSS的情况,加入了分布式锁的控制,同一时刻只能有一个请求生成临时token,其他请求排队等待。

4.6. 性能方面的一些优化

其实这些优化点在上面都已经提到了。主要有三点

  • 为了解决AK密文解密耗时的问题,采用项目启动时并发解密获取明文AK、SK,常驻内存。
  • 为了减少缓存Token过期重新获取临时的Token带来的毛刺波动,采用定时任务异步刷新Token,这样能保证所有请求都能从内存直接获取临时Token,能保证很好的接口响应表现
  • 获取临时Token时的分布式锁控制,避免触发OSS的限流规则。

通过以上的动作,客户端SDK获取Token就变成了纯内存的查询操作,RT是非常低的。

4.7 其他概念介绍

在设计上为每个租户生成一个bizId,bizId对应子账号、角色、权限、endpoint、bucket这些概念,他们之间的关系如下图所示

每个账号生成临时token都可以设置单独的权限policy(比如控制生成的Token只有可读、可写,某一目录的权限),在进行业务配置时可以指定。配置示例如:

"policy":{
            "Version":"1",
            "Statement":[
                {
                    "Effect":"Allow",
                    "Action":"oss:*",
                    "Resource":[
                        "acs:oss:*:*:amap-architecture",
                        "acs:oss:*:*:amap-architecture/*"
                    ]
                }
            ]
        },

CDN加速

对于大流量的场景,需要配置CDN加速访问,具体可参考

https://yuque.antfin.com/eio17z/iq5svr/ar43cd 《如何开启CDN加速》

4.8. 压测数据分享

单机(4C8G)可承载2500QPS,RT在55ms以内,CPU利用率峰值36%

https://yuque.antfin.com/eio17z/iq5svr/xgfuxb 《压测报告》

5. 说了这么多,如何使用呢

详细的使用文档见:https://yuque.antfin.com/docs/share/3e28b8c5-5ce5-4025-834f-519cb849670f?# 《OSS直传-业务接入流程》

总结一下接入步骤:

  • 在诺曼底完成账号申请,资源申请
  • 提供资源信息由平台分配bizId(目前通过发邮件申请,后期会提供后台能力自行申请创建)
  • 拿到bizId,发起调用。
  • 客户端SDK接入的流程

客户端调用代码示例:

重要提示:由于文件在OSS服务端是通过 ossSaveDir + 本地文件名的方式存储的,相同的文件名会覆盖,因此接入前辛苦业务方确认下,是否需要保证文件的唯一性。可以在 ossSaveDir 中加入类似UID,或者时间戳来保证文件的唯一性。

上传方案一:AJX切面接入

/// 上传
const uploadObj = {bizId: (申请的bizId,例如: 111000_fileservice-read_aos_c1), fileLocalPath: (本地文件绝对路径,例如: file:///sdcard/xxx/yyy/demo.txt), ossSaveDir: (远端存储路径,以"/"结尾,例如:a/b/)};
requestId = natives.oss.uploadFile(uploadObj, (error, result) => {
              if (result) {
                const res = JSON.parse(result);
                ajx.app.toast(`result:${res.msg}`)
              }
            }, (progress) => {
              const prog = JSON.parse(progress);
              if (prog) {
                ajx.app.toast(`${prog.progress}`)
              }
            });

/// 取消上传
natives.oss.cancel(requestId);

上传方案二:Native接入

/// 1、创建upload对象
GDOSSUploadRequest *uploadRequest = [[GDOSSUploadRequest alloc] init];

/// 2、申请的bizId,例如:111000_fileservice_aos_c1
uploadRequest.bizId = @"111000_fileservice_aos_c1";

/// 3、本地文件绝对路径
uploadRequest.fileLocalPath = [[NSBundle mainBundle] pathForResource:@"LargeFile" ofType:@"zip"];

/// 4、远端存储路径,以"/"结尾,例如:a/b/
uploadRequest.ossSaveDir = @"a/b/";

/// 5、上传
NSString *requestId = [AMapNetworkService uploadWithRequest:uploadRequest progress:^(NSInteger progress, int64_t current, int64_t total) {
        
} completion:^(GDOSSUploadResponse * _Nonnull response) {

}];

/// 取消上传
[AMapNetworkService cancelOSSRequestWithId:requestId];

注意:如果上传的文件名有特殊字符(空格,加号等),返回的 objectName 也会带有特殊字符。业务方自己拼接 URL 做下载时,需对 URL 进行 urlEncode 处理,否则 URL 无效。

下载方案一:AJX切面接入

/// 下载
const downloadObj = {objectName: `下载文件名`, localPath: `下载文件的绝对路径.文件后缀名,例如:file://documents/oss/media/tmp/a.file`, bizId: `申请的bizId,例如:111000_fileservice_aos_c1`};
downloadTaskId = natives.oss.downloadFile(downloadObj, (error, result) => {
        						if (error) {
           						ajx.log.print(error);
        						} else {
             						if (result) {
                   				 const res = JSON.stringify(result);
                    			 ajx.log.print(`${downloadTaskId} result:${res}`);
                				} else {
                   				 ajx.log.print(`download result is empty`)
              		 		  }
       					 		}	
        				  }, (progress) => {
            				if (progress) {
                			ajx.log.print(JSON.stringify(progress))
            				}
        					});
/// 取消下载
natives.oss.cancel(downloadTaskId);

下载方案二:img标签接入

/// img标签加载图片
<img src="oss://111000_fileservice_aos_c1/test/33333.jpg" style={{ 'width': "500px", 'height': "500px", 'border-radius': '70px' }} />

下载方案三:Native接入

/// 1、创建download对象
GDOSSDownloadRequest *request = [[GDOSSDownloadRequest alloc] init];

/// 2、申请的bizId,例如:111000_fileservice_aos_c1
request.bizId = @"111000_fileservice-read_aos_c1";

/// 3、下载的文件名
request.objectName = [NSString stringWithFormat:@"test/bigfile.zip"];

/// 4、下载的本地绝对路径
request.destinationPath = @"AbsolutePath/bigfile_0.zip";

/// 5、下载
NSString *downloadRequestId = [AMapNetworkService downloadWithRequest:request progress:^(NSInteger progress, int64_t current, int64_t total) {
        
} completion:^(GDOSSDownloadResponse * _Nonnull response) {
        
}];

/// 取消下载
[AMapNetworkService cancelOSSRequestWithId:downloadRequestId];

就先介绍到这里。

整理了一些常见的问题,需要时自取

https://yuque.antfin.com/docs/share/b047d959-7adc-46bb-a47d-c5514fde4050?# 《OSS直传能力接入常见问题》

6.接入情况

目前已有足迹、停车点记录、用反、评论,趣游等九个业务方接入,每日业务传文件量5w+。欢迎更多的业务场景接入,为大家提效。

7.后期规划

  • 自动化接入平台建设。目前申请流程比较繁琐,需要很多道申请审批流程,配置也较多,很容易出错。终极目标是提供自动化接入的能力,把诺曼底上的申请流程实现自动化对接,让业务方的申请过程变得丝滑
  • web端文件上传能力建设。目前的上传支持AMAP里的上传诉求,对于WEB端的上传还不支持,后期需要补齐这一块能力
  • 统计分析&风控能力。提供基于bizId 维度的风控配置、统计分析等能力。

开发团队:

移动架构部:郝仁杰、呼唤、陈腾蛟、任涛

技术服务平台自主出行服务端:魏国兵、闻钟

有相关业务场景接入,欢迎加钉钉群沟通: 33253097

相关实践学习
借助OSS搭建在线教育视频课程分享网站
本教程介绍如何基于云服务器ECS和对象存储OSS,搭建一个在线教育视频课程分享网站。
目录
相关文章
|
5月前
|
数据采集 传感器 人工智能
大数据关键技术之电商API接口接入数据采集发展趋势
本文从数据采集场景、数据采集系统、数据采集技术方面阐述数据采集的发展趋势。 01 数据采集场景的发展趋势 作为大数据和人工智能工程的源头,数据采集的场景伴随着应用场景的发展而变化,以下是数据采集场景的发展趋势。
|
11月前
|
数据采集 数据可视化 JavaScript
如何接入神策平台
如何接入神策平台
|
5月前
|
数据采集 供应链 前端开发
电商企业如何构建一站式数字化供应链体系|API接口实现淘宝/京东/1688多平台商品采集+上传一站式供应链系统搭建
网络时代,企业面临转型。如今进入数字化时代,企业再次面临重大变革,全面实现数字化、智能化已是当务之急。公司将继续良性发展,请记住16个字:精简流程、降低成本、提高效率、智慧管理。主流电商平台API商品数据采集接口,不但可以在商品采集上为供应链提供大量商品,同时我们也可以通过申请官方商品上传商品发布API接口,实现商品的多平台发布。
|
5月前
|
小程序 搜索推荐 视频直播
您有一份餐饮行业数字化解决方案待接入!
您有一份餐饮行业数字化解决方案待接入!
132 11
|
11月前
|
运维 搜索推荐 API
带你读《构建企业级好数据(Dataphin智能数据建设与治理白皮书)》——9. 开放能力:自由拓展,满足企业个性化需求
带你读《构建企业级好数据(Dataphin智能数据建设与治理白皮书)》——9. 开放能力:自由拓展,满足企业个性化需求
287 0
|
数据采集 安全 大数据
大数据数据采集的数据来源的第三方服务数据之第三方平台的运营数据
大数据已经成为数字时代最重要的资源之一,而数据采集则是大数据处理的第一步。在实际应用中,大多数企业都需要采集来自不同来源和渠道的数据,这些数据会在后续分析中被用于决策和预测。
184 0
|
Web App开发 存储 编解码
《2023云原生实战案例集》——04 互联网——新东方 基于函数计算实现直播流实时转码
《2023云原生实战案例集》——04 互联网——新东方 基于函数计算实现直播流实时转码
|
云安全 安全
一图读懂云安全中心2.0,一体化安全运营加速落地
一图读懂云安全中心2.0,一体化安全运营加速落地
216 0
|
人工智能 云计算 开发者
《云端智创—云端智能媒体生产技术解析与实践》电子版地址
本书基于阿里云开发者社区的DeepVideo训练营,搜集整理了阿里云视频云的资深导师们的精彩演讲内容,与各位开发者和视频制作技术朋友分享。
86 0
《云端智创—云端智能媒体生产技术解析与实践》电子版地址
|
SQL 数据采集 运维
Dataphin V3.7 版本发布!通过国产化适配、数据研发体验优化、数据治理能力提升和标签平台,帮助企业加速构建数据中台
本次发布的V3.7版本中,Dataphin重点围绕资产建设平台的易用性及可交付性、资产治理平台的完备性以及基础平台的稳定性和开放性进行优化与升级。通过国产化支持适配、数据研发体验优化、数据治理能力提升和标签平台,帮助企业加速构建企业级数据中台,轻松拥有好数据!
Dataphin V3.7 版本发布!通过国产化适配、数据研发体验优化、数据治理能力提升和标签平台,帮助企业加速构建数据中台