当前位置:网站首页>使用函数计算打包下载OSS文件【遇坑锦集】

使用函数计算打包下载OSS文件【遇坑锦集】

2022-08-11 10:35:00 蓝枫秋千

前言

项目中的oss服务器未来不打算继续续费了,接下来想要把所有的文件进行备份到本地进行留存

权衡了官方文档几种方式之后选择了函数计算的方式

原因主要是:有一个bucket当时没有处理好,所有文件存储到了bucket的根目录下面,而不是子目录,导致无法直接选中文件或者目录下载(因为根目录下有好几万的文件)

步骤

先根据官方文档来进行函数计算的部署

开始踩坑

  1. 函数计算已经顺利的部署上去了,但是点击测试代码运行报错,如下

    {
          
    "errorMessage": "No JSON object could be decoded",
    "errorType": "ValueError",
    "stackTrace": [
    [
    "\\u00a0\\u00a0File \"/code/main.py\"",
    "line 28",
    "in main_handler",
    "evt = json.loads(request_body)"
    ],
    [
    "\\u00a0\\u00a0File \"/var/fc/lang/python2/lib/python2.7/json/__init__.py\"",
    "line 339",
    "in loads",
    "return _default_decoder.decode(s)"
    ],
    [
    "\\u00a0\\u00a0File \"/var/fc/lang/python2/lib/python2.7/json/decoder.py\"",
    "line 364",
    "in decode",
    "obj, end = self.raw_decode(s, idx=_w(s, 0).end())"
    ],
    [
    "\\u00a0\\u00a0File \"/var/fc/lang/python2/lib/python2.7/json/decoder.py\"",
    "line 382",
    "in raw_decode",
    "raise ValueError(\"No JSON object could be decoded\")"
    ]
    ]
    }
    

    原因是无法读取到event.json这个文件,咨询了阿里云售后工程师给出的结论是,当前python2.7的版本已经无法读取了,需要修改代码,直接将json配置写到main文件中

    代码如下,main.py文件的20行到40行左右,修改的位置见注释

    def main_handler(environ, start_response):
        LOG.info('event: %s', environ)
        try:
            request_body_size = int(environ.get('CONTENT_LENGTH', 0))
        except (ValueError):
            request_body_size = 0
        request_body = environ['wsgi.input'].read(request_body_size)
    
        # 这一行注释的原因是因为python2的运行环境中 wsgi.input确实不能接收配置了. 这里接收配置主要是wsgi接收 event.json
        # evt = json.loads(request_body)
        evt = {
          
            "region": "cn-zhangjiakou",
            "bucket": "zhushang-applet-code",
            "source-dir": "test/"
        }
        context = environ['fc.context']
    
        oss_client = get_oss_client(evt, context)
        ret = _main_handler(oss_client, evt, context)
    
        status = '302 FOUND'
        response_headers = [('Location',sign_url(oss_client, ret))]
        start_response(status, response_headers)
    
        return "ok"
    
    
  2. 官方文档上说,如果想要下载根目录下的文件,使用./即可

    在这里插入图片描述
    实际上,我按照他这么修改之后,运行的时候,并没有效果,本地会在下载到一个只有22B且无法解压的压缩包,并且oss上面并没有对应的压缩包,也就是意味着失败了

    最后做了多种测试之后,发现使用""空字符串作为目录的话是可行的

    代码如下

    evt = {
            "region": "cn-zhangjiakou",
            "bucket": "zhushang-applet-code",
            "source-dir": ""
    }
    
  3. 下载的文件打包压缩后太大导致失败

    运行代码报错如下:Zipfile size would require ZIP64 extensions

    {
          
        "errorMessage": "Zipfile size would require ZIP64 extensions", 
        "errorType": "LargeZipFile", 
        "stackTrace": [
            [
                "\\u00a0\\u00a0File \"/code/main.py\"", 
                "line 37", 
                "in main_handler", 
                "ret = _main_handler(oss_client, evt, context)"
            ], 
            [
                "\\u00a0\\u00a0File \"/code/main.py\"", 
                "line 52", 
                "in _main_handler", 
                "return zip_files(oss_client, source_dir, source_files, dest_file)"
            ], 
            [
                "\\u00a0\\u00a0File \"/code/main.py\"", 
                "line 116", 
                "in zip_files", 
                "task_q.run()"
            ], 
            [
                "\\u00a0\\u00a0File \"/code/task_queue.py\"", 
                "line 40", 
                "in run", 
                "raise self.__exc_info[1]"
            ]
        ]
    }
    

    在网上找到一篇靠谱些的博客

    里面说,由于python 2.7 脚本限制,超过2G就会报这个错,需要修改一下配置,能提高到4G(但是实际上我压缩了20多个G的也是可以的

    修改代码如下,main.py文件的80-100行左右修改这个函数的一行

        def producer(queue):
        mem_buf = MemBuffer(queue)
        # 默认的压缩文件最大只支持2G,使用这个方式可以做到支持4G
        zip_file = StreamZipFile(mem_buf, 'w', allowZip64=True)
    
        if isinstance(source_files, list):
            for obj in source_files:
                zip_add_file(zip_file, obj)
        elif isinstance(source_dir, basestring):
            for obj in oss2.ObjectIterator(oss_client, prefix=source_dir):
                zip_add_file(zip_file, obj.key)
        else:
            raise Exception('either `source_files` or `source_dir` must be speicified')
    
        zip_file.close()
        mem_buf.flush_buffer()
    
  4. 函数计算默认是10分钟执行时间

    函数计算建立的默认是弹性实例,最大的运行时间是10分钟

    需要修改为性能实例,然后将执行超时时间修改为7200

    在这里插入图片描述

原网站

版权声明
本文为[蓝枫秋千]所创,转载请带上原文链接,感谢
https://lanfengqiuqian.blog.csdn.net/article/details/122089056