V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yuuk520
V2EX  ›  Node.js

压测出现 no such file or directory, scandir 'XXX'

  •  
  •   yuuk520 · 321 天前 · 1497 次点击
    这是一个创建于 321 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一个基于 next.js 的项目使用 JMeter 在 docker 容器中进行压力测试,当并发数过高时,会出现以下错误,但该目录确实是存在的,并且随着并发数变高报错也变多。正常访问就不会出现。

    错误出现的代码在此: https://github.com/i18next/next-i18next/blob/205e9a4fe5d5d1baca9f5a82561096b6372e1432/src/config/createConfig.ts#L211

    2023-12-25 07:47 +00:00: Error: ENOENT: no such file or directory, scandir '/app/packages/eshop/public/locales/cn'
        at Object.readdirSync (node:fs:1405:3)
        at getLocaleNamespaces (/app/node_modules/next-i18next/dist/commonjs/config/createConfig.js:214:16)
        at /app/node_modules/next-i18next/dist/commonjs/config/createConfig.js:231:20
        at Array.map (<anonymous>)
        at getNamespaces (/app/node_modules/next-i18next/dist/commonjs/config/createConfig.js:230:44)
        at createConfig (/app/node_modules/next-i18next/dist/commonjs/config/createConfig.js:271:29)
        at _callee$ (/app/node_modules/next-i18next/dist/commonjs/serverSideTranslations.js:201:53)
        at tryCatch (/app/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:44:17)
        at Generator.<anonymous> (/app/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:125:22)
        at Generator.next (/app/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:69:21) {
      errno: -2,
      syscall: 'scandir',
      path: '/app/packages/eshop/public/locales/cn'
    }
    

    报错指向的是用的一个 next.js 的多语言库 next-i18next ,它在每次页面刷新的时候都会调用 fs.readdirSync 读取本地多语言 json 文件。

    我也试过在容器里面大量调用(定时器模拟) fs.readdirSync 也没出现报错。

    实在不知道是什么原因引起的...有了解的小伙伴吗?

    12 条回复    2024-01-08 16:41:26 +08:00
    thinkershare
        1
    thinkershare  
       321 天前
    我也遇到过,不知道什么原因,感觉是 I/O 句柄被耗尽了。
    yuuk520
        2
    yuuk520  
    OP
       321 天前
    @thinkershare 如果是这种情况有什么工具可以监测到吗?
    namelesswryyy
        3
    namelesswryyy  
       321 天前   ❤️ 1
    试试把资源一起打包到 docker ,不要挂载上去
    如果要是 docker 在 windows 上的话,那就是 windows 锅
    yuuk520
        4
    yuuk520  
    OP
       321 天前
    @namelesswryyy 不太理解,能具体说下打包上去和挂载上去区别么?
    cloverzrg2
        5
    cloverzrg2  
       321 天前
    宿主机的 `ulimit -a` 返回啥?尝试设置一下? `ulimit -n 100000`
    另外,docker 的参数尝试加下
    `docker run --ulimit nofile=262144:262144`
    zhangky
        6
    zhangky  
       321 天前
    如果资源内容不变,不需要每次都读,可以做个缓存。
    luojiyin87
        7
    luojiyin87  
       321 天前
    docker 默认是没 ulimit ,可以打开无限的 I/O 句柄,不会主动释放,耗尽主机的 I/O 句柄。
    ```shell
    grep 'Limit' /lib/systemd/system/docker.service
    # Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
    StartLimitBurst=3
    # Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
    StartLimitInterval=60s
    # Having non-zero Limit*s causes performance problems due to accounting overhead
    LimitNOFILE=infinity
    LimitNPROC=infinity
    LimitCORE=infinity
    ```

    但是主机内是有 ulimit ,可以分配给 docker 的 I/O 句柄是有限。

    ```shell
    ulimit -n
    1024
    ```
    1 调高主机的 ulimit ,2 限制 docker 的 ulimit
    yuuk520
        8
    yuuk520  
    OP
       321 天前
    @zhangky 理论是这样,不过就得改这个第三方库了
    ntedshen
        9
    ntedshen  
       320 天前
    在 wsl 下使用 await fs.readdir 读取文件过多的文件夹时候也遇到过。。。
    怀疑是某种 os 内置的超时。。。
    因为没当回事所以没试过修改 ulimit 。。。
    julyclyde
        10
    julyclyde  
       320 天前
    是不是用了 inotify 功能啊?这个也是有限的

    既然可以主动触发错误,那我建议挂个 strace 看看
    yuuk520
        11
    yuuk520  
    OP
       318 天前
    @julyclyde 怎么看 inotify 有没有启动?
    julyclyde
        12
    julyclyde  
       318 天前
    @yuuk520 “启动”这个词不太合适
    建议你挂上 strace 看看
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3439 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 11:07 · PVG 19:07 · LAX 03:07 · JFK 06:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.