在开发 Lsky Pro 时,我的目的性很强,开发语言选择了 PHP,就是为了快速迭代出项目,无论是库以及生态,PHP 在这方面有很大的优势,效果也很明显,我仅仅用了 18 天的时间发布了 Lsky Pro 第一个版本。

但使用 PHP 最大的痛点是在于 PHP 的工作模式,传统的 FPM 满足不了 Lsky Pro 的部分场景,例如部分第三方云储存尚未提供删除多个资源的接口(点名又拍云),这就导致了用户进行批量删除时,需要并发请求删除资源接口,最简单的实现方式就是使用队列来进行异步请求,在程序进程中一个一个的删除。

但是实现一个队列,对于程序的安装以及维护成本上是昂贵的,并且还需要考虑到失败重试、消费进程数、同时处理消息数等一系列延伸出来的问题。

没有解决办法吗?有的,上 Swoole,直接异步编程,需要并发处理的操作全部协程化,在协程中处理长时间的任务,并且性能上更是质的飞跃。但是在开发 Lsky Pro 时,我并没有考虑使用 Swoole,原因是对于部分站长很不友好,如果使用的是非集成环境安装的 PHP,通常需要自己编译安装 Swoole,单在这点上就已经劝退了大部分人。

新项目兰空云盘(Lsky Cloud),在进行了一些简单的规划后,开发 Lsky Cloud 我选择了 Golang&Gin&Gorm + Vue&Vuex,Golang 通过关键字 go 就能创建一个线程,且编译速度飞快,对于云盘这种业务逻辑少的程序,Golang 成为了不二之选。

当前预览图:

Lsky Cloud 延续了 Lsky Pro 的 UI,前端使用 Vuetify 框架实现。

目录结构

├─bootstrap 程序初始化文件目录
├─http 程序模块目录
│  ├─controllers 控制器目录
│  ├─middleware 中间件目录
│  ├─validate 验证器目录
├─models 模型目录
├─routes 路由目录
├─runtime 缓存目录
├─storage 物理文件储存目录
├─tools 工具函数目录
├─utils 程序辅助函数目录
├─web 前端脚手架工程文件目录

Lsky Cloud 支持以本地、七牛云、又拍云、腾讯云、阿里云、ftp 的方式储存文件,并且支持客户端分片直传。

上传策略

考虑到以后有更多的第三方储存,前后端在实现上传时,以工厂模式的设计方式,对上传策略部分进行封装,以便以后拓展更多的上传策略。

image-20210208143823019

每个 policy 中所有的方法、事件名相同,增加一个 policy 是只需要实现其中的方法即可。

上传流程

Lsky Cloud 上传文件时,会进入一个队列,队列我使用 tiny-async-pool 实现,为了避免分片请求过多导致请求 padding,每次只会有一个文件出队上传,单个文件会进行分块处理,每个块异步上传。

入队的文件首先获取所选文件的 hash md5 值,也就是在客户端计算 md5,我选择了 CryptoJS ,为了改进性能,计算时会进行文件分片,逐个计算,完成速度取决于客户端性能。

在计算 md5 前会向服务器请求获取文件的基本大小,判断文件格式是否允许上传、用户储存空间是否足够等,同时获取该文件应该存在的目录路径。md5 计算完毕后开始正式向第三方储存 API 上传文件,出现错误时则会跳过,处理队列中的其他文件。

由于部分第三方储存不支持异步回调功能,所以回调验证部分只能需要自己实现,设计成了文件上传成功后由客户端发起回调请求,告诉服务器该文件已被上传完毕。

起初想以携带文件元数据(meta)的方式储存文件的一些基础数据,比如文件类型、md5、sha1 值等,这样的话就可以在上传完毕后很方便的创建该文件记录,无奈在我的百般尝试下,又拍云的 REST API 居然在设置 meta 时会出现跨域的问题,询问客服才知道 REST API 无法设置自定义的 meta,只能作罢。

回调通知到服务器后,将会重复执行上传前的验证操作,避免非法伪造的回调。

文件夹

Lsky Cloud 中可以新建“文件夹”进行文件分类,为了更方便的实现文件夹加密功能,该文件夹并非物理文件夹,而是类似一个分类功能。

image-20210208144037061

文件管理

Lsky Cloud 在磁盘文件管理上下了很大的功夫,最终实现了与 Windows 资源管理器类似的交互体验,得益于 Vuetify 强大的 Menus 组件,很轻松的实现了右键菜单的操作,以及各种 Material Design 风格的响应式对话框。

其次就是拖拽、多选文件夹等操作,这部分实现比较繁琐,首先需要监听鼠标点击、松开、以及拖拽事件,在鼠标移动时根据元素以及父元素宽高来判断选框是否覆盖,并遍历被覆盖的 object,被覆盖的 object 同时需要改变其被选中样式,开始是使用 vue 的双向绑定 class 实现动态改变样式,但实际测试过程中,被绑定的数据是存在于 vuex 中的,鼠标在拖拽过程中会频繁执行 vuex 的 commit,导致性能低下,元素过多的情况下会出现卡顿现象,尝试直接使用 Jquery 修改元素,问题解决。

然后就是文件拖拽到指定文件夹的操作,我使用 vuedraggable 实现,这个组件主要是拖拽替换位置的,不过它可以重写 move 方法,自定义拖动、被拖动的方法,实现自己的需求。

代码节选:

image-20210208142840585

可以看到,部分事件中使用了 Jquery 进行动态修改、删除元素的 class,以及元素的显示与隐藏。当然了,在 Vue 中,新手需要注意双向绑定的数据中 Jquery 事件绑定优先级等问题。

本地上传

本地和 FTP 上传策略,都是直接走的服务器流量,由于安全性问题,FTP 策略需要从服务器中转后上传,前端使用百度的 Web Uploader 实现,该组件支持分片上传、队列等功能。

文件上传到后端以后,验证完成后会在本地磁盘创建唯一的分片目录,每一个分块通过分块序号进行命名,全部分块都上传完毕后进行合并,然后重复验证文件大小、以及是否允许上传等。

心路历程

Lsky Cloud 在几个月前就开始筹备,在简单的学习了 Golang 后便着手利用空余时间开发,虽然是断断续续的提交代码,但是期间积累了不少经验。

中间遇到了主线逻辑中比较难解决的问题,差点就放弃了,不过在几天后突然就冒出一个想法,顺着这个想法便解决了问题。

目前还有很多需要完善的地方,目前重心都在雕琢用户体验的部分,耗费的大部分时间也都在前端上,希望可以做出一个令自己满意的产品。

说点什么吧~ 取消回复
共有 22 条评论
  • 枯叶 iOS 14.4Google CriOS

    4月22日 10:54

    回复
    你好,我打算做一个免费图床网站,使用蓝空图床之后开启图片鉴黄发现用不了,上传之后就是502报错
  • jclser Windows 7 x64Google Chrome

    4月17日 13:56

    回复
    有趣的博客,仔细一看发现是个大佬,都是自己写的啊,很强
  • 魏嘉璇 Windows 10 x64Google Chrome

    4月16日 16:39

    回复
    什么时候开源啊,我想要用了……
  • Spoience Windows 10 x64Google Chrome

    3月30日 22:10

    回复
    Go 写的项目!期待ing。大佬会考虑添加WebDav挂载阿里云、又拍、七牛云之类的功能吗?很多网盘程序太缺乏直接挂载WebDav的功能了。另外,如果能增加挂载OneDrive之类的策略就更好了。Lsky Cloud 可以进行付费授权域名就更好了
  • 抚琴 Android 11Edge Android

    3月27日 21:46

    回复
    大佬,lsky pro上传图片后打开图片是404,后台也看不了图片预览,这是我没有设置好吗
    • Wisp X 博主Windows 10 x64Google Chrome

      3月27日 22:06

      回复
      @抚琴 访问图片的路径是优先取策略设置的域名,如果策略未设置域名则会使用站点的域名,域名错误的话就会导致图片无法访问。
    • 抚琴 Android 11Edge Android

      3月30日 14:31

      回复
      @Wisp X 谢谢大佬,我后来设置为本地就可以了,但是切换到ftp后上传的图片还是看不到
  • 胡说 Android 9Google Chrome

    3月26日 04:00

    回复
    Lsky Cloud什么时候出?我想购买
  • 云图床 Windows 7 x64Google Chrome

    3月15日 23:21

    回复
    在哪里可以下载Lsky Cloud ?
    • Wisp X Windows 10 x64Google Chrome

      3月16日 18:47

      回复
      @云图床 非开源的哦,目前还在开发中,进度50%
    • 云图床 Windows 10 x64Google Chrome

      4月1日 23:46

      回复
      @Wisp X 大概什么时候能完成开发?很期待 Lsky Cloud 
  • 晓晨 Windows 10 x64QQBrowser

    3月4日 11:35

    回复
    如果可以的话,希望可以加上onedrive储存环境
  • okok Windows 10 x64Google Chrome

    2月26日 21:16

    回复
    非常好的图床,请问支持虚拟主机安装吗。要是在增加github上传就厉害了,
  • wodesd Windows 10 x64Google Chrome

    2月22日 16:28

    回复
    支持作者,期待中
  • Seamonster Windows 10 x64Google Chrome

    2月22日 15:01

    回复
    哇哦,开始玩Go啦~不错哦,我觉得基于 vue 的 elementUI 更加现代化,可以试试
  • 刘老板 Windows 7 x64Google Chrome

    2月20日 16:35

    回复
    加油!支持!很期待。
Wisp X

不妄自菲薄,不矫枉过正; 不随波逐流,不固步自封。

欢迎访问熊二哈的猫窝,本站建议使用 Chrome 浏览器浏览以获得最佳效果。