一个解决方案想了好久

2018-05-21 12:40:57 +08:00
 jiangnanyanyu

目前我司的一个产品,有一个功能是这样的: 1.web 端上传文件,文件的类型包括 视频,文档,音频(其中视频和文档( office 全家桶,pdf,txt 等)) 2.文件上传后会判定是否需要转换操作,然后启用新的进程去执行相关转换软件的 CLI 3.在转换操作前会执行数据库操作( oracle ),相关文件的操作记录,转换完成后更新记录操作 目前的问题: 1.文件上传后,我们是不知道转换的进度的,只知道有没有转换成功 或者失败,具体服务器是一个什么状态是不知道的。 2.服务器是 win 的,因为在 linux 下文档转换的效果达不到要求 3.这一个过程是是耦合在一起的 现在想要改成的样子: 1.想要将文件上传和文件转换拆分成单独的服务,文件上传已经单独搞成 nio 来提高性能,文件转换正在重构中 2.文件转换的服务 要求是可以查询到实时的进度,文件上传后可以触发文件转换服务器去转换,进度可以实时的在前端显示出来 目前难点: 文件上传服务和文件转换服务的通讯机制,我想了 http 的形式,mq 的形式(大材小用),观察者模式( watcher ) 都不是好方法,比如 http 的形式,因为转换肯定不是一个很快的过程,所以容易超时。 有什么方案可以解决这样的问题吗? 一个是通讯机制,一个是实时进度问题

2505 次点击
所在节点    问与答
12 条回复
whileFalse
2018-05-21 13:33:05 +08:00
什么叫实时进度?我理解是指上传了 100 个文档,转换了 40 个,进度 40%,是这个意思不?
用 http 轮询最简单。
也可以试试 websocket。
jiangnanyanyu
2018-05-21 13:39:51 +08:00
@whileFalse 文档这种转成 jpg 这种不耗时,但是视频转码会比较耗时。比如单个视频转换要可以在前端看到它的进度
luoway
2018-05-21 13:47:09 +08:00
目前难点: 文件上传服务和文件转换服务的通讯机制
就是不熟悉前后端通信咯
pelloz
2018-05-21 14:00:57 +08:00
对于前端展现的进度应该不是完全准确的进度。
你的需求应该是有两个进度需要展示:
第一个是文件上传的进度,这个你自己可以百度到很多答案。
第二个是文件已经上传完毕后的转换进度。
前端可以采取轮询,比如每 10 秒,查到的只是当前进度然后展示到页面。所以我不是很懂你为什么说会有超时的问题。
imn1
2018-05-21 14:17:54 +08:00
除非你的 cli 命令有实时交互,否则只能判断是否完成
搜索 powershell start-process -wait
chairuosen
2018-05-21 14:26:15 +08:00
这个需求你做一下。完了么,完了么,完了么,完了么,完了么。。。。
1010011010
2018-05-21 14:57:31 +08:00
这标题和内容看得我很难受
saulshao
2018-05-21 16:54:24 +08:00
这个设计应该包括以下的程序:
1. 文件上传,包括是否需要转换的判断,完成后将文件的唯一标识符放到数据库里,标识一个状态
2. 另外一个程序将文件标识符从数据库里面读出来,把状态改成"处理中",然后开始处理,处理完成后改成"转换完",如果需要很久,就通过一个定时操作记录进度并在前台显示,进度这个事情其实就是估计值和实际处理之间的比值,参考 Windows 文件夹复制的实现,并不是一个很靠谱的信息。
3. 上面的程序 2 负责记录相关的操作日志之类的信息
ZhLTE
2018-05-21 17:48:07 +08:00
排版难受
collinswang
2018-05-21 19:11:24 +08:00
前端一句话就能解决:后台转换中,请稍后查看是否转换完成
holystrike
2018-05-21 20:28:57 +08:00
视频转换,无法获知进度,但是可以变通解决,就是预估时间

一般某大小文件转为某个码率所需的时间不会有太大的差异,可以预估什么时间完成,告知用户即可
zavieryip
2018-05-23 10:47:33 +08:00
其实你本身就有方案了吧,这样做是为了改善交互.
我说说具体的流程和实现,毕竟刚好不久前做过类似的文件上传处理,语言是 php.

前端:
1.上传文件
2.请求处理接口
3.轮询后端处理进度(2 之后的回调)

后端:
因为实际处理时间过长,会导致超时,所以可选的处理就只有非阻塞异步,同时要实时反馈,因此不选择队列处理

1.处理接口
直接返回处理结果(本次处理标识,统计信息),并且用非阻塞的方式调用异步接口,如果你也是 php,推荐使用 fsockopen ,当然 curl 也可以,调用异步接口后就断开.
2.异步接口
这里放实际的业务处理,记得设置执行不超时,因为处理结果是需要实时反馈的,因此每一个进度处理完的结果放在缓存(处理标识)比较合适.
3.轮询进度接口
通过 处理标识 直接读放在缓存的结果就好了.

可能有些说得不准确,但希望有点帮助吧.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/456475

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX