关于七牛云存储:2021-七牛云战略发布会圆满落幕开启下一个十年

2021 年 12 月 17 日,「云纳万物 · 数皆有言」——2021 七牛云策略发布会于上海圆满举办。 千里之行,十年一剑,之于生存,之于产业,之于生态。万物纳于云上,信息诉诸数间。七牛云从此开启全新篇章,走向下一个十年。 七牛云策略公布,开启下个十年从数据的飞速增长到产业的矩阵反动,这是技术和产业激荡的十年,也是七牛云倒退的十年。 本次七牛云策略发布会特邀中国互联网协会副秘书长裴玮缺席并致收场辞。“十年间,咱们看到国内崛起了一批专一做云计算的企业。在云计算守业大军中,七牛云不断创新,砥砺前行,长期投入云计算核心技术畛域,在业内领有宽泛影响力。” 中国互联网协会副秘书长 裴玮 裴玮示意云计算是新型基础设施的重要组成部分,随着关键技术的一直冲破、产业生态的日益凋敝,已成为数字经济时代承载各类信息化设施的重要驱动力。 面对新局势、新需要,各行各业亟需增强技术改革,投入新一代产业互联网浪潮。在恭喜七牛云成立十周年的同时,也期待与七牛云独特奔赴下一个十年。 自成立起,七牛云始终着眼「云+数据」,一直优化策略布局,在过来的十年倒退中保持技术创新。七牛云 CEO 许式伟在本次策略发布会中发表了题为《云纳万物·数皆有言》的演讲,剖析以后时代背景和市场时机,瞻望七牛云的将来。 七牛云 CEO 许式伟 许式伟为与会观众分享了七牛云的十年倒退。从 1.0 的企业级云存储平台,到 2.0 的一站式数据管理平台,再到 3.0 的「云+数据」一体化 PaaS 平台,七牛云曾经实现百万级客户的服务部署,海纳百川,连贯生态。 “变动即时机。” 对于七牛云的定位,许式伟示意随着云计算市场竞争进入「深水区」,咱们正面临着遍地是机会的产业互联网,七牛云也趁势而为被动拥抱「视频化」和「产业数字化」。 七牛云作为 PaaS 厂商,许式伟也提到“建设扎实的技术底座、造成技术壁垒”是十分要害的。“作为「云+数据」一体化 PaaS 平台,七牛云的外围竞争力仍是那句「帮忙客户解决技术挑战,从而缩短客户从想法到产品之间的间隔」。” 将来,七牛云将一直摸索,深刻行业,把握垂直畛域的细分劣势,走差异化之道,以「新兴科技巨幅晋升客户业务效率」作为七牛云的价值点,构建基于 MPaaS + DPaaS 根底之上的行业场景化 aPaaS 能力。 七牛云的「云」到底是一朵怎么的「云」?七牛云 CTO 陈超以《数据·产业·云上万有引力》为题,从数字化浪潮和产业倒退视角对七牛云的倒退策略进行解读,并分享了七牛云在产业侧的相干思考与摸索。 七牛云 CTO 陈超 陈超示意,需要是由产业倒退衍生。在七牛云「Cloud + Data(云+数据)」的策略下,“从产业角度简略来了解,七牛云的「云」应该是一朵数据驱动的云,提供的不仅是 IT 工具,更是效率工具与智能工具;七牛云的「云」,是一朵了解客户业务的云,了解客户场景,从而提供更多一体化的解决方案给客户应用。” 十年专一,继续精进。陈超以智能网联车平安、近程智能工业检修、企业直播三个场景作为具体的产业案例,分享了七牛云如何「缩短需要到计划的间隔」。 陈超示意七牛云正从大容量数据的低成本存储与剖析、视频在线化和机器数据分析计划等三大方面来匹配产业的需要;以「点线面体」四层逻辑,“可复制、可继续、可规模化”作为产业侧具体的执行门路。 十年一跃,十年一约,七牛云十周年启程典礼作为会议上半场的压轴隆重启动。 策略公布启程典礼 启程典礼由七牛云 CEO 许式伟、CTO 陈超、COO 陈伊玲与特邀嘉宾中国互联网协会副秘书长裴玮及七牛云客户代表等独特发动,共议十年、齐迈新征程。 ...

December 18, 2021 · 1 min · jiezi

关于七牛云存储:Cocos-大表姐Cocos-引擎中的音视频应用丨ECUG-Meetup-回顾

本文依据「大表姐」李阳(Cocos 引擎布道师负责人)于 2021 年 6 月 26 日举办的 ECUG Meetup 第 1 期 | 2021 音视频技术最佳实际·杭州站上的分享整顿而成。本文长达 5800 余字,次要构造如下: Cocos 引擎介绍Cocos Creator && Engine基于 FFmpeg 的 Cocos Creator 视频播放器Cocos 的音视频播放及革新获取「讲师完整版 PPT」 ,请增加 ECUG 小助手微信(微信ID:ECUGCON)并备注「ECUG PPT」。其余讲师的分享也将于后续陆续放出,敬请期待。 以下为分享注释: 大家伙,我是 Cocos 引擎布道师负责人李阳。我写了大略七年的代码,始终是做基于 Cocos 引擎的手游研发,做的可能被大家相熟的一款游戏是捕鱼达人。 我当初在 Cocos 做布道师负责人,在我看来这个职业就是开发者的辅助师、技术的导航仪,次要是帮助用公司引擎的开发者更高效地开发出游戏,帮忙他们解决技术上的问题,提供引擎部门的反对。 一、Cocos 引擎介绍Cocos 以「技术驱动数字内容行业效率晋升」为理念。从 2011 年成立到目前为止,在寰球有 140 万个注册开发者,注销游戏数有将近 10 万。下载 Cocos 引擎制作游戏或者 APP 的大略有 16 亿设施,包含 203 个国家和地区。 上图中是 Cocos 引擎的一些市场占有率。中国手游的占有率是 40%,中国小游戏的占有率 64%,在线教育 APP 占有率是 90%。在线教育畛域 Cocos有专门的教育编辑器,用相似 PPT 的形式就能够开发出一个互动的游戏。 ...

August 6, 2021 · 2 min · jiezi

关于七牛云存储:Zilliz-陈室余音视频相似性检索的技术实现丨ECUG-Meetup-回顾

本文依据陈室余(Zilliz 资深数据工程师)于 2021 年 6 月 26 日举办的「ECUG Meetup 第 1 期 | 2021 音视频技术最佳实际·杭州站」上的分享整顿而成。全文共计 4200 余字,次要构造如下: 非结构化数据与 AI向量与数据的区别以音频为案例剖析 Milvus 我的项目“以图搜图”为例剖析相似性搜寻流程音频的相似性检索流程视频的相似性检索流程音视频相似性检索的三个案例获取「讲师完整版 PPT」 ,请增加 ECUG 小助手微信(微信ID:ECUGCON)并备注「ECUG PPT」。其余讲师的分享也将于后续陆续放出,敬请期待。 以下为分享注释: 大家下午好!很快乐加入 ECUG 和七牛云主办的 ECUG Meetup,来和大家探讨音视频技术的最佳实际,我明天给大家介绍的是「音视频的相似性检索的技术实现」。 首先,自我介绍一下,我叫陈室余,是 Zilliz 的数据工程师,次要是从事数据处理、模型利用等方面的工作。 给大家介绍一下咱们公司: Zilliz 是 Zillion of Zillions 的缩写,是来自上海的一家科技守业公司,专一于开发基于异构计算的数据迷信软件。开源是咱们的重要策略,咱们心愿通过开源来推动咱们的软件商业模式。咱们的愿景是从新定义数据迷信,为新畛域、新场景、新需要提供数据相干技术,帮忙人们更好地发现数据中蕴含的价值。咱们公司的次要我的项目是 Milvus,一个开源我的项目。非结构化数据与 AI在座各位也是音视频畛域的专家,咱们一起来回顾一下音视频的一些个性。视频其实是由一系列的视频帧组成的,像咱们看到的连环画,由一帧一帧的图片,能够组成视频。 视频还有一个重要因素是帧率,示意以帧为单位的图像间断呈现在显示器上的频率。还有就是音频,音频是示意人耳可能听到的范畴内的任何声音或乐音,声音有本人的振幅和频率,通常是 WAV、Mp3 等格局的,而带有音频的视频数据格式有 MP4、RMVB、AVI 等等。 这里提到的图片、音频和视频,咱们都能够称之为非结构化数据。咱们常说的数据个别分为三类: 第一类是结构化数据,包含数字、日期、字符串等。第二类是半结构化数据,包含具备肯定格局的文本信息,如各种系统日志。第三种是非结构化数据,图片、视频、语音、自然语言等,不容易被计算机了解。关系型数据库、传统大数据这些技术都是为了解决结构化数据的问题,而半结构化数据,以通过基于文本的搜索引擎来解决。唯独非结构化数据,在咱们的日常生活中每天都会产生,占总数据的 80%,过来始终不足无效的分析方法。直到近年来人工智能、深度学习技术的衰亡,非结构化数据得以利用。 深度学习模型的魅力在于,它能够将本来计算机难以解决的非结构化信息转化为机器容易了解的特色信息,利用深度学习模型把像图片、视频、语音、自然语言等非结构化数据提取出特征向量,最终通过对特色向向量的计算,实现对非结构化数据的剖析。 向量与数据的区别 咱们通过 AI 技术能够将非结构化数据转换成向量,那么向量计算该怎么做呢?传统的关系型数据库能够计算吗?毕竟一个向量也像一个数字,精确地说,向量是由一组数字组成的。 那么向量和数字有什么区别?向量和数字的区别,我认为次要有两个方面: 首先,向量和数字的罕用操作是不同的。数字之间常见的操作是加减乘除,但向量最常见的操作是计算类似度,比方计算向量之间的欧氏间隔,这里我给出了欧氏间隔的计算公式,能够看出向量的计算要比个别的数字计算简单的多。 第二点,数据和向量的索引形式不同。两个数字之间,能够进行数值比拟而后建设 B 树的数字索引。然而两个向量之间,咱们不能进行数值比拟。咱们只能计算它们之间的类似度,它的索引通常基于近似最近邻 ANN 算法。这里我给出了两种 ANN 的办法,基于聚类的索引和基于图的索引。 ...

August 5, 2021 · 2 min · jiezi

关于七牛云存储:年营收近-11-亿七牛云今日递交招股书拟在纳斯达克上市

北京工夫 5 月 1 日早间,七牛云正式提交 F1 招股书,拟在纳斯达克上市。 七牛云成立于 2011 年,作为企业级云计算和数据服务提供商,建设了对立的异构数据湖,打造了齐备的视频云服务和视频数据分析平台,并创立了简洁凋谢的机器数据处理平台。 七牛云创始了“云+数据”的一体化 PaaS 平台,为客户提供多媒体数据智能和解决方案的 MPaaS 服务,以及机器数据智能和解决方案的 DPaaS 服务。 同时,七牛云也是寰球最早将 Go 语言大规模利用于商业化产品的团队之一。创始人、CEO 许式伟开源公布的开发语言 Go+,在开发者群体中引发宽泛关注,曾占据了 Github Go 趋势榜双榜冠军。 七牛云招股书显示,依据 Frost & Sullivan 的数据,依照 2020 年的支出计算,七牛云是中国最大的 PaaS 繁多业务服务商和最大的独立 MPaaS 服务商,别离领有 4.4% 和 7.5% 的市场份额,客户数曾经超过百万,笼罩了包含泛娱乐、社交网络、医疗衰弱、电子商务、教育、媒体、金融服务、汽车、电信和智能制作等行业。 从财务数据来看,七牛云 2019 年、2020 年营收别离为 8.25 和 10.89 亿元人民币,其中 2020 年营收同比增速为 32%,毛利别离为 1.86 亿元和 2.37 亿元人民币,毛利率为 22.5%和 21.8%。2021 年七牛云第一季度营收为 3.22 亿元,而去年同期的营收为 2.86 亿元。 相干浏览:许式伟:相比 Python,咱们可能更须要 Go+权威公布丨2020 中国开源先锋 33 人之心尖上的开源人物 ...

May 1, 2021 · 1 min · jiezi

Laravel-配置使用七牛云

导语正好有时间,从头配置了一次,下面记录下。 七牛云配置七牛的文档写的很详细,所以只放上官方文档的链接就好了 对象存储,新建存储空间融合 CDN,配置域名在上一步配置域名之后,要到你的域名提供商去绑定,在七牛云文档中也有写安装扩展包以及配置根据文档操作 composer require "overtrue/laravel-filesystem-qiniu"config/app.php 中在 providers 添加 Overtrue\LaravelFilesystem\Qiniu\QiniuStorageServiceProvider::class,config/filesystems.php 中在 disks 添加'qiniu' => [ 'driver' => 'qiniu', 'access_key' => env('QINIU_ACCESS_KEY', 'xxxxxxxxxxxxxxxx'), 'secret_key' => env('QINIU_SECRET_KEY', 'xxxxxxxxxxxxxxxx'), 'bucket' => env('QINIU_BUCKET', 'test'), 'domain' => env('QINIU_DOMAIN', 'xxx.clouddn.com'), // or host: https://xxxx.clouddn.com],然后在 .env 中配置好对应的值。其中 access_key 和 secret_key 在七牛云的个人中心,bucket 是存储空间的名称,domain 是在融合 CDN 中配置的自定义域名 结语使用很简单,参考文档就可以了。因为我用了 laravel-admin,同时修改 config/admin.php 如下 参考资料:七牛云文档中心、laravel-filesystem-qiniu、laravel-admin。

June 22, 2019 · 1 min · jiezi

关于七牛云正确使用姿势探索

业务场景需求我们项目有一个文件上传需求,需要从客户端上传到七牛云的对象存储和自己的应用服务器上。这里使用七牛云主要是实现下载分发。应用服务器需要留一份是因为后续需要做文件分析(并且是上传后需要立马分析出结果展现给客户端)。另外,由于是初期项目,暂时没考虑用独立服务器来分析。所用技术栈服务器:Centos7开发语言:PHP框架:Laravel前端上传组件:百度的WebUploader解决方案准确的说我经过了三个阶段才真正完美的实现了需求(主要解决上传速度)。一期解决方案及细节初期面对需求很容易想到的思路是:客户端先上传文件到应用服务器(因为上传完成可以及时做分析),然后再上传到七牛云上。所以我的解决方案是:前端用webuploader,后端的七牛云文件处理方面使用了Laravel的一个插件:overtrue/flysystem-qiniu (https://github.com/overtrue/f…,该插件的接口很简洁好用(但是有坑,后面会说到)。然后为了解决性能问题,我还做了以下工作:1,使用分片上传2,后续上传七牛云使用异步的方式(因为文件上传到其他应用来下载这个文件,中间有许多时间来让上传任务的完成)关于分片上传这里讲下分片上传的实现思路,客户端主要是把大文件按一定size进行分片,然后上传到服务器,所以会有多个请求,并且每个请求还需带上关键的信息:当前chunk(从0开始)和chunks(总分片数)。由于我用的是webuploader组件,所以客户端不用自己做什么,只需配置下简单信息(是否分片及分片大小)。服务端处理逻辑为:客户端一个请求过来,分两种情况:1,文件总size小于要分片的size,这时候直接处理文件。2,处理分片情况。具体逻辑是判断chunk和chunks,如果相等说明为第一种情况,直接处理上传,其他走处理分片逻辑。处理分片的逻辑为:保存当前分片到临时目录(按分片命名),然后判断当所有分片完成时,就合并文件。具体逻辑是判断 chunk + 1 是否等于chunks。 合并逻辑就是循环读取临时文件,然后写入到一个新的文件(合并后的),这里可以顺便删除临时文件。所遇的坑:这里处理碎片文件时,当初图方便使用了Laravel的文件处理接口Storage::append,但是这个接口有个坑就是它自作主张的文件结尾加入换行符。导致合并后的文件还原不成原始文件。解决办法是老老实实使用php的fopen、fwrite、fclose这一套。关于PHP异步处理关于PHP的异步实现可以参考鸟哥写的文章:http://www.laruence.com/2008/…主要方法为:客户端AJAX、popen函数、curl、fsocketopen等不过这篇文章比较老了,局限性也大,现在有了协程等处理方案(现在Swoole也提供协程方案了,并且client-server task分发这种也可以用swoole的),而且往架构方面考虑可以使用队列等(感觉靠谱的还是队列)。PS: 我这里前期用的是简单粗暴的popen,后来使用的是Laravel提供的队列。一期方案的问题通过上述所说的方案,很容易就实现了一个版本。但是没高兴多久。。,在后续测试时遇到一个诡异bug,当文件过大时,任务脚本上传到七牛云失败。这里脚本是写在Laravel的artisan中的,当我把脚本命令直接在终端调试时也是没有任何异常(准确讲是看不了任何异常)。前面我说过七牛这块SDK用的是overtrue/flysystem-qiniu ,并且为了考虑性能问题用的是他的writeStream接口。 $disk = Storage::disk(‘qiniu’); $stream = fopen($localFileName, ‘r’); $disk->writeStream($fileName, $stream); if (is_resource($stream)) { fclose($stream); }代码表面上看起来很理想,用的是文件流上传(怕吃内存)。但结果证明一切只是表面上的。。当我遇到大文件无法上传到七牛云时,断点调试到$disk->writeStream这里,发现返回的是false。 继而调试到overtrue/flysystem-qiniu这个扩展的源代码。然后发现了一个大坑。。主要是两个问题:1,writeStream只是个假的流写入具体源码在扩展的QiniuAdapter.php文件中,这里贴段代码:public function writeStream($path, $resource, Config $config){ $contents = ‘’; while (!feof($resource)) { $contents .= fread($resource, 1024); } $response = $this->write($path, $contents, $config); if (false === $response) { return $response; } return compact(‘path’);}注意这里的$contents变量,最终还是等价于一个大文件内容的大小(服务器为此变量开辟的内存)。并且后续还要在方法间传递。所以这里是假的流!2,接口对调试不友好还有在write方法中,屏蔽了$error,只返回false,这样不便于我们查问题,最终我是断点打印这个$error才知道报的错误是:“invalid multipart format: multipart: message too large”,这个应该是七牛那边真正返回的,但这么重要的信息被这个扩展屏蔽了。二期解决方案知道了一期方案的具体问题所在,我就一直在思考(那个扩展就不提了。。我现在怀疑它的存在意义。。),甚至在想也许一开始整个思路就错了(通过SDK上传文件的方案)。后来还真被我找到了,七牛云官方提供一个脚本工具:Qshell(https://github.com/qiniu/qshell)。这个是命令行运行脚本,具体操作看文档就可以了。放到我的项目也是集成到七牛的任务脚本中。后来测试可以了,整个流程可以跑通。但是无意中发现二期的重要问题,这个上传走的是服务器的上行带宽!而我们平常付费买的带宽就是买的上行带宽!(下行是一般是免费的)。这还怎么搞!由于我们上传业务是商户端使用的,平时使用频次也不会太少,这会导致在上传时影响前端网站的访问速度。这里具体讲下服务器带宽问题(网上查询后整理的):首先对服务器带宽方向的描述一般是用上行和下行,上传和下载是指动作。上行是指从服务器流出的带宽,如果是在其他机器下载服务器上的文件,用的主要是服务器的上行带宽(这里说下我们平时的网页浏览,其实也是不同客户端从服务器下数据, html文件、css等然后渲染,所以网页浏览占用的也是上行带宽)。下行是指流入到服务器的带宽,如果是在其他机器上传文件到服务器,比如用FTP上传文件,用的主要是服务器的下行带宽(服务器上下载文件用的也是下行带宽)。现在的云提供商比如阿里云不限制的是下行带宽,大部分服务器的使用环境,都是上行带宽用的多,下行带宽用的少。通过对带宽的理解,再回到我们项目的上传实现思路,可以看到一开始就错了(不该用应用服务器作为中转)!三期(最终)方案当初为了节省时间,直接跳过官方文档,而使用第三方扩展。 现在看来,不得不又回到官方文档了。通过把七牛的文档过一遍,发现是有方案可以避开那个占用服务器上行带宽的问题的。主体思路是要避开应用服务器上行带宽的使用,因为上行带宽很宝贵,尽量使用下行带宽(免费、速度很快!阿里的大概60M多每秒)。具体实现是通过七牛的表单上传方案直接把客户端的文件先上传到七牛(这一步根本不关应用服务器什么事,所以避开了,而且直接上传到七牛的速度非常快,基本只取决于用户端的网速,而且对于一般需求,七牛提供了对于到我们应用服务器的回调方法)。然后由于我们应用服务器也需要文件,所以方案是直接在我们应用服务器直接下载七牛的文件(这里可以同步阻塞住,前端做个等待效果解决用户体验问题)。因为前面说到流入到服务器占用的是下行带宽。所以这里速度也会非常快(而且是免费的^_^)。这种方案基本是完美的了。总结首先是对个人的反省,前期调研不充足,但是项目初期有点紧,这里也说明投入时间的重要性。其次关于项目经验:上传第三方云存储,千万不要使用应用服务器做中转!可以直接上传到第三方云服务器,如果有后续处理逻辑的,可以使用他们的回调接口。

April 10, 2019 · 1 min · jiezi

加速你的博客永无止境-七牛云存储

将自己的静态博客直接部署到七牛云存储,由七牛云托管运行,你说快不快,还没有注册七牛云的看这里,七牛云注册邀请:https://portal.qiniu.com/signup?code=3l7cpouzlru4y,哈哈!一、创建七牛云存储登录进入管理中心,菜单进入:对象存储=>新建存储空间,设置好空间名称就可以直接创建,完成后会分配一个测试域名,有效期只有30天,当然可以自定义域名,长期使用二、静态博客文件构建我使用的是jekyll管理博客, 通过命令jekyll build构建MacBook-Pro:iChochy mleo$ jekyll buildConfiguration file: /Users/mleo/Develop/GitHub/iChochy/_config.yml Source: /Users/mleo/Develop/GitHub/iChochy Destination: /Users/mleo/Develop/GitHub/iChochy/_site Incremental build: disabled. Enable with –incremental Generating… Jekyll Feed: Generating feed for posts done in 1.121 seconds. Auto-regeneration: disabled. Use –watch to enable.构建成功后,生成的静态文件都在_site目录中,直接上传到云空间就可以了三、同步静态博客文件到云存储这里使用到七牛云官方工具qshell工具介绍:https://github.com/qiniu/qshell工具下载:http://devtools.qiniu.com/qshell-v2.3.6.zip选择安装:文件名描述shell_linux_x86Linux 32位系统shell_linux_x64Linux 64位系统shell_linux_armLinux ARM CPUshell_windows_x86.exeWindows 32位系统shell_windows_x64.exeWindows 64位系统shell_darwin_x64Mac 64位系统,主流的系统1、安装以Mac为例,安装shell_darwin_x64运行复制命令:cp qshell_darwin_x64 /usr/local/bin/qshell,将shell_darwin_x64复制到 bin目录下,运行qshell -v检测是否安装成功MacBook-Pro:qshell-v2.3.6 mleo$ qshell -vqshell version v2.3.62、添加账号运行命令qshell accountqshell account <AK> <SK> <Your Name>参数说明<AK>、<SK>可以到个人中心 => 密钥管理中查看<Your Name>为用户的唯一标识,自定义,如iChochy3、同步文件 使用命令qshell qupload <LocalUploadConfig>其中LocalUploadConfig参数配制文件本人的LocalUploadConfig文件信息:MacBook-Pro:iChochy mleo$ cat .LocalUploadConfig{ “src_dir” : “/Users/mleo/Develop/GitHub/iChochy/_site”, “bucket” : “blog”, “ignore_dir” : false, “overwrite” : true, “check_exists” : true, “check_hash” : true, “check_size” : true, “rescan_local” : true, “skip_file_prefixes” : “test,demo,”, “skip_path_prefixes” : “hello/,temp/”, “skip_fixed_strings” : “.svn,.git,.log”, “skip_suffixes” : “.DS_Store,.exe”, “log_file” : “/Users/mleo/.qshell/upload.log”, “log_level” : “info”, “log_rotate” : 1, “log_stdout” : false, “file_type” : 0}主要参数说明:参数说明src_dir本地同步目录bucket云空间名称log_file日志文件命令参数详细说明:https://github.com/qiniu/qshell/blob/master/docs/qupload.mdMacBook-Pro:iChochy mleo$ qshell qupload .LocalUploadConfigWriting upload log to file /Users/mleo/.qshell/upload.logUploading /Users/mleo/Develop/GitHub/iChochy/_site/404.html => 404.html [1/67, 1.5%] ……………See upload log at path /Users/mleo/.qshell/upload.log通过日志查看详情cat /Users/mleo/.qshell/upload.log至此:文件已经同步到了云空间,修改文件后再次运行qshell qupload <LocalUploadConfig>命令及可完成同步四、自定义域名1、云空间绑定域名菜单进入对象存储=>空间概览=>融合 CDN 加速域名=>立即绑定一个域名 创建域名2、域名解析创建成功后七牛云会为每个域名分配一个CNAME,如:www.chochy.cn.qiniudns.com登录域名商的管理系统,将域名解析到CNAME五、设置存储空间菜单进入对象存储=>空间设置 设置空间信息如:开启默认首页index.html,自定义404页面等 现在可以通过域名直接访问自己的博客了,是不是非常快快快………………如:http://www.chochy.cn ...

April 9, 2019 · 1 min · jiezi

七牛云上传及上传方法封装

分片及七牛云上传封装项目里面用到七牛云,有分片和简单上传在此做下简单的记录,分享下面是分片上传封装process.env.MAX_FILESIZE 是我写在config里面分片的大小 如1024102410 10MB分片项目是vue框架,请求是axios。上传的进度在onUploadProgress中获取/** * 封装upload方法 * @param url 上传路径 * @param json 包含file对象 * @returns {Promise} /export function upload(url,json) { return new Promise((resolve,reject) => { let size = parseInt(Number(json.file.size)/Number(process.env.MAX_FILESIZE) +1); let y = 0; let fun = function(){ let formData = new FormData(); let file = json.file.slice(yprocess.env.MAX_FILESIZE,(y+1)process.env.MAX_FILESIZE); formData.append(‘chunk’, y); formData.append(‘file_name’, json.file.name); formData.append(‘count’, size); formData.append(’type’, json.type); formData.append(‘file’, file); axios.post(url,formData,{ headers: { ‘Content-Type’: ‘multipart/form-data’ },timeout:10000000, onUploadProgress: progressEvent => { //progressEvent.loaded 为上传进度 }, }).then(response => { if(response.data.code === 200){ if(y+1<size){ y++; fun() }else{ y=0; resolve(response.data.data); } }else{ Vue.prototype.$message.error(response.data.msg) } }) .catch(err => { reject(err); let message = ‘请求失败!请检查网络’; if(err.response)message=err.response.data.message; Vue.prototype.$$msgbox({ title:‘错误!’, message:message, type:’error’, }) }) }; fun() } })} 下面是七牛云上传的封装/* * 封装upload方法 * @param json json中包含fail * @returns {Promise} */export function uploadQiniu(json) { return new Promise((resolve,reject) => {axios.get(‘获取七牛权限的后台接口地址,主要获取七牛token’,{ params:{ file_name:json.file.name } }).then(resData =>{ let putExtra = { fname: json.file.name, mimeType:json.mimeType || null }; let congif = {}; let observable = qiniu.upload(json.file,resData .data.data.new_name,resData .data.data.token,putExtra,congif); let observer = { next(res){ let progress = Number(res.total.percent.toFixed(0)); // 此处得到上传进度百分比 可加后续操作 }, error(err){ reject(err); let message = ‘请求失败!请检查网络’; if(err.response)message=err.response.data.message; Vue.prototype.$alert({ title:‘错误!’, message:message, type:’error’, }) }, complete(res){ res.url = res.key; res.name = json.file.name; resolve(res); } }; let subscription = observable.subscribe(observer) } ); })} ...

March 8, 2019 · 1 min · jiezi

小程序上传图片到七牛云(支持多张上传,预览,删除)

以下为wxml (使用的vant小程序ui框架,需在json文件里自行引入)<view class=‘clearFloat’> <view class=‘upload_title’>头像展示(必填) <span class=“basic_title_desc”>(选一张好看的个人照片可以增加客户点击的机会哦) </span> </view> <view class=‘healthCertImg’> <view class=‘imgrelative’ wx:if="{{headIconArr}}" wx:for="{{headIconArr}}" wx:for-index=“index” wx:for-item=“item” wx:key="this"> <image class=“image uploadimg” src="{{imgPath+item.key}}" mode=“aspectFit” id="{{imgPath+item.key}}" catchtap=‘previewHeadIcon’>{{item}}</image> <van-icon name=“clear” custom-style=“color:#979797;position:absolute;right:-20rpx;top:-20rpx;” id="{{index}}" bind:click=“deleteHeadIcon” /> </view> <image src=’../../imgs/upload.png’ class=‘uploadimg upload_jkz’ catchtap=‘headIcon’ wx:if="{{IsHeadIcon}}"></image> </view> </view>以下为wxss.clearFloat { clear: both; overflow: hidden;}.upload_title { color: #222; font-size: 32rpx; margin-bottom: 16rpx; display: block; margin-top: 50rpx;}.imgrelative { position: relative; height: 164rpx; width: 164rpx; margin-right: 43rpx; float: left;}.uploadimg { height: 164rpx; width: 164rpx; float: left;}以下为json{ “usingComponents”: { “van-popup”: “../../vant/popup/index”, “van-area”: “../../vant/area/index”, “van-icon”: “../../vant/icon/index”, “van-toast”: “../../vant/toast/index”, “van-datetime-picker”: “../../vant/datetime-picker/index”, “van-field”: “../../vant/field/index”, “upload”: “../../component/upload/index” }}以下为js文件(涉及到封装的微信ajax和七牛云上传图片方法在下面)const util = require(’../../utils/util.js’);const qiniuUploader = require("../../utils/qiniuUploader"); // 头像展示上传图片 headIcon() { var that = this that.chooesImage(that, 1, function(res) { that.data.headIconArr.push(res) // console.log(that.data.ysCertImgArr.length) if (that.data.headIconArr.length >= 1) { that.setData({ IsHeadIcon: false }); } that.setData({ headIconArr: that.data.headIconArr }); }) }, // 头像展示预览与删除 previewHeadIcon(e) { this._previewImage(e, this.data.headIconArr) }, deleteHeadIcon(e) { var that = this that._deleteImage(e, that.data.headIconArr, function(files) { that.setData({ headIconArr: files, IsHeadIcon: true }); }) }, /图片上传/ chooesImage(that, count, callback) { util.didPressChooesImage(that, count, function(filePath) { qiniuUploader.upload(filePath, (res) => { console.log(res) callback(res) that.checkSubmit() }, (error) => { console.error(’error: ’ + JSON.stringify(error)); }, null, // 可以使用上述参数,或者使用 null 作为参数占位符 (progress) => { // console.log(‘上传进度’, progress.progress) // console.log(‘已经上传的数据长度’, progress.totalBytesSent) // console.log(‘预期需要上传的数据总长度’, progress.totalBytesExpectedToSend) }, cancelTask => that.setData({ cancelTask }) ); }) },/图片预览/ _previewImage: function(e, arr) { var preUlrs = []; console.log(arr) const imgPath = ‘https://cdn.wutongdaojia.com/' arr.map( function(value, index) { var key = imgPath + value.key preUlrs.push(key); } ); wx.previewImage({ current: e.currentTarget.id, // 当前显示图片的http链接 urls: preUlrs // 需要预览的图片http链接列表 }) }, /图片删除/ _deleteImage: function(e, arr, callback) { var that = this; var files = arr; var index = e.currentTarget.dataset.index; //获取当前长按图片下标 console.log(index) wx.showModal({ title: ‘提示’, content: ‘确定要删除此图片吗?’, success: function(res) { if (res.confirm) { files.splice(index, 1); console.log(files) } else if (res.cancel) { return false; } // files, that.setData({ isCanAddFile: true }); that.checkSubmit() callback(files) } }) },以下为封装的七牛云上传图片方法(util.js)const qiniuUploader = require("./qiniuUploader");import api from ‘./api.js’;const getUploadToken = () => { var params = { token: wx.getStorageSync(’token’) } api.ajax(“GET”, params, “/weixin/getUploadToken”).then(res => { console.log(res.data) initQiniu(res.data) });}// 初始化七牛相关参数const initQiniu = (uptoken) => { var options = { region: ‘NCN’, // 华北区 // uptokenURL: ‘https://[yourserver.com]/api/uptoken’, // cdn.wutongdaojia.com // uptokenURL: ‘http://upload-z1.qiniup.com’, // uptokenURL: ‘https://yuesao.wutongdaojia.com/weixin/getUploadToken', // uptoken: ‘xxx’, uptoken: uptoken, // domain: ‘http://[yourBucketId].bkt.clouddn.com’, domain: ‘image.bkt.clouddn.com’, // image为七牛云后台创建的空间 shouldUseQiniuFileName: false }; qiniuUploader.init(options);}export function didPressChooesImage(that, count, callback) { getUploadToken(); // 微信 API 选文件 wx.chooseImage({ count: count, success: function(res) { console.log(res) var filePath = res.tempFilePaths[0]; console.log(filePath) callback(filePath) // 交给七牛上传 } })}/* * 文件上传 * 服务器端上传:http(s)://up.qiniup.com * 客户端上传: http(s)://upload.qiniup.com * cdn.wutongdaojia.com */function uploader(file, callback) { initQiniu(); qiniuUploader.upload(filePath, (res) => { // 每个文件上传成功后,处理相关的事情 // 其中 info 是文件上传成功后,服务端返回的json,形式如 // { // “hash”: “Fh8xVqod2MQ1mocfI4S4KpRL6D98”, // “key”: “gogopher.jpg” // } // 参考http://developer.qiniu.com/docs/v6/api/overview/up/response/simple-response.html that.setData({ ‘imageURL’: res.imageURL, }); }, (error) => { console.log(’error: ’ + error); }, // , { // region: ‘NCN’, // 华北区 // uptokenURL: ‘https://[yourserver.com]/api/uptoken’, // domain: ‘http://[yourBucketId].bkt.clouddn.com’, // shouldUseQiniuFileName: false // key: ’testKeyNameLSAKDKASJDHKAS’ // uptokenURL: ‘myServer.com/api/uptoken’ // } null, // 可以使用上述参数,或者使用 null 作为参数占位符 (res) => { console.log(‘上传进度’, res.progress) console.log(‘已经上传的数据长度’, res.totalBytesSent) console.log(‘预期需要上传的数据总长度’, res.totalBytesExpectedToSend) });};module.exports = { initQiniu: initQiniu, getUploadToken: getUploadToken, didPressChooesImage: didPressChooesImage}封装小程序wx.request(api.js)const ajax = (Type, params, url) => { var methonType = “application/json”; // var https = “http://www.wutongdaojia.com” var https = “https://yuesao.wutongdaojia.com” var st = new Date().getTime() if (Type == “POST”) { methonType = “application/x-www-form-urlencoded” } return new Promise(function (resolve, reject) { wx.request({ url: https + url, method: Type, data: params, header: { ‘content-type’: methonType, ‘Muses-Timestamp’: st, ‘version’: ‘v1.0’ // 版本号 // ‘Muses-Signature’: sign }, success: function (res) { // if (res.statusCode != 200) { // reject({ error: ‘服务器忙,请稍后重试’, code: 500 }); // return; // } // resolve(res.data); wx.hideLoading() console.log(res) if (res.data.status == 200) { resolve(res.data); } else if (res.data.status == 400) { wx.showToast({ title: res.data.message, icon: ’none’, duration: 1000 }) return } else if (res.data.status == 401){ wx.removeStorageSync(‘phone’) wx.removeStorageSync(’token’) wx.showToast({ title: res.data.message, icon: ’none’, duration: 1000, success:function(){ wx.navigateTo({ url: ‘../login/index’, }) } }) return } else { //错误信息处理 wx.showToast({ title: ‘服务器错误,请联系客服’, icon: ’none’, duration: 1000 }) } }, fail: function (res) { // fail调用接口失败 reject({ error: ‘网络错误’, code: 0 }); }, complete: function (res) { // complete } }) })}有什么不懂的可以加我微信(18310911617)备注(小程序上传图片到七牛云) ...

February 28, 2019 · 4 min · jiezi

被七牛云OSS对象存储测试域名回收后正确数据迁移姿势!

概述七牛云OSS对象存储bucket创建后有一个「外链默认域名」这个域名, 如果没有记错的2018上半年没有回收这个概念, 2018下半年隐隐约约记录收到过「【七牛云】测试域名回收通知」邮件, 出现这个域名后也没有太在意, 因为是个人使用, 怎么着都成! 后来用得着静态文件存储时就接着新建bucket, 接二连三的收到「测试域名回收通知」回收后最大的影响就是「整个Bucket基本所有功能都不能使用了, 都不能使用了, 都不能使用了~」下载什么的你就可劲点吧, 额~~~, 好吧!所有外部引用文件都不可用了, 你之前的所有引用又都想使用之前那些文件吧, 好了, 下载下来这个文件将其上传到阿里云对象存储OSS完美解决问题, 请看下面迁移过程, 可能会对你有所帮助~建立一个同区下的新Bucket您需要先新建一个同区域存储空间,会分配一个新的测试域名到新空间下载qshell关于qshell的下载请移步Github, 关于qshell的配置请参考命令行工具(qshell), 最好将qshell添加系统环境变量设置qshell登录账号查看 qshell account 命令使用方式➜ qshell account –helpGet/Set AccessKey and SecretKeyUsage: qshell account [<AccessKey> <SecretKey> <Name>] [flags]Flags: -h, –help help for account -w, –overwrite overwrite account or not when account exists in local db, by default not overwriteGlobal Flags: -C, –config string config file (default is $HOME/.qshell.json) -d, –debug debug mode -L, –local use current directory as config file path -v, –version show version添加 qshell account 登录账号AccessKey: 访问密钥SecretKey: 安全密钥SelfCustomName: 此处填写自定义的用户名(这个name就是qshell存存您登陆的账户名,可以随便设置的,比如qiniuaccount 或者 account_1 等等)AccessKey 及 SecretKey 可以到控制台右上角的个人面板,密钥管理里找到### 格式: qshell account AccessKey SecretKey SelfCustomName### 列如:➜ qshell account AccessKey SecretKey warnerwu将已被回收Bucket文件同步到新建Bucket下载已被回收Bucket下所有文件列表到文件进入到「本地数据备份路径」如➜ cd /qiniu/migration执行以下命令, 下载已被回收Bucket下所有文件列表到文件➜ migration qshell listbucket warner -o warner-data-list.txt下载到已被回收Bucket下所有文件列表到文件具体内容类似如下图所示将下载到的文件的第一列复制到一个最终文件列表文件➜ migration cat warner-data-list.txt | awk ‘{print $1}’ > warner-data-list-final.txt文件列表到文件内容如下:将文件列表文件将旧Bucket文件列表文件拷贝到新建Bucket文件列表➜ migration qshell batchcopy warner warnerwu-migration -i warner-data-list-final.txt执行以上命令七牛云会有一个安全机制就是让你输入验证码到此文件也就会从旧Bucket拷贝或者说同步到新建Bucket列表啦下载已同步到建新Bucket文件到本地备份文件夹关于如何下更详细讲解可以移步Github下载说明文档添加一个下载配置文件文件名如 warnerwu-migration-download.confdest_dir: 为本地备份文件绝对路径文件夹, 不过这个绝对路径要提交建立好bucket: 要下载Bucket下文件所在的Bucket名称{ “dest_dir” : “/Users/warnerwu/qiniu/migration/warnerwu-migraition”, “bucket” : “warnerwu-migration”}下载Bucket列表文件到本地备份文件夹-c: 10 参数 -c 代表是要使用多个 goroutine 进行下载Bucket列表下的文件, 我们都知道七牛后端全站 Go 语言开发, 对头, 你当前使用的 qshell 也是使用 Go 语言编写➜ migration qshell qdownload -c 10 warnerwu-migration-download.conf下载完成后会生成一个下载日志文件, 它是默认生成当前用户家目录下查看下载日志文件tail 默认显示最后10行tail -n 24 可以指定显示行数➜ migration tail /Users/warnerwu/.qshell/qdownload/e65c69a164299e2f7045ea3b7a3d18d7/e65c69a164299e2f7045ea3b7a3d18d7.log2019/02/18 22:14:33.548 [I] Download 2017.02.17.attrbute.01.png => /Users/warnerwu/qiniu/migration/warnerwu-migraition/2017.02.17.attrbute.01.png success 1785.53KB/s2019/02/18 22:14:33.548 [I] ——-Download Result——-2019/02/18 22:14:33.548 [I] Total: 262019/02/18 22:14:33.548 [I] Skipped: 02019/02/18 22:14:33.548 [I] Exists: 02019/02/18 22:14:33.548 [I] Success: 262019/02/18 22:14:33.548 [I] Update: 02019/02/18 22:14:33.548 [I] Failure: 02019/02/18 22:14:33.548 [I] Duration: 2.205420428s2019/02/18 22:14:33.548 [I] —————————–可以看到这个下载还是很快的只用了 2 秒左右的时间, 并且所有的下载都成功了!查看下载文件最后你可以将文件上传到阿里云对象存储OSS上, 它不存在「测试域名」的问题, 不过你要先购买对象存储OSS, 不贵40G好像是9块多钱的样子并且是一年!希望本文对你的工作和学习有所帮助如果觉得还不错怎么感谢我呢? 妈呀! 点赞啊!Good Luck! from warnerwu at 2019.02.18 PM ...

February 18, 2019 · 2 min · jiezi

七牛云账户假注销小指南

七牛云账号一枚,许久不用,遂发注销之意,提工单,告之待客服电。客服电,注销之,有邮件为证。因账号未登出,现端倪。见账号前现000前缀,遂生好奇:WTF? 假注销?尝试之:以000 + 原账号为登录账号,辅原密码登录。中!假注销矣!遂发文,以志之,告同仁:七牛云,假注销。所以呢,七牛云所谓的注销就是把你的账号冻结在你的账号前加上000的前缀如此呢,对于个人便可释放你原有的账号,使其可以重新注册等等。而对于七牛云呢,因为账户并未真正的删除,所以用户原有的身份认证等信息就可以保留下来而不被用户发现了,所以呢客服所说的什么信息全删除全是骗人的,让你不能登录才是真的。但是留一个问题:那个加000前缀的账号使用原来的密码还是可以登录的,只不过是被冻结了。这。。。。。(自己想吧)

February 15, 2019 · 1 min · jiezi

用element的upload组件实现多图片上传和压缩

我用vuex做状态管理,七牛云做图床。项目地址:多图片上传组件效果展示项目执行流程首先,让我们来分析一下实现多图片上传的流程:前端向后端请求用来上传图片至服务器的token后端为每张要上传的图片生成一个图片名,并用这个图片名生成token后端将图片名和token返回给前端前端拿到token以后,将图片上传至服务器上传成功以后,前端将图片名发给后端后端将图片名存入数据库项目实现过程1.我们要利用element-ui的Upload组件布置界面://upload.vue<el-upload :action= domain ref=“upload” accept=‘image/jpeg,image/gif,image/png’ :auto-upload=“false” :http-request=“upqiniu” :limit=“limit” :multiple=“multiple” list-type=“picture-card” :before-upload=“beforeUpload” :on-preview=“handlePictureCardPreview” :on-change=“handldChange” :on-remove=“handleRemove”> <i class=“el-icon-plus”></i></el-upload><el-dialog :visible.sync=“dialogVisible”> <img width=“100%” :src=“dialogImageUrl” alt=""></el-dialog>domain 指的是我们的上传地址,upqiniu 是我们自定义的上传方法,beforeUpload 是图片上传前执行的方法。关于该组件的其他用法可以在element的官方文档查阅:Upload 上传2.对图片进行压缩// upload.vueimgQuality: 0.5, //压缩图片的质量dataURItoBlob(dataURI, type) { var binary = atob(dataURI.split(’,’)[1]); var array = []; for(var i = 0; i < binary.length; i++) { array.push(binary.charCodeAt(i)); } return new Blob([new Uint8Array(array)], {type: type});},beforeUpload(param) { //对图片进行压缩 const imgSize = param.size / 1024 / 1024 if(imgSize > 1) { const _this = this return new Promise(resolve => { const reader = new FileReader() const image = new Image() image.onload = (imageEvent) => { const canvas = document.createElement(‘canvas’); const context = canvas.getContext(‘2d’); const width = image.width * _this.imgQuality const height = image.height * _this.imgQuality canvas.width = width; canvas.height = height; context.clearRect(0, 0, width, height); context.drawImage(image, 0, 0, width, height); const dataUrl = canvas.toDataURL(param.type); const blobData = this.dataURItoBlob(dataUrl, param.type); resolve(blobData) } reader.onload = (e => { image.src = e.target.result; }); reader.readAsDataURL(param); }) }}压缩图片实现起来比较简单。就是在beforeUpload()方法里面return一个Promise,Promise里面我们把图片的长度和宽度按比例进行缩小,并把图片画到canvas上,然后把canvas转成一个blod对象。3.前端向后端请求上传token。//upload.vueupqiniu(param) { let filetype = ’’ if (param.file.type === ‘image/png’) { filetype = ‘png’ } else { filetype = ‘jpg’ } const formdata = { filetype: filetype, param: param } this.actionGetUploadToken(formdata) }// vuex/action.jsactionGetUploadToken({commit}, obj) { const msg = { filetype: obj.filetype } usersApi.getImgUploadToken(msg).then((response) => { if(response.stateCode === 200) { commit(‘uploadImg’, {’token’: response.token, ‘key’: response.key, ‘param’: obj.param}) } }, (error) => { console.log(获取图片上传凭证错误:${error}) commit(‘uploadImgError’) })},4.后端生成上传token,并发给前端,我用Python实现。filetype = data.get(‘filetype’)# 构建鉴权对象q = Auth(configs.get(‘qiniu’).get(‘AK’), configs.get(‘qiniu’).get(‘SK’))# 生成图片名salt = ‘’.join(random.sample(string.ascii_letters + string.digits, 8))key = salt + ‘’ + str(int(time.time())) + ‘.’ + filetype# 生成上传 Token,可以指定过期时间等token = q.upload_token(configs.get(‘qiniu’).get(‘bucket_name’), key, 3600)return Response({“stateCode”: 200, “token”: token, “key”: key}, 200)5.前端接收token,开始向服务器上传图片// vuex/state.jsimgName: [], //图片名数组// vuex/mutations.jsuploadImg(state, msg) { const config = { useCdnDomain: true, region: qiniu.region.z2 } var putExtra = { fname: msg.param.file.name, params: {}, mimeType: [“image/png”, “image/jpeg”, “image/gif”] }; var observer = { next(res){ }, error(err){ console.log(图片上传错误信息:${err.message}) }, complete(res){ console.log(图片上传成功:${res.key}) state.imgName.push(res.key) } } var observable = qiniu.upload(msg.param.file, msg.key, msg.token, putExtra, config) //上传开始 var subscription = observable.subscribe(observer)},6.上传成功以后,将图片名存入数据库// 用到upload.vue的界面this.imgsList = this.imgName.map(key => http://${this.qiniuaddr}/${key})switch(this.imgsList.length) { case 4: this.img4 = this.imgsList[3] case 3: this.img3 = this.imgsList[2] case 2: this.img2 = this.imgsList[1] case 1: this.img1 = this.imgsList[0]}let obj = { goods_img1: this.img1, goods_img2:this.img2, goods_img3:this.img3, goods_img4:this.img4}//将信息发送给后端this.actionPublish(obj) ...

February 11, 2019 · 2 min · jiezi

七牛云测试域名过期后如何备份文件

七牛云测试域名过期后如何备份文件之前很多人都会使用【七牛云】作为图床,非常方便,但是后来七牛云政策做了修改,测试域名只有30个自然日的试用期,到期将自动回收。导致存储空间中文件或图片既不能外链下载,也无法从七牛云的控制台下载或预览,因此很多博客中的图片无法显示。如果想要继续正常使用的话,需要绑定完成 ICP 备案的域名才可以,但是进行 ICP 备案,还需要一台国内主机,及一系列的手续,产生了不必要的费用及麻烦。那么如何将失效存储空间中的文件或图片下载下来呢?本篇将告诉你方法。一、使用自定义域名如果您有一个完成 ICP 备案的域名,可以与失效存储空间进行绑定,绑定之后可以继续使用,也可以将文件或图片下载下来进行备份。此方法在此不再赘述。二、使用 qshell 备份文件除了绑定自定义域名进行备份外,我们还可以通过 qshell 工具进行文件的备份。qshell 工具是七牛云官方提供得,方便开发者测试和使用七牛云API的一个命令行工具。qshell 官方文档qshell Github地址快速模式# 在同存储区域内创建一个新的存储空间# 账号赋权./qshell.exe account <AccessKey> <SecretKey> <Name># 获取失效存储空间的文件列表./qshell.exe listbucket bucketError -o list.txt# 处理文件,仅获取第一列文件名cat list.txt | awk ‘{print $1}’ >list_final.txt# 将失效存储空间的文件复制到新的存储空间./qshell.exe batchcopy –force –overwrite bucketError bucketNew -i list_final.txt# 下载文件./qshell.exe qdownload download.conf2.1 在七牛云控制台新建空间使用浏览器进入七牛云控制台,在对象存储中新建一个存储空间,此存储空间需要与失效的存储空间在同一个【存储区域】上(比如都在华东,不在同一存储区域无法拷贝)。此存储空间被用来将失效存储空间中的文件复制进去,因为新建的存储空间有一个可以使用30天的测试域名,所以可以从这个新建的存储空间中将原来的文件下载下来进行备份。2.2 安装 qshell 工具qshell 工具下载地址为:http://devtools.qiniu.com/qshell-v2.3.5.zip下载完成后解压,将会得到对应三种操作系统的程序。|-qshell-v2.3.5 |-qshell_darwin_x64 |-qshell_linux_arm |-qshell_linux_x64 |-qshell_linux_x86 |-qshell_windows_x64.exe |-qshell_windows_x86.exe如果你是 Windows 系统的话,那么你应该使用 qshell_windows_x64.exe 这个程序,因为这是一个命令行工具,所以双击打开会闪退,应该在命令行中操作。为了简化命令,可将其重命名为 qshell.exe ,命令使用形式如下:# CMD 命令格式qshell.exe 命令 参数# Git Bash 等类 Linux 终端命令格式./qshell.exe 命令 参数2.3 设置账号密钥想要使用 qshell 操作七牛空间,需要添加账户密钥 AccessKey 和 SecretKey, 赋予 qshell 权限。# qshell-2.3.5 版本命令./qshell.exe account <AccessKey> <SecretKey> <Name># qshell-2.2.0 版本命令./qshell.exe account <AccessKey> <SecretKey>AccessKey, SecretKey 两个参数可以从七牛云-密钥管理中获取。Name是用户可以任意取的名字,表示当前在本地记录的账户的名称,和在七牛注册的邮箱信息没有关系。注:qshell-2.2.0 版本 与 qshell-2.3.5 版本 命令上稍有差异。qshell account 命令文档2.4 复制失效存储空间文件至新存储空间假设失效存储空间名为:bucketError假设新建存储空间名为:bucketNew若想要将失效存储空间的文件复制到新的存储空间,首先需要获取失效存储空间的文件列表,使用 listbucket 命令进行文件列表的导出。获取到文件列表后,使用 batchcopy 命令将 bucketError 中的文件全部复制到 bucketNew 中。(1) 使用 listbucket 导出文件列表# qshell-2.3.5 版本命令./qshell.exe listbucket bucketError -o list.txt# qshell-2.2.0 版本命令./qshell.exe listbucket bucketError list.txtlist.txt 文件结构如下:Hexo.png 33446 Fmmc-_RoRE19Gy86M_p3sEqt-Ue3 15475323542679537 image/png 0atom.xml 249682 FhtSZviyys9iSIMyPBmuohWEJDcE 15475323543559808 application/xml 0favicon.ico 4286 FiXUxb856CirSyQ78t3VQNQmCIZO 15475323543881185 image/x-icon 0ssh_rsa.png 17895 FsImghWkk55vj06DIt6DAhhLzAxQ 15475323564546303 image/png 0qshell listbucket 命令文档(2) 修改文件列表结构这里需要修改文件,只保留第一列的文件名,可以用awk获取list文件的第一列,不然无法进行复制。cat list.txt | awk ‘{print $1}’ >list_final.txtwindows 系统中CMD无法使用上面的命令,可以使用 Git Bash 终端或手动修改文件。 list_final.txt 文件结构如下:Hexo.pngatom.xmlfavicon.icossh_rsa.png(3) 复制文件到新存储空间获取到需要的文件列表 - list_final.txt 后,就可以进行文件的复制了。使用 batchcopy 命令进行复制。文件复制方向: bucketError -> bucketNew 。# qshell-2.3.5 版本命令./qshell.exe batchcopy –force –overwrite bucketError bucketNew -i list_final.txt# qshell-2.2.0 版本命令./qshell.exe batchcopy –force –overwrite bucketError bucketNew list_final.txtforce : 没有此选项,需要输入验证码,加入此项则不需要输入。overwrite :如果批量复制的文件列表中存在目标空间已有同名文件的情况,针对该文件的复制会失败,如果希望能够强制覆盖目标文件,那么可以使用-overwrite选项。qshell batchcopy 命令文档2.5 下载新存储空间的文件使用 qdownload 命令可以将存储空间中的文件下载到本地。但是该功能默认需要收取流量费用,如果想要免费下载,还需进行以下配置。(1) 配置 download.conf在 qshell 目录下创建新文件 download.conf ,并将以下信息添加进去。{ “dest_dir” : “D:\Images\”, “bucket” : “bucketNew”, “cdn_domain” : “xxxxxx.bkt.clouddn.com”}参数名描述dest_dir本地数据备份路径,为全路径,并且文件夹需要事先创建好,不然无法下载bucket空间名称cdn_domain设置下载的CDN域名,此处为新建空间的测试域名。默认为空表示从存储源站下载,需支付源站流量费用,无法减免!!!备注:在Windows系统下面使用的时候,注意dest_dir的设置遵循D:\jemy\backup这种方式。也就是路径里面的要有两个(\)。在默认不指定cdn_domain的情况下,会从存储源站下载资源,这部分下载产生的流量会生成存储源站下载流量的计费,请注意,这部分计费不在七牛CDN免费10G流量覆盖范围。(2) 文件下载配置好文件之后,可以使用下面的命令进行文件下载:# qshell-2.2.0 与 qshell-2.3.5 版本命令相同./qshell.exe qdownload download.conf下载完成后可以在对应的文件夹中查看下载的文件。不管是备份,还是更换图床都是可以的了。qshell qdownload 命令文档三、参考七牛云 qshell 官方文档qshell Github地址Github 中关于此问题的issues点击阅读原文 ...

January 16, 2019 · 2 min · jiezi

Beego文件上传至七牛云的玩法

前言Beego是一款GO语言开发的传统MVC的框架,beego对上传这块的代码封装的也非常简单易用。beego的上传贴出官方的一段代码https://beego.me/docs/mvc/con…func (c *FormController) Post() { f, h, err := c.GetFile(“uploadname”) if err != nil { log.Fatal(“getfile err “, err) } defer f.Close() c.SaveToFile(“uploadname”, “static/upload/” + h.Filename) // 保存位置在 static/upload, 没有文件夹要先创建 }这里beego通过 GetFile方法获取文件的name,既设置的 input name=“uploadname” 可以通过其第二个返回值获得文件的详细详细h.Filenameh.Headerh.size上面的例子是一个传统上传,既将文件拷贝到本地项目目录中。七牛云关于注册、登录、获取key什么的本文就不废话了。官方提供了Go的Sdk文档地址:https://developer.qiniu.com/k…安装通过go get 安装包go get -u github.com/qiniu/api.v7使用这里演示两种上传方式七牛官方的SDK提供了几个上传方法,如下所示// 本地文件上传至七牛云func (p *FormUploader) PutFilefunc (p *FormUploader) PutFileWithoutKey// 数据流方式上传至七牛云func (p *FormUploader) Putfunc (p *FormUploader) PutWithoutKey这个SDK也允许你自定义返回结果,通过重写结构体的方式type PutRet struct { Hash string json:"hash" PersistentID string json:"persistentId" Key string json:"key"}本地上传这是官方的一个demo,本地上传这里就不多阐述了,大概都能看懂// 设置上传文件localFile = “/Users/jemy/Documents/github.png”// 设置上传空间名bucket = “if-pbl”// 上传的文件名称key = “github-x.png"putPolicy := storage.PutPolicy{ Scope: bucket,}mac := qbox.NewMac(accessKey, secretKey)upToken := putPolicy.UploadToken(mac)cfg := storage.Config{}// 空间对应的机房cfg.Zone = &storage.ZoneHuadong// 是否使用https域名cfg.UseHTTPS = false// 上传是否使用CDN上传加速cfg.UseCdnDomains = false// 构建表单上传的对象formUploader := storage.NewFormUploader(&cfg)ret := storage.PutRet{}// 可选配置putExtra := storage.PutExtra{ Params: map[string]string{ “x:name”: “github logo”, },}err := formUploader.PutFile(context.Background(), &ret, upToken, key, localFile, &putExtra)if err != nil { fmt.Println(err) return}fmt.Println(ret.Key,ret.Hash)流信息上传这是我自行封装的流上传代码package qiniuimport ( “github.com/qiniu/api.v7/storage” “github.com/qiniu/api.v7/auth/qbox” “context” “io”)const ( bucket = “avatars” // accessKey = "” secretKey = “")func config() storage.Config { cfg := storage.Config{} cfg.Zone = &storage.ZoneHuadong // 是否使用https域名 cfg.UseHTTPS = false // 上传是否使用CDN上传加速 cfg.UseCdnDomains = false return cfg}func Upload(localFile io.Reader, size int64, filename string) (string, error) { putPolicy := storage.PutPolicy{ Scope: bucket, } mac := qbox.NewMac(accessKey, secretKey) upToken := putPolicy.UploadToken(mac) cig := config() formUploader := storage.NewFormUploader(&cig) ret := storage.PutRet{} putExtra := storage.PutExtra{} err := formUploader.Put(context.Background(), &ret, upToken, filename, localFile, size, &putExtra) if err != nil { return “”, err } return ret.Key, nil}注意localFile io.Reader这个参数,调用upload方法需要传一个byte。下面演示调用方法的代码func (u *UserController) UploadImage() { f, h, err := u.GetFile(“image”) if err != nil { u.Data[“json”] = common.Response{ Data: [0]int{}, Message: “上传失败”, Code: 0, } u.ServeJSON() return } defer f.Close() file, _ := h.Open() // 这里获得的实际就是一个io,通过源码看到这个open方法最终返回的是一个结构体,其内部包含了 io.Reader的接口 // type File interface { // io.Reader // io.ReaderAt // io.Seeker // io.Closer // } unix := time.Now().Unix() timeByte := []byte(strconv.Itoa(int(unix))) filename := function.Md5(timeByte) // 这里是计算了一个md5(time())的字符串作为文件名 if filename, err = qiniu.Upload(file, h.Size, filename); err != nil { // 通过h.size 即可获得文件大小 u.Data[“json”] = common.Response{ Data: [0]int{}, Message: “上传失败”, Code: 0, } } else { u.Data[“json”] = common.Response{ Data: map[string]string{ “filename”: filename, }, Message: “上传成功”, Code: 200, } } u.ServeJSON()}致谢go 自身的特点不应是做web,web使用php,java就够了。一般用go都是写接口。所以上传文件时不应先传到本地再传到七牛,我想很多初学者都在这里被坑。特此写一篇来解释其使用方法。希望本篇文章可以帮到你。谢谢 ...

January 4, 2019 · 2 min · jiezi