阿里云 OSS Ruby SDK 开发手记 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
rockuw
V2EX    Ruby

阿里云 OSS Ruby SDK 开发手记

  •  
  •   rockuw 2016-03-14 19:52:57 +08:00 5950 次点击
    这是一个创建于 3548 天前的主题,其中的信息可能已经有所发展或是发生改变。

    阿里云 OSS是一个对象存储服务,类似于 Amazon 的 S3 。相比于自建存储,使用 OSS 能够迅速帮您搞定存储,并且大大地节省成本,提升可靠性和安全性。

    现在,喜欢 Ruby 的同学终于可以优雅地使用 OSS 了。先看看 Rubyist 如何上传和下载文件吧:

    require 'aliyun/oss' bucket = Aliyun::OSS::Client.new( endpoint: 'http://oss-cn-hangzhou.aliyuncs.com', access_key_id: 'xxx', access_key_secret: 'yyy').get_bucket('bucket') bucket.put_object('ruby') { |s| s << 'hello world' } bucket.get_object('ruby') { |c| puts c } bucket.put_object('rails', :file => '/tmp/x') bucket.get_object('rails', :file => '/tmp/y') 

    是不是 so easy ? OSS SDK for Ruby 支持 OSS 目前绝大部分功能,主要的 highlights 包括:

    • 顾名思义的接口 put_object/get_object/list_buckets/list_objects
    • block 风格的代码
    • iterator 形式的列表
    • 流式上传 /下载
    • 断点续传上传 /下载

    下面我们随便挑几个来聊一聊:

    1. iterator 形式的列表

    OSS 用户在一个 bucket 下可能有成千上万的 objects ,所以 OSS 不会将 object 列表一次性全部返回,每次最多返回 1000 条。如果我要列出前 1001 个 object 怎么办?一般来说用户可能要调用两次接口。但是在 ruby 中你只需要一行:

    bucket.list_objects.take(1001) 

    再比如用户要找 files/下文件名包含'ruby'的文件:

    bucket.list_objects(prefix: 'files/').find { |x| x.key.include?('ruby') } 

    是不是非常方便?

    2. 流式上传

    流式上传允许用户动态地一边生成内容,一边上传到 OSS ,上传的数据可以 generated on the fly 。如下面的例子:

    bucket.put_object('numbers') do |stream| (1..1_000_000).each { |i| stream << i << "\n" } end 

    注意:这里并不是要 100 万个数字都生成完后再发送,而是一边生成一边发送的。

    要做到上面的效果并不容易,试想一下,put_object要如何调用所接受的 block 参数?如果调用那么 100 万个数字都一口气生成完了,所以,如何能做到对一个函数调用一半? 答案就是使用Fiber

    def hello puts 'hello' Fiber.yield puts 'world' end def world fiber = Fiber.new { hello } puts 'first' fiber.resume # puts 'hello' puts 'second' fiber.resume # puts 'world' end world 

    类似上面的代码,stream#<<内每接受一部分内容,会将自己 yield 出去,这样已经接受的内容就可以立即发送出去。有兴趣可以查看SDK 代码

    3. 断点上传

    在上传大文件时如果中途失败了,要重新上传是不是很沮丧?有了断点上传,中途失败后可以接着上次的进度继续上传。在 ruby 中只需要:

    bucket.resumable_upload('object_key', 'local_file') 

    断点上传依赖于 OSS 提供的 multipart 功能,类似于一个事务:

    • 开启一个 multipart 上传 (begin transaction)
    • 将文件分成多个 part 分别上传 (do modify)
    • 完成此次 multipart 上传 (commit transaction)

    只有最后一步成功后文件才算上传成功,在此之前文件对用户是不可见的。

    文件被中断后如何恢复上传?如何知道哪些 parts 已经上传成功?这需要记录事务的状态信息。 SDK 的做法是将这些信息(称为 checkpoint )保存在一个本地的 json 文件中。每上传完一个 part 就更新一次 checkpoint 。恢复上传时从 checkpoint 文件中恢复上传的进度。

    另外断点上传 /下载中也利用多线程实现加速,先看结果:

    $ruby tests/test_large_file.rb -n test_large_file_1gb Run options: -n test_large_file_1gb --seed 7587 # Running: user system total real Upload with put_object: 20.810000 1.880000 22.690000 ( 62.843336) Upload with resumable_upload: 28.720000 9.740000 38.460000 ( 33.963555) Download with get_object: 17.300000 4.550000 21.850000 ( 47.132476) Download with resumable_download: 23.260000 9.530000 32.790000 ( 31.883211) 

    Ruby 或者 Python 的多线程一直是个“迷”,但是对于这种 IO 多场景,用多线程效果还是很明显的。因为进行 IO 的标准库函数在需要等待 IO 时会将当前线程切出去。参考: http://yehudakatz.com/2010/08/14/threads-in-ruby-enough-already/

    一个简单的 demo

    借助 rails ,可以在 15 分钟内搭建一个oss 文件管理器,可以查看 /上传 /下载文件,效果图如下:

    QQ20151202_0

    更多

    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     807 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 20:08 PVG 04:08 LAX 12:08 JFK 15:08
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86