增加 2016-08-19

Erlang/Elixir: 用Distillery替换Exam打包器

更新 2016-07-25

这里有一篇Gitbooks上的文章专门简介如何搭建,配置一个Phoenix应用程序的自动化构建,部署的过程Phoenix持续部署

Edeliver 是一个基于 deliver 的构建和部署工具.

它提供了一个 Bash 脚本来帮助你构建, 部署, 以及执行热代码升级

Edeliver 部署关系图示

本文我们来聊一聊关于 Erlang/Elixir 的部署问题. 最原始的 Erlang, 我们要使用一大堆工具, 比如 reltool, 后来有了rebar, 还后来 relx 也出来了, Elixir 生态链中还有个 Exrm 打包工具, 是基于 relx 创建发布包的, 打包好了呢, 需要部署到服务器上去运行.

Exrm 打好的包, 一般情况, 我直接用 scp 复制到服务器上的某个目录, 然后在登录到远程服务器解压, 升级等操作. 而 Edeliver 让这个过程完全自动化, 提高了效率, 并且更加适用于中等规模的应用程序部署.

构建 Erlang/Elixir 初始发布版本, 并部署到产品服务器.

mix edeliver build release --branch=master -V

mix edeliver deploy release to production -V

mix edeliver start production -V

把上面三个单独的命令合并为一个

mix edeliver update production --branch=master --start-deploy -V

配置

在项目目录下创建一个 .deliver 目录, 然后在其中添加 config 文件.

#!/usr/bin/env bash

APP="your-erlang-app" # name of your release

# 构建主机的地址, 用户名, 和构建目录

BUILD_HOST="build-system.acme.org"

BUILD_USER="build"

BUILD_AT="/tmp/erlang/my-app/builds"

# 测试目标主机的地址, 用户名, 和部署目录, 多个目标服务器地址用空格分隔开

STAGING_HOSTS="test1.acme.org test2.acme.org"

STAGING_USER="test"

TEST_AT="/test/my-erlang-app"

# 产品目标主机的地址, 用户名, 和部署目录, 多个目标服务器地址用空格分隔开

PRODUCTION_HOSTS="deploy1.acme.org deploy2.acme.org"

PRODUCTION_USER="production"

DELIVER_TO="/opt/my-erlang-app"

本质上, Edeliver 使用 SSH 和 scp 来部署发布. 如果需要无密码登陆, 可通过 ssh-keygen 工具创建密钥对, 把公钥添加到服务器的 ~/.ssh/authorized_keys 文件中即可.

项目配置

defp deps do

[{:edeliver, ">= 1.2.8"}]

end

def application, do: [

applications: [

# ...

:edeliver,

],

]

不同的部署目标不同的配置

对于一个需要实现 Failover/Takeover 分布式应用程序来讲, 每个节点的配置是不一样的, 这样在部署的时候就要去编写不同的配置文件.

Edeliver 提供了这样一个功能

TODO::目前项目还没有到这个阶段以后再研究.

构建

必须在和目标系统类似 (建议完全一样的系统) 的系统上构建. 如果想在 Linux 上部署产品系统, 那么发布也应该在 Linux 系统上构建(建议使用相同厂商的 Linux 发型版). 不要求在产品系统上安装 Erlang/OTP 和 Elixir 运行时, 他们会随打包系统自动包含进发布包分发到产品系统上. 下面的配置变量是必须的:

Name

Description

APP

发布的应用程序名称

BUILD_HOST

构建发布包的主机名称或IP地址

BUILD_USER

构建主机上的本地用户名称

BUILD_AT

在构建主机上构建发布包的目录.

构建完成后, 发布包会被复制到你的本地 .deliver/releases 目录. 然后通过下面的命令发布到产品服务器. 如果成功编译和生成发布包. 发布包会从构建主机复制到发布存储, 默认发布存储的位置在项目根目录下的 .deliver 目录的 releases 子目录, 但可以通过配置环境变量来自定义, 例如:

准确的讲, 是复制到 RELEASE_STORE 环境变量指定的位置, 如果设置了该环境变量的话. 如果没有设置 RELEASE_STORE 环境变量, 默认为项目根目录的 .deliver/releases 子目录.

RELEASE_STORE=/tmp/.deliver # 本地目录

RELEASE_STORE=user@releases.acme.org:/releases # 远程主机

RELEASE_STORE=s3://AWS_ACCESS_KEY_ID@AWS_SECRET_ACCESS_KEY:bucket # 亚马逊S3

发布使用RELEASE_DIR=环境变量来确定发布归档包的位置. 如果未设置, 默认目录包含RELEASES文件的目录. 比如: 如果$APP=myApp, RELEASES的位置为rel/myApp/myApp/releases/RELEASE. 关于完整的 edeliver 命令, 可以通过运行 mix help edeliver 查看:

别自己创建 $BUILD_AT, $TEST_AT, $DELIVER_TO 目录. config/*.secret.exs 应该放在$CONFIG_AT目录, *.vm.args 文件处理节点名称, 集群等配置参数

构建一个全新的版本

mix edeliver build release --version=0.0.1

部署第一个版本

mix edeliver deploy release to production --version=0.0.1 --start-deploy

构建一个升级版本

热升级包含该两条路径

从Git仓库发布一个升级包

从之前发布的版本构建一个升级包

提升版本号, 在 mix.exs 提升项目的版本号, 下面的命令是直接从源码仓库构建一个热升级包

git commit -m 'Bump version to 0.0.2' # 提交

git tag 0.0.2 # 打TAG

mix edeliver build upgrade --from=0.0.1 --to=0.0.2 # 构建

部署一个升级版本

mix edeliver deploy upgrade to production --version=0.0.2

构建从 v1.0 到 v2.0 的升级包, 并部署升级到产品环境

mix edeliver build upgrade --from=v1.0 --to=v2.0

mix edeliver deploy upgrade to production

或者, 如果在发布存在有旧的发布版本, 可以用那个旧的发布版本来构建升级而不是Git的旧版修订/Tag

mix edeliver build upgrade --with=v1.0 --to=v2.0

mix edeliver deploy upgrade to production

注意 --from= 和 --with= 的区别. --from=指定git仓库的tag, --with=指定旧的release版本号. 可以通过命令mix edeliver show releases查看当前有哪些版本可用.

# 运行Ecto 移植

mix edeliver migrate production

或者使用 --run-migrations 选项在升级期间自动运行

升级 Patch 版本号

mix edeliver build release --increment-version=patch -V

这个命令也是用于构建一个发布包, 只是他会从Git工作区读取最新的Tag版本, 并在此基础上加1, 比如当前仓库中的Tag最新为 1.0.2, 那么该命令会创建一个 1.0.3 的发布版本.

单个命令完成升级

mix edeliver upgrade production -V

上面这个命令将会执行如下步骤:

检查所有运行节点的当前版本

验证所有节点运行在相同的版本

构建从该版本到当前版本的升级包

自动给 relup 文件打补丁

节点运行的同事部署升级包(热更新)

验证所有的节点运行在已升级的版本

部署发布包到其他没有处于运行状态的节点

排错

构建主机需要安装好 Erlang/Elixir 的构建环境, 推荐使用 kerl 编译 Erlang, kiex 安装 Elixir. 然后把下面两行脚本添加到用户目录的 .profile 文件中. 目的是让 Edeliver 能够找到 Elixir 工具的位置

. /home/ycc/.kerl/installs/18.3_systemtap/activate

test -s "$HOME/.kiex/scripts/kiex" && source "$HOME/.kiex/scripts/kiex"

kiex use 1.2.5 > /dev/null 2>&1

关于热升级的问题

根据实践验证, 请保证你的项目中 applications, deps 升级前后保持一致, 否则热升级可能导致失败, 如果applications, deps有修改, 这种情况下最好用下面的命令做一次全新部署.

mix edeliver build release --version= -V

mix edeliver deploy to production --version= -V

mix edeliver start production -V

关于 -V, --verbose 参数

我们在构建发布包的时候, 有时候会出错, 可以通过构建是添加 -V 参数来看到构建过程的大量信息, 包括 git 本地工作区的 HEAD 的指向, 编译的详细输出(mix compile的输出), 默认情况 Edeliver 会从拉取 HEAD 指向的分支来构建发布.

集群设置

在vm.args设置节点名称和 cookie

在配置文件 prod.exs 中配置 :kernel 模块的 :sync_nodes_mandator 和 :sync_nodes_optional 选项

use Mix.Config

config :kernel, distributed: [{:opencv_thumbnail_server, 5000, [

:"node1@192.168.212.45",

:"node2@192.168.212.45",

:"node3@192.168.212.45",

:"node4@192.168.212.45",

:"node5@192.168.212.45"

]}]

config :kernel, inet_dist_listen_min: 9100

config :kernel, inet_dist_listen_max: 9105

config :kernel, sync_nodes_mandatory: [

:"node2@192.168.212.45",

:"node3@192.168.212.45"

]

config :kernel, sync_nodes_optional: [

:"node4@192.168.212.45",

:"node5@192.168.212.45"

]

config :kernel, sync_nodes_timeout: 10000

上传到服务器的压缩包解压后, 需要修改,下面两个文件的节点名字和 distributed 配置.

./releases/0.0.1/sys.config

./releases/0.0.1/vm.args

其他管理命令

# 显示发布版本清单

$ mix edeliver show releases

# 停止线上的服务器

$ mix edeliver stop production

# 显示线上服务器当前运行的版本

$ mix edeliver version production

# 重启线上服务器

$ mix edeliver restart production

# 启动

$ mix edeliver start production

总结

大体上一个全新的部署过程就是三个命令

mix edeliver build release --V # 构建发布包

mix edeliver deploy release to production --V # 部署(上传, 解压)到产品服务器

mix edeliver start production --V # 启动产品服务器

如果上线前还需要部署到 staging 服务器进行测试, 或者灰度发布

热升级的过程为

mix edeliver build upgrade --with=0.1.3 --to=0.1.14 -V # 构建一个从0.1.13到0.1.14的升级包

mix edeliver deploy upgrade to production --version=0.1.14 -V # 部署升级包0.1.14到线上

关于Git仓库的问题

我们一般在 develop 分支下进行开发, 而 edeliver 构建发布包的时候是去 master 分支拉取源码进行构建的, 因此我们在开发过程中需要注意版本和分支的管理.

这里我使用了 gitflow 这个工具来管理项目的版本和发布. 假设我们现在需要向线上发布一个新版本, develop 分支需要合并到master, 先修改 mix.exs 提升一下版本, 并提交, 然后:

git add .

git commit -m 'bump version to 0.1.14'

git push

发布

git flow release start 0.1.14

git flow release publish 0.1.14 # Push发布分支0.1.14到远程仓库,以便在构建主机上编译,打包和部署

git flow release finish 0.1.14

git push

git push --tags

git checkout develop # 回到 develop 继续开发

参考资料

linux deliver分发管理,Erlang/Elixir: 使用 Edeliver 进行自动化的持续部署相关推荐

  1. 转:浅谈Linux的内存管理机制

    一 物理内存和虚拟内存          我们知道,直接从物理内存读写数据要比从硬盘读写数据要快的多,因此,我们希望所有数据的读取和写入都在内存完成,而内存是有限的,这样就引出了物理内存与虚拟内存的概 ...

  2. 浅谈Linux的内存管理机制

    一 物理内存和虚拟内存          我们知道,直接从物理内存读写数据要比从硬盘读写数据要快的多,因此,我们希望所有数据的读取和写入都在内存完成,而内存是有限的,这样就引出了物理内存与虚拟内存的概 ...

  3. (转)SSH批量分发管理非交互式expect

    目录 1 SSH批量分发管理 1.1 测试环境 1.2 批量管理步骤 1.3 批量分发管理实例 1.3.1 利用sudo提权来实现没有权限的用户拷贝 1.3.2 利用sudo提权开发管理脚本 1.3. ...

  4. Linux的RPM管理

    目录 rpm包的介绍 rpm包的简单查询指令 rpm包的卸载指令 rpm包的安装指令 rpm包的介绍 一种用于互联网下载包的打包及安装工具,它包含在某些Linux分发版中.它生成具有.RPM扩展名的文 ...

  5. Linux glibc内存管理:用户态内存分配器——ptmalloc实现原理

    文章目录 ptmalloc 设计假设 Arena Chunk Bins 内存分配.释放流程 总结 C++ STL : SGI-STL空间配置器源码剖析 Linux 内存管理 | 物理内存管理:物理内存 ...

  6. Linux集群管理软件clustershell

    Linux集群管理软件clustershell 1.简介 机房有大概百台的服务器需要管理,加上需要搭建Hadoop以及Spark集群等,因此,一个轻量级的集群管理软件就显得非常有必要了.经过一段时间的 ...

  7. KY-RTI分布仿真技术:附录1 分组聊天(HLA数据分发管理的应用)

    本章从RTI开发者的角度简单地介绍HLA1.3标准中的数据分发管理(DDM,Data Distributed Management)并给出了一个具体的示例.前面介绍了基于各种程序设计语言开发的聊天程序 ...

  8. Linux使用和管理——从零到系统管理员

    Linux使用和管理--从零到系统管理员 关于本课程 本Linux培训课程" 使用和管理Linux – SysAdmin为零 " 共分三册.这三个卷中的每一个都是紧密相连的,它们相 ...

  9. Linux笔记 软件管理

    一.软件包分类 1.软件包分类:源码包.二进制包 源码包:源代码 1)优点:开源,有能力可修改源代码 可以自由选择所需的功能 软件是编译安装,更适合Linux系统,更稳定效率更高 卸载方便. 2)缺点 ...

最新文章

  1. 12.HTML编辑器(CKEditor、CKFinder集成)
  2. Android MarsDaemon实现进程及Service常驻
  3. 5 Best User Interface Design Pattern Libraries
  4. flask 检测post是否为空_用Flask和Vue制作一个单页应用(五)
  5. 禁止用户对系统数据库表的SELECT权限
  6. java中的堆、栈、方法区等比较
  7. {}企业如何才能实现多方位网络营销
  8. 普及几个小常识,新手技能补充
  9. C# 11 预览,又增加了实用的语法糖
  10. Redis(三):Redis基础知识与常用命令
  11. linux 基本配置tab键和显示行号 和中文输入法
  12. Cocos2D-X笔记(1)制作一个动态的精灵
  13. 压力大对身体有没有伤害,你觉的有伤害就有伤害,你觉的没伤害就没伤害
  14. 用扫码枪收款钱到哪里_微信官方收款音箱,智能语音播报器,不受来电和信息干扰,老板不在也能正常播报,0费率无需蓝牙,面送赠送流量,真正的摆摊神器...
  15. Student的增删改查
  16. 根据运单号查询快递物流详情
  17. Android开发-AMD平台如何使用Android studio自带模拟器
  18. 给定平面上任意三个点的坐标(x​1​​,y​1​​)、(x​2​​,y​2​​)、(x​3​​,y​3​​),检验它们能否构成三角形
  19. 计算机毕业设计Java宠物互助领售平台(源码+系统+mysql数据库+lw文档)
  20. Access数据库文件HeroDB.MDB用什么工具可以打开呢?

热门文章

  1. PHP vs Node.js vs Nginx-Lua(转)
  2. 巧用css实现强制不换行、自动换行、强制换行(转)
  3. C# xml文件的创建,修改和添加节点 。
  4. 图像处理 花屏_滴滴开源的 AoE:工程实践中的图像处理
  5. python 字符串替换_Python基础教程,第四讲,字符串详解
  6. stc单片机入门c语言,谈谈单片机入门
  7. java商品新增怎麽弄_添加新商品时如何初始化计数器 - java
  8. java多线程详细讲解_Java多线程例子讲解
  9. 创造思维方法训练_数学思维方法训练课程:每日一题11.24
  10. QtCreator中的Sysroot的含义及坑