部署 使用 Mina 部署时的错误 (SOS!!)

linjunzhugg · 2014年11月23日 · 最后由 wangxing0122 回复于 2016年01月28日 · 3565 次阅读

用 mina 部署单台服务器没问题。

但最近做分布式,因此需要跑一下 mina deploy 同时部署几台服务器,找了下没有相关的资料,求各位指点指点

首先感谢各位的耐心解答,不过搞了许多时间,表示疑惑越来越大。其中,

set :domains, %w[192.168.0.12 192.168.0.13]

domains.each do |domain|
      p "begin to deploy server #{domain}"
      set :domain, domain
      invoke :deploy
      run!
      p "finish to deploy server #{domain}"  
end

这种情况会造成:第一次循环正常,第二次循环 deploy 了两次

提示信息:

begin to deploy server 192.168.0.12

   deploying.....

finish to deploy server 192.168.0.12

begin to deploy server 192.168.0.13

   deploying.....

finish to deploy server 192.168.0.13

   deploying......  ( server 192.168.0.13 )

可能的原因:该代码块循环后的代码会是:

p "begin to deploy server '192.168.0.12'"
 set :domain, '192.168.0.12'
 invoke :deploy       #   =》 第一次 queue
 run!      # 此时commands == [ 'invoke :deploy']   ( 当然这里应该是具体的命令,我笼统点写 )
 p "finish to deploy server 192.168.0.12"  

 p "begin to deploy server 192.168.0.13"
 set :domain, 192.168.0.13
 invoke :deploy   #  => 第二次 queue
 run!     # 此时commands == [ 'invoke :deploy',  'invoke :deploy']  
 p "finish to deploy server 192.168.0.13"

所以第二次循环时,才会执行两次的 invoke: deploy。但是我直接输出 commands,发觉第二段确实是只有 一个 [' invoke :deploy'] 而已!并且 invoke 的 task,默认是只会被引用一次。 ###那为何这里重复运行了两次呢?

网上的解决方案是:

isolate do
    domains.each do |domain|
        p "begin to deploy server #{domain}"
        set :domain, domain
        invoke :deploy
        run!
        p "finish to deploy server #{domain}"  
    end
end

这样就正常了,而 isolate 的意思是: Starts a new block where new commands are collected. 开辟一个新的 block 来新建集合 commands。

example:

queue "sudo restart"
queue "true"
commands.should == ['sudo restart', 'true']
isolate do
  queue "reload"
  commands.should == ['reload']
end
commands.should == ['sudo restart', 'true']

###但是这样子做,循环后的所有代码不都是在同一个 block 下么?( 怎么还会起做作用??)为何不是这么做?

domains.each do |domain|
    isolate do
        p "begin to deploy server #{domain}"
        set :domain, domain
        invoke :deploy
        run!
        p "finish to deploy server #{domain}"  
    end
end

不过这样子做的话,第一次正常,第二次没有执行 invoke :deploy。

更新

做了很多次试验,发现最终总是会多部署最后一个 server。看来这是跟invoke :deploy这个特殊 task 有关了。

说下我的看法.. 可以在 deploy.rb 里这么写set :domain, ENV['SERVER'] 然后在目录下写一个部署脚本

mina deploy SERVER='xxx.com'
mina deploy SERVER='yyy.com'

并把脚本加到.gitignore 里去 要嫌麻烦也可以在.bashrc/.zshrc 里写

function xxx_deploy { cd xxx && mina deploy SERVER='xxx.com' && mina deploy SERVER='yyy.com' }

#1 楼 @xyuwang 再写个 task 在里面就可以多次 invoke deploy,不用运行 min deploy 多次

#2 楼 @gihnius 恩 了解了 谢谢~

#2 楼 @gihnius 能麻烦您给段 code 看下嘛?谢谢了 😄

5 楼 已删除

#3 楼 @xyuwang 感谢!不过二楼的做法能否麻烦您提供下 code 看看呢?

#6 楼 @linjunzhugg 类似这样,不过我还没试过,


set :servers, ['svr1', 'svr2', 'svr3']

task :deploy_all do
  servers.each do |s|
    set :domain, s
    invoke 'deploy'
    ...
  end
end 

#6 楼 @linjunzhugg 如果不行,这样应该可以的:

task :to_svr1 do
  set :domain, "svr1"
end

task :to_svr2 do
  set :domain, "svr2"
end

# 不过也要分开调用:

$ mina to_svr1 deploy
$ mina to_svr2 deploy

#8 楼 @gihnius 好,谢谢,我试试。

#7 楼 @gihnius 这种是不行的,最终起效的是最后的 server,也就是 svr2

#8 楼 @gihnius 如果是分开调用的话,那得写个脚本,最终则是直接调用脚本而不是 mina deploy 了,不知道有没更好的方法?:)

个人看法:用 Capistrano

Mina 本身就是个简单的自动化部署脚本生成器,目的是让重复的部署过程变得简单快速,它设计之初就不是为了管理复杂的部署环境的,比如多服务器批量部署。Mina 官方很早就有人提 issue 加入多服务器部署的要求,不过我记得貌似作者响应不是很积极…… 它本来就不是为了这种要求而设计的。

所以本着合适的工具做合适的事情的原则,如果要题主现在(或者以后)有复杂的部署要求,建议用 Capistrano,毕竟别人一开始的定位就是多服务器部署,并且已经做了很多年,论稳定性和需求考虑的全面性不是自己 hack 的方案可比的。

#7 楼 @gihnius 这种方法其实是可以的,不过要在 invoke 后面加上 run! .

最新看了下 mina 感觉配置简单清晰点 Capistrano 官方文档我看的有点蛋疼 哈哈

HELP!!!!!

19 楼 已删除

你这样循环不如手动部署两次。如果真的需要两个同时部署,多开几个窗口来运行。

你好,我想请教一下你的 yml 文件是怎么写的,我的 deploy..rb Mina::Error: Setting :repository is not set 这个是错误的

需要 登录 后方可回复, 如果你还没有账号请 注册新账号