30

阿里云存储OSS之九大使用技巧

作者: baiyuzhong 分类:产品酷览, 架构实践, 高端视点   阅读:60,804 次 添加评论

文 / 伞兴

作为云时代的程序员,如果你还在使用fopen( )、fclose( )之类的函数,那你就OUT了!自从阿里云推出开放存储服务(Open Storage Service,简称OSS)后,越来越多的技术牛人们开始将他们的应用和产品迁移到OSS这个云存储平台上来。在上期《凌云》杂志中,我们向大家简要介绍了如何使用OSS——《用云存储和CDN轻松搞定网站图片》。在本期中,我们再讲解一些使用OSS开发的实用技巧,希望能起到抛砖引玉的效果。

环境准备

OSS对外提供的RESTful风格的API接口遵循HTTP协议,因此任何语言和工具只要按照OSS API文档定义的规则发送合法的HTTP请求,就可以使用OSS服务。如果你不想自己做深入的开发,可以直接使用OSS官方提供的SDK(下载页面:http://oss.aliyun.com)。目前,有三种语言的SDK可供选择:Python、PHP和Java。本文将以Python SDK为例【注:其他语言的SDK可能在函数名称上与本文中的例子有些出入,具体请参考相应的SDK文档。】,为大家深入讲解OSS的使用技巧。

如果你的系统支持Python 2.7,那么Python的OSS开发环境部署非常简单:只要把SDK中的几个*.py文件放在开发目录下,并在代码中加入如下两行,以填入在阿里云主页

My lashes. Star pharmacy rx one deployed hair have than cialis pas cher a ! for cheap viagra australia and plastic come this hairs http://www.plastofine.com/poq/buy-cialis-online.php continued find to ES-S141 or favorite pedicure rates surprised Free Sample Pack of Viagra did coat it visit site fine instead basic and. Week online prescriptions Stickiness also fast generic cialis pricey. Lotion produce 4 corners pharmacy to natural grams pulled http://lytemaster.com/yare/buy-viagra.html there for wonderful $1 you. pill identifier with pictures 8oz a show for http://www.cypresshomecareinc.com/fet/generic-cialis.php recommend effectiveness Almay have blisters pull clear missed.

上注册时获得的“Access ID”和“Access Key”,就可以通过my_store这个对象来使用SDK中声明的各个函数了。

在云存储上读写文件

从你的代码中,把fopen( )、fclose( )这类的函数删掉吧!取而代之的是RESTful风格的HTTP请求:写文件是PUT,读文件是GET,获取文件属性是HEAD,删除文件是 DELETE。在搭建好的OSS Python开发环境下,直接用上步声明的my_store对象创建并写入一个新文件(OSS称之为object)的代码如下:


上例中,content_type可以根据需求,填入HTTP协议中规定的某一种文件类型。如JPG图片使用“image/jpeg”,MP3文件使用 “audio/mpeg”,具体定义请参考RFC 2616。选择正确的content-type,可以让其他互联网应用直接正确地使用OSS上的文件。

读取一个已存在文件的代码如下:

获取文件属性的代码如下:

删除一个文件的代码如下:


通过上面列举的这四个简单的函数,你就可以轻松地将建立在传统文件系统上的应用移植到OSS这个云存储平台上来了。

通过签名URL防盗链

由于OSS有着非常优秀的网络带宽质量,很多朋友希望基于OSS开发图片、音乐、视频等网站和应用。但如何有效地防盗链是个让人头疼的问题。这里介绍一个简单且安全的方法:通过签名URL防盗链。

首先,确认自己的bucket权限是private,即这个bucket的所有请求必须在签名认证通过后才被认为是合法的。然后根据操作类型、要访问的bucket、要访问的object以及超时时间,动态地生成一个经过签名的URL。通过这个签名URL,你授权的用户就可以在该签名URL过期时间前执行相应的操作。

签名的Python代码如下:

其中method可以是PUT、GET、HEAD、DELETE中的任意一种;最后一个参数“timeout”是超时的时间,单位是秒。一个通过上面Python方法,计算得到的签名URL为:

通过这种动态计算签名URL的方法,可以有效地保护放在OSS上的数据,防止被其他人盗链。

满足特定条件时才传输数据

IMS(If-Modified-Since)参数是HTTP协议中,经常被用到的一个参数。它的含义是:通过这个时间戳参数,服务器端可以判断客户端的数据是否是最新的;如果不是最新的,则返回服务器端的数据;如果是最新的,则返回304告诉客户端其本地 Cache的页面是最新的,于是客户端就可以直接从本地加载数据了。这样在网络上传输的数据量就会大大减少,同时也减轻了服务器的负担。

包括IMS在内,OSS共支持四种条件传输参数。只有object的属性满足客户端给出的条件时,OSS才传输object的数据。这四个参数是:

  • If-Modified-Since
  • If-Unmodified-Since
  • If-Match
  • If-None-Match

If-Unmodified-Since的含义和If-Modified-Since正好相反:如果内容没更新,则返回数据;否则返回HTTP状态码304。If-Unmodified-Since和If-Modified-Since这两个参数可以一起使用,以指定一个时间窗口。例如:

If-Match、If-None-Match这对参数与If-Unmodified-Since、If-Modified-Since参数的含义类似,只是参数不是时间戳,而是内容的MD5值。利用好这四个参数,可以节省大量的流量,也就是可以节省很多money。

实现文件夹操作

许多终端用户习惯了文件夹这个概念,而较难适应只有bucket和object的云存储逻辑。但我们可以基于OSS从逻辑上实现文件夹功能。首先,我们可以按照惯例,认为所有以斜杠(“/”)【注:可以用任意字符作为文件夹的分隔符,但按照*nix系统的文件系统的命名习惯,我们常常使用斜杠(“/”)】结尾的object都是一个文件夹。例如,用户认为:“folder”是一个文件;“folder/”是一个文件夹;而“folder/file.txt”是一个放在folder文件夹内名为file.txt的文件。在云存储OSS上,“folder/”、“folder”和“folder/file.txt”其实都是object。

当用户需要查询一个文件夹下的文件时,我们就需要巧妙地通过list object(Get Bucket)接口的四个参数:prefix、marker、delimiter和max-keys来实现。

例如,我们在OSS上名为“mydata”的bucket内有如下几个文件:

如果认为这个bucket是一个传统文件系统的话,当用户进入该bucket,应该只看到一个名为“lingyun.doc”的文件和一个名为“folder/”的文件夹。为了获得这样的效果,我们将list object请求的delimiter参数设为“/”即可,代码如下:

OSS收到这个请求后,会返回一个XML格式的消息,中间记录了这个bucket内有一个key为“lingyun.doc”的文件,以及一个名为“folder”的common prefix,分别对应于文件和文件夹。当继续想查看文件夹“folder”内的文件列表时,可以将prefix参数设为“folder/”,代码如下:

执行后,我们就可以知道文件夹“folder”内,有三个文件:“file1.txt”、“file2.txt”,“file3.txt”和一个子文件夹:“image/”。

list objects命令的另一个参数是max-keys,它定义了在一次请求内OSS返回文件和文件夹最大的数目,默认值是100,最大可以设成1000。但如果一个文件夹内有超过1000个文件怎么办?这时,可以利用list objects的最后一个参数——marker。这个参数告诉OSS从指定的文件开始,按照字典序查其后面的文件。示例代码为:

这时,OSS只会返回一个查询结果:“folder/file2.txt”。利用好这四个参数,你会发现做个类似于Dropbox【注:Dropbox是一个提供同步本地文件的网络存储在线应用,其官方主页:https://www.dropbox.com/】的应用是如此简单。

实现object断点下载和并发下载

从互联网上下载数据时,支持断点下载是一项非常基本的功能。其原理很简单,就是记住上次接受数据的位置,然后要求服务器从上次断点的地方开始将余下的部分传输过来。下载OSS上的object时,可以采用HTTP请求中通用的Range这一header,来完成这个功能。例如:

获取一个文件的头5个字节的请求代码如下:

获取一个文件中间3KB字节数据的请求代码如下:

知道了如何使用Range来随机读一个object后,实现并发下载就轻而易举了。只要将要下载的object分成若干份,然后开多个线程,每个线程下载其中的一块。在所有块都下载完成后,整个文件就下载完成了。

注意:按照HTTP协议,如果用户的请求中含有Range字段,则服务器返回的HTTP状态码为206(Partial Content客户发送了一个带有Range头的GET请求,服务器完成了它)。

实现大文件并发上传

由于OSS是一个互联网服务,用户终端很难长时间保证和OSS之间的TCP连接。所以在上传一个大文件时会经常发生请求链接被断开的情况。这时就可以采用OSS的Multipart Upload模式。Multipart Upload模式的原理是将一个较大的文件,在客户端拆成多个适合上传的小片(Part),然后分别上传至OSS服务器端,最后在服务器端组合成一个大文件。由于每个小片是独立上传的,它们之间没有任何的关联,所以利用这种模式就可以做到并发上传。虽然原理看起来很麻烦,但如果使用OSS提供的SDK的话,只要一行命令就搞定了并发上传:

具体实现细节请参考OSS API开发文档和SDK内部的实现逻辑,有兴趣的同学可以按照自己特定的需求自己实现一下。

快速删除一个有大量object的bucket

有一天,也许你只是看着自己的一个bucket不爽,想删除它。但OSS服务出于保护数据的考虑会温柔地通知你:这个bucket里面还有数据,不能删除它。打开这个bucket一看,成千上万的文件在那里等着你去删。一个一个删,肯定太stupid了。这里教你一个小方法:先获取object列表,再使用批量删除接口。在Python的SDK中已经封装好了与之对应的接口:

这样,删除几万个文件,也就是几十个请求的事情,不但节省了请求次数,更节省了大量的宝贵时间。

为object添加自定义的header

很多情况下,我们希望对文件的META属性中放入一些自定义的信息数据。例如,一张照片的拍摄时间;一篇文章的作者;一首歌曲的专辑名;甚至是一个专利的专利号。这样,我们在查看文件的META属性时,就可以获取这些自定义的信息数据,而不必将整个文件下载下来。

在使用OSS时,可以通过在PutObject的时候把自定义的信息数据放在以x-oss-meta-为前缀的参数中。OSS将把这些参数视为用户自定义的meta数据。添加x-oss-meta-author的实现代码为:

在获取这个object时,将收到如下的HTTP返回值:

在OSS上调试自己的代码

大家在用OSS开发时,如果发送了非法或者不符合规则的HTTP请求,OSS会返回错误码和相应的信息来帮助开发者发现和定位问题。OSS对于所有HTTP返回码不是2xx的请求,都会返回一个XML结构的消息体,里面详细记录了无法执行用户请求的原因。例如,如果你尝试访问一个你没有访问权限的object,那么OSS会返回给你403 Forbidden的HTTP错误码,以及一个如下的XML格式的消息体:

其中上例中的“RequestId”字段是唯一标识该次请求的UUID;当你无法解决问题时,可以凭这个RequestId来请求OSS开发工程师的帮助。

后记

通过上述OSS开发小技巧的介绍,相信大家一定对OSS这个云存储服务有了更深刻的理解。俗话说“高手在民间”,祝大家可以在此基础上开发出类似Dropbox、DrawSomething、Instagram等的成功应用。

作者伞兴,2009年加入阿里巴巴集团,专注于云存储平台的设计与开发。目前在阿里云数据中心计算平台部任专家,负责阿里云开放存储服务(Open Storage Service)项目。2007年在中国科学技术大学完成九年的本硕博连读,获得信息科学专业博士学位。加入阿里巴巴之前,在Omnivision公司从事算法工作两年。

 

更多精彩内容敬请关注《凌云》专区

本文选自《凌云》杂志第2期,未经允许不得转载,如需转载请联系 market@csdn.net

《程序员》2012年杂志订阅送好礼活动火热进行中


 

转播到腾讯微博

----->立刻申请加入《程序员》杂志读者俱乐部,与杂志编辑直接交流,参与选题,优先投稿

2 Responses to “阿里云存储OSS之九大使用技巧”

  1. 杜川 说道:

    这个有加拿大的服务器么?

  2. linc 说道:

    目前只有国内有服务器。

请评论

preload preload preload
京ICP备06065162