nodejs 打包_NodeJS Docker 打包优化 - Go语言中文社区

nodejs 打包_NodeJS Docker 打包优化


d8590bd7072382446b895f8c6a69579c.png

最近 NodeJS 后端工程的 Docker 打包优化工作总算告一段落了。其实去年 12 月份就开始试点改造,期间遇到了很难复现的间歇性 socket hang up 问题,不得不延后。上周终于抽出时间全力排查了下,发现是升级 NodeJS 到 6.15.0 后,其有一个 HTTP Keep-alive 连接超时的 Bug。不得不感慨:这小版本升级也要格外小心啊。

回到正题。在确认没有其他附带问题后,在试点的基础上,又增加了一些新的目标。总的目标大概如下:

  • 支持优雅停机,要求 Node 进程能够接收到 SIGTERM 软终止信号
  • 提升打包速度,充分利用 Docker Layer 缓存机制,降低 yarn install、node_modules 拷贝等高 IO 动作的运行频率
  • 保证源代码安全,不要将源代码打包到镜像里
  • 尽可能降低最终镜像大小,不要包含不必要的文件(如 node_modules 中的 devDependencies)

下面从各个目标一一介绍下我们的优化实践之路。

基础镜像设置

由于之前的基础镜像使用的是 FROM node:6,只有 major version,没有指定 minor version、patch version。当该基础镜像 minor 或 patch 版本更新后,如果本地的镜像缓存也被清除了,那么打包就会使用新版本的基础镜像。这也是上面不经意升级到 node 6.15.0 的原因。所以这里我们限定了基础镜像的全版本:FROM node:6.16.0。

我们的产品主要在国内使用,运维人员也都是在国内。为了更方便查看日志中的时间、方便程序中的日期计算,把时区调整为北京时区(即东八区):RUN rm /etc/localtime && echo "Asia/Shanghai" > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata。注意,Debian Stretch 版本后需要 rm /etc/localtime,否则时区修改可能无法生效(被替换回原值)。

最后设置镜像的工作目录:WORKDIR /app。这样,我们新的基础镜像就完成了。

支持优雅停机

优雅停机(Gracefully Shutdown),就是当应用(进程)要被关闭时,首先会被发送一个软终止信号。应用在收到这个信号后,执行清理工作,然后自行退出。如果在指定的时间内没有自行退出,则会被强制关闭——这自然就不优雅了。这个软终止信号一般就是指 SIGTERM。NodeJS 进程默认会对 SIGTERM 信号进行响应,执行进程退出。但是默认的监听程序并不会执行清理工作。我们需要显式监听该信号,并在清理完毕后执行 process.exit(0) 以退出进程。

然而,在 Docker 容器里实现优雅停机会有一些新的问题需要面对。当使用 docker stop 停止一个容器时,docker 会首先发送一个 SIGTERM 信号给容器内的 PID=1 进程,也就是常说的 init 进程。如果 PID=1 进程没有在规定时间(一般 10 秒)内退出,则 docker 会发送 SIGKILL 信号强制退出容器内的所有进程。PID=1 进程比较特殊,在 linux 下,它会忽略所有默认的信号监听程序,也就是说收到 SIGTERM 默认不会退出。所以,我们的 PID=1 进程要求能显式监听 SIGTERM 并执行后续动作。

然而,当我们使用 shell form 的 ENTRYPOINT 或 CMD 指令时——如 CMD npm run start,Docker 容器会默认启用一个 Shell 来运行后面的指令。此时 PID=1 进程是 /bin/sh,完整的运行命令是 /bin/sh -c 'npm run start'。当 sh 收到 SIGTERM 信号时,它自身并不会退出。因为 sh 并没有显式监听 SIGTERM,默认的信号处理器被忽略了。自然 sh 内部也不会把信号转发给子进程。最后只会超时,继而被 SIGKILL 强制关闭。

Docker 推荐我们用 exec form 的 ENTRYPOINT 或 CMD 指令,如 CMD ["npm

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_39611308/article/details/111679473
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-06-13 14:10:04
  • 阅读 ( 1001 )
  • 分类:前端

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢