windows 客户端 上传海量文件(5 万+),性能问题如何处理?

2020-04-01 10:24:46 +08:00
 TomeWong

客户端用是 Electron 开发,在批量上传大量文件过程中出现性能问题。

上传前要计算文件的 md5 值,来实现秒传,但上传大量文件,如果每个文件都计算 MD5,然后在加入队列中,页面中就会出现空白响应,这个过程主要是计算 MD5 值,读文件流。

目前的问题是,上传开始挺快的,但上传一段时间发现上传慢了下来,而且上传几个小时后,页面可能出现卡死,或者上传失败。想问下现在该怎么优化批量加入队列,显示到页面中;然后批量上传这些文件,各位大佬有没有好的想法,指点下

3120 次点击
所在节点    程序员
22 条回复
crella
2020-04-01 10:52:19 +08:00
百度网盘是有多个名为 baidunetdiskhost.exe 的后台进程。

要不就新建一个不是 electron 的后台进程,这个进程负责计算 md5 和上传,然后指定协议与前台 electron 通讯。

有时候百度网盘抽风,baidunetdiskhost 吃满单核 cpu,但是程序 ui 是没卡顿的。
sc3263
2020-04-01 10:56:15 +08:00
计算和上传的逻辑放到独立的子进程中去。
或者写个 addon,在 addon 中新建线程进行处理。
TomeWong
2020-04-01 10:56:49 +08:00
@crella 我目前想到的是用 web worker 来分离计算 MD5 值,但效果不是很明显,文件数量多了,还是有问题。我先试试,谢谢大佬
TomeWong
2020-04-01 10:58:29 +08:00
@sc3263 electron 分主线程和渲染线程,我现在是将计算和上传的逻辑全部放在了渲染线程中
nannanziyu
2020-04-01 11:05:57 +08:00
密集型任务放到 Main 和 Render 里都不合适
用 node-gyp 写到 c++里去
TomeWong
2020-04-01 11:20:11 +08:00
@nannanziyu 有相关的库或者类似么
Mithril
2020-04-01 11:25:06 +08:00
@TomeWong 不要放在同一个进程,文件 IO 也不要用多线程。
g00001
2020-04-01 11:34:30 +08:00
主进程 /渲染进程 - 这个是跨进程了,密集的跨进程通信效率不会很高。
有些后台线程与界面的交互可能存在优化的空间,例如有时候过于密集的通知界面工作状态其实是无意义的。
时间长就出问题,可能是存在内存泄露,JS 这种语言,太容易搞出内存泄露了。

做这种事跟多线程开发利索的语言不能比。
TomeWong
2020-04-01 11:56:10 +08:00
@g00001 用 js 实现这种场景问题就很多
sc3263
2020-04-01 12:06:39 +08:00
@TomeWong Electron 应该是主进程和渲染进程吧,之间用 IPC 通讯。
我们的客户端也是 Electron 实现的,计算 sha1 和上传都是放在 addon 里用 C 实现的。
这种 CPU 密集任务还是不要为难 js 了。
emeab
2020-04-01 12:09:41 +08:00
放过 js 吧. 这些任务丢给 go 做不好吗? electron 做套壳吧
xiangyuecn
2020-04-01 12:21:04 +08:00
跟语言无关,写的太烂就算用 C 也不会快到哪去,v8 里面的 js 也并不慢,但你怎么可以把复杂运算任务丢到 UI 线程😂
jones2000
2020-04-01 12:56:48 +08:00
都做成客户端了,直接 c++开并行分块上传( probuffer), 计算 MD5 慢, 直接使用 GPU 计算, 页面只读取状态就可以了。
TomeWong
2020-04-01 14:12:44 +08:00
@xiangyuecn 刚开始用 Electron 开发,是新手,上传文件的多的话,就会出现问题
xcstream
2020-04-01 14:18:25 +08:00
子进程上传 传一个文件就关闭 就不会泄露什么
magicdawn
2020-04-01 15:18:08 +08:00
promise.retry 欢迎你. 加超时, 加重试.

md5 node.js 里是同步的, 解决:
主进程用 worker_threads, renderer 进程用 web worker

P.S web worker 可以使用 node.js API, 但不能用 electron API & node native addon. see https://www.electronjs.org/docs/tutorial/multithreading#available-apis
cheng6563
2020-04-01 17:48:18 +08:00
@xiangyuecn 计算 md5 的开销很高的吧
MintZX
2020-04-02 09:51:58 +08:00
用的如果是云服务的话,直接让客户端上传到云服务里面,然后做一个 callback 到你的后端服务器就行了。
TomeWong
2020-04-02 10:03:55 +08:00
@cheng6563 小文件还好,大文件计算的时间会长些
TomeWong
2020-04-02 10:17:36 +08:00
@magicdawn 大佬,选择文件夹,这个文件夹包含大量的文件,这个过程会有计算 MD5 值,读文件流,如果是统一处理,然后再加入对列中,处理,中间会存在一部分空白响应等待的问题

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

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

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

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

© 2021 V2EX