Erlang/OTP 生产应用部署简介
Posted
技术标签:
【中文标题】Erlang/OTP 生产应用部署简介【英文标题】:Introduction to Erlang/OTP production applications deployment 【发布时间】:2012-09-27 08:54:48 【问题描述】:我想开发一个 Erlang/OTP 应用程序并将其部署到 VPS 上的生产环境中。
我非常熟悉在本地机器上开发 Erlang 代码,我的问题是关于部署的。
基本上,我想知道我应该采取哪些步骤才能将 Erlang 代码从本地机器移动到生产服务器并使其运行,即可供用户使用。
注意:我已经阅读了一些关于 Erlang and command line、Erlang code 模块、Erlang releases 的文档,但我仍然不确定如何执行所需的任务。
不过,我想在服务器上部署基于 Erlang 的软件比为 LAMP 执行 sudo tasksel
更棘手。
我计划有一个 Erlang/OTP 应用程序,它具有 Mochiweb、CouchDB (couchbeam) 和 boss_db 作为依赖项。
所以,我的新手关于在生产服务器上部署所有这些东西的问题如下:
我打算使用Ubuntu Server 12.04;有没有更好的选择让 Linux 发行版在生产环境中用于 Erlang/OTP? 应该如何组织所有代码?我应该将我的应用程序放入 /home/myapp/ 目录,然后将所有依赖项放入 /home/myapp/deps 吗?还是应该将所有依赖项放入/usr/local/lib/erlang/lib? (由代码返回:get_path())。我应该以某种方式定期更新依赖项还是应该冻结它们? 如何让整个应用程序在服务器启动后启动?它应该是某种 bash 脚本还是其他什么? 我知道 Erlang 允许热代码升级,但我应该如何组织呢?在 Rails 上我可以update the code with git,Erlang 世界中是否存在类似的东西?【问题讨论】:
【参考方案1】:有两种类型的依赖:内部和外部。如果你想以正确的方式做这件事(tm),开始工作需要一些时间:
外部依赖:
首先考虑后者,external 依赖项是在您的应用程序运行之前必须运行的其他东西。例如 PostgreSQL 数据库或 Riak 集群。对于那些,您通常只使用 Ubuntu 中的常用工具来使其正常启动。我在使用monit
完成这些任务方面有很好的经验:
http://mmonit.com/monit/
内部依赖:
对于internal依赖,你需要将你的程序安排到Erlang VM里面的applications中。它们相互依赖,就像外部依赖一样。例如,您的主应用程序可能需要在启动之前运行记录器。然后你创建一个release。 release 将 Erlang 二进制文件和必要的库/beams/应用程序复制到发布目录中,形成一个独立的 Erlang 系统。它包含一个boot-script,它告诉如何以正确的顺序启动应用程序并保持它们运行。因此,您可以压缩此版本,将其复制到服务器,然后启动它。这里介绍了一些基础知识:
http://learnyousomeerlang.com/release-is-the-word
但也请阅读之前关于应用程序的章节。您还可以让rebar
致电reltool
为您构建一个版本。这是我通常做的。
热升级:
可以通过多种方式处理生产中的热升级。您可以将梁移动到机器上然后部署它,获取外壳然后调用l(Module)
将其加载到正在运行的系统中。这适用于较小的修复。对于大型系统升级,您可以进行发布升级,这将在不停止服务的情况下即时升级正在运行的系统。但是,如果您的系统大多不共享,通常不值得。相反,您可以拥有多台机器并按顺序升级它们。
例如,您可以升级一台机器,然后使用像 HAProxy 这样的系统将 2% 的请求发送到新系统。然后系统地调高请求负载权重。
【讨论】:
我假设在现实世界中没有人将源代码推送到生产机器上来更新系统,而只是束文件,对吧? “独立的 Erlang 系统”是指带有 .beam 文件的版本,应该由安装了 Erlang VM 的生产机器执行?【参考方案2】:虽然@I GIVE CRAP ANSWERS 给出了相当详尽的总结,但我觉得有必要使用sync,它有助于自动化模块的热重新编译和重新加载。
简单的方法是将同步指定为 rebar 依赖项,然后在准备部署升级时,可以在 Erlang 节点上运行 sync:go()
。这将启动同步引擎,它监视文件系统的变化。然后你可以使用 git 推送到你的服务器。 Sync 会注意到文件的变化,重新编译它们,并自动加载新的梁。
然后,您可以立即运行 sync:stop()
告诉系统停止监视文件系统更改(通常不建议在实时服务器上保持同步运行,只是为了防止意外重新编译,无论出于何种原因,源文件更改,这是无意的。
【讨论】:
虽然这可能适用于较小的事情,但当有很多应用程序具有混乱的依赖关系时,这是否有可能真正搞砸事情? (即应用程序解决了什么问题?) 对于较小的升级来说,这绝对是一个更简单的解决方案(而且“简单”也有它的缺点——主要是它不是一个全面的解决方案)。新应用程序的重大升级,以及新升级的应用程序,是的,你会想要使用更全面的东西。但是对于不需要添加或升级依赖项的将更改推送到生产环境,它非常方便并且几乎不需要乱七八糟:只需推送代码即可升级。 也就是说,sync 也会升级 rebar deps(基本上,加载到 erlang 系统中的任何内容,以及源文件和梁文件的目录都会受到监控)。所以像rebar update-deps
这样的操作也会热加载新的应用程序。当然,如果应用升级编译失败,那么你就会处于不一致的状态(有一半的依赖应用升级了),这显然不是一件好事。所以它可以为此工作,但它不是具有混乱依赖层次结构的最佳选择。
看起来很有趣;我再看看它 - 我一直在使用 mochiweb 的 reloader.erl,但会检查 Sync - 将所有应用程序替换为更简单的项目会很好......
切碎,感谢您对同步的参考。我接受了另一个答案,因为它更具描述性和一般性。无论如何,谢谢。以上是关于Erlang/OTP 生产应用部署简介的主要内容,如果未能解决你的问题,请参考以下文章