部署 使用 Capistrano 部署,时间超长,原因是什么?

sefier · June 28, 2020 · Last by SpiderEvgn replied at July 16, 2020 · 3271 hits

最近一年没用 rails,最近一个小项目,上了 rails,把环境搭建了一遍,采用 Rails 6.0 + Mysql 8.0 + Ruby 2.6.3,部署上线。发现 Capistrano 部署极慢,哪怕没做任何资源文件的修改,也要很长时间。卡在了 deploy:assets:precompile 上面,这是什么原因,如何避免?

比如下面这个,居然耗时接近 500S

输出信息里有写,你的 application.js 文件超出了推荐大小

建议先检查一下里面用了什么第三方库,会占用这么大文件。

这应该只是一个提醒吧,我本地执行这个命令很快。部署这么慢,不应该是这个问题。

Reply to sefier

编译前端资源很消耗 CPU 的,我记得有 Cap 的 recipe 在本地编译传到服务器的

前端编译是大坑,之前用 gitlab ci 跑 yarn build,cpu 马上上 100 多

第一次是慢的,但是第二次就快了。也可以吧node_modules,tmp/cachepublic/packs加到 linked_dirs。

经过一天的时间,这个问题解决了。本着有问有答的精神,我总结一下:

1)关于原因:应该就是服务器的 CPU 性能原因,买的是阿里云的突发性能实例,因为这个项目只有我们内部偶尔用,本着节约成本的精神买的高度共享实例。

2)解决方案:诚如@imadbc 所言,我是用这个插件解决的,我一开始也注意到了这个插件,之所以没考虑,是因为已经一年多没人维护了,大概率是不良项目,没想到还能用。

3)这个方案有个问题,服务器是 rbenv,本地是 rvm 的情况下,会在本地执行 rbenv 命令,而本地没有,故而报错。为了解决这个问题,我本地将 rvm 迁移到 rbenv,顺便我把 brew 重装了一下,就这两个事情折腾了我一天,遇到了各种奇葩问题,有五六个小时不停的 google 和 stackoverflow,真是什么问题都遇到了。虽然 rbenv 理念更先进,不知道是不是我打开方式不对,居然一直跳坑,主要原因可能跟 homebrew 的重装有关系。总之,花了一天时间都是踩这些坑。

4)如果有同学想用这个方案的话,文档里写移除require 'capistrano/rails/assets',你的文件里可能没有这一行,是因为你用了capistrano/rails,那么删掉这一行,改成 require 'capistrano/bundler' require 'capistrano/rails/migrations'

5)效果测试:没有修改 js 文件,修改其他文件,耗时 17 秒;如果修改了 js 文件,耗时 24 秒。表现良好,完全解决了这个问题。

跑题一下,是时候改用 Docker 部署了。

发布前通过 GitLab CI 打包好 Docker Image,发布 / 回滚 / 服务器水平扩展将会变得更容易。

Reply to huacnlee

目前使用 docker-compose 的时候出现一个问题

在升级 image 完毕后, 重新运行 docker-compose 的时候 这个时候新的 docker image 有启动时间 这段时间会 502

大概几秒,docker 里的 puma 启动完毕后就没这个现象了

Reply to huacnlee

研究了一段时间,因为是小项目,对 Docker 不熟悉,所以放弃了。我离开 Rails 社区有段时间了,倒是有兴趣在大型项目这么操作,但是网上资料少得可怜,有没有什么推荐的 Rails 部署方面的 Docker/K8S 资料推荐一下?我之前用 capistrano 部署过 300 台服务器,实在很痛苦。

Reply to jicheng1014

compose 是用于本地开发而不是用于部署的。部署要用 swarm,配置是延续 compose 的配置。

puma/unicorn 热重启是通过管理进程,在重启过程保持接口的监听,在重启结束后移交接口。swarm 也实现了这样的重启,swarm 本身接管网络,滚动重启容器,维持访问把流量转到可用的容器上。

Reply to Rei

ps 是使用的 swarm 的

类似这样的配置么

deploy:
  replicas: 3
  update_config:
    parallelism: 1
    delay: 5s

另外还有个地方还想请教下

就是 docker 下 静态文件夹 public 的管理。

因为配置等原因,我们还是期望 nginx 不在容器中运行 puma 提供的服务,本身我们可以依赖 upstream, 但是静态文件这块就有点尴尬,

之前我们的做法是 有个 container 专门接受从外层主机挂载的目录 /tmp/public, 之后这个镜像 run 的指令就是 cp -r public /tmp/public

这样外层的机器就获得了镜像里的 public 文件夹,但是我觉得这种方式属于取巧的邪道

能否参考下您的解决方案 或者 有人能好心分享下么?

Reply to jicheng1014

静态文件用 CDN 处理。Web server 提供静态文件,CDN 回源的时候缓存。

谢谢楼主。

Reply to jicheng1014

我跟你一样。。。

You need to Sign in before reply, if you don't have an account, please Sign up first.