V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
TomeWong
V2EX  ›  程序员

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

  •  
  •   TomeWong · 2020-04-01 10:24:46 +08:00 · 3080 次点击
    这是一个创建于 1458 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    22 条回复    2020-04-09 10:27:10 +08:00
    crella
        1
    crella  
       2020-04-01 10:52:19 +08:00 via Android
    百度网盘是有多个名为 baidunetdiskhost.exe 的后台进程。

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

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

    做这种事跟多线程开发利索的语言不能比。
    TomeWong
        9
    TomeWong  
    OP
       2020-04-01 11:56:10 +08:00
    @g00001 用 js 实现这种场景问题就很多
    sc3263
        10
    sc3263  
       2020-04-01 12:06:39 +08:00
    @TomeWong Electron 应该是主进程和渲染进程吧,之间用 IPC 通讯。
    我们的客户端也是 Electron 实现的,计算 sha1 和上传都是放在 addon 里用 C 实现的。
    这种 CPU 密集任务还是不要为难 js 了。
    emeab
        11
    emeab  
       2020-04-01 12:09:41 +08:00
    放过 js 吧. 这些任务丢给 go 做不好吗? electron 做套壳吧
    xiangyuecn
        12
    xiangyuecn  
       2020-04-01 12:21:04 +08:00
    跟语言无关,写的太烂就算用 C 也不会快到哪去,v8 里面的 js 也并不慢,但你怎么可以把复杂运算任务丢到 UI 线程😂
    jones2000
        13
    jones2000  
       2020-04-01 12:56:48 +08:00
    都做成客户端了,直接 c++开并行分块上传( probuffer), 计算 MD5 慢, 直接使用 GPU 计算, 页面只读取状态就可以了。
    TomeWong
        14
    TomeWong  
    OP
       2020-04-01 14:12:44 +08:00
    @xiangyuecn 刚开始用 Electron 开发,是新手,上传文件的多的话,就会出现问题
    xcstream
        15
    xcstream  
       2020-04-01 14:18:25 +08:00
    子进程上传 传一个文件就关闭 就不会泄露什么
    magicdawn
        16
    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
        17
    cheng6563  
       2020-04-01 17:48:18 +08:00 via Android
    @xiangyuecn 计算 md5 的开销很高的吧
    MintZX
        18
    MintZX  
       2020-04-02 09:51:58 +08:00
    用的如果是云服务的话,直接让客户端上传到云服务里面,然后做一个 callback 到你的后端服务器就行了。
    TomeWong
        19
    TomeWong  
    OP
       2020-04-02 10:03:55 +08:00
    @cheng6563 小文件还好,大文件计算的时间会长些
    TomeWong
        20
    TomeWong  
    OP
       2020-04-02 10:17:36 +08:00
    @magicdawn 大佬,选择文件夹,这个文件夹包含大量的文件,这个过程会有计算 MD5 值,读文件流,如果是统一处理,然后再加入对列中,处理,中间会存在一部分空白响应等待的问题
    TomeWong
        21
    TomeWong  
    OP
       2020-04-08 11:24:12 +08:00
    @sc3263 不懂 c++和 c,开发起来比较困难
    TomeWong
        22
    TomeWong  
    OP
       2020-04-09 10:27:10 +08:00
    @xiangyuecn 大佬,可以指点些么?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3391 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 10:40 · PVG 18:40 · LAX 03:40 · JFK 06:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.