前言
项目中的oss服务器未来不打算继续续费了,接下来想要把所有的文件进行备份到本地进行留存
权衡了官方文档几种方式之后选择了函数计算的方式
原因主要是:有一个bucket当时没有处理好,所有文件存储到了bucket的根目录下面,而不是子目录,导致无法直接选中文件或者目录下载(因为根目录下有好几万的文件)
步骤
先根据官方文档来进行函数计算的部署
开始踩坑
-
函数计算已经顺利的部署上去了,但是点击测试代码运行报错,如下
{ "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"
-
官方文档上说,如果想要下载根目录下的文件,使用
./
即可
实际上,我按照他这么修改之后,运行的时候,并没有效果,本地会在下载到一个只有22B
且无法解压的压缩包,并且oss上面并没有对应的压缩包,也就是意味着失败了
最后做了多种测试之后,发现使用
""
空字符串作为目录的话是可行的代码如下
evt = { "region": "cn-zhangjiakou", "bucket": "zhushang-applet-code", "source-dir": "" }
-
下载的文件打包压缩后太大导致失败
运行代码报错如下:
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()
-
函数计算默认是10分钟执行时间
函数计算建立的默认是
弹性实例
,最大的运行时间是10分钟需要修改为
性能实例
,然后将执行超时时间修改为7200
秒