ruby 实现windows service启动和关闭 nginx和jruby trinidad
问题:单位只给windows server,部署环境被迫使用 jruby trinidad + nginx + mongodb,每次启动app需要开4个窗口(2个jruby)。共用的服务器经常被人关窗口,服务器重启后需手动启动。
解决办法:写windows 服务。
1. 使用win32-service gem。
需要本地编译。
gem install win32-service。
文档见http://win32utils.rubyforge.org/
2.编写服务
服务分为两个部分,一是service 安装和卸载的部分。另一部分为服务内容部分。
可参照
http://stackoverflow.com/questions/163497/running-a-ruby-program-as-a-windows-service
简化版的service 安装部分如下:
require "win32/service" include Win32 class String; def to_dos() self.tr('/','\\') end end class String; def from_dos() self.tr('\\','/') end end #override to support utf8 class String; def strip() self end end rubyexe="C:/bin/ruby.exe".to_dos SERVICE_FILE= (File.expand_path(File.dirname(File.dirname(__FILE__)))+ '/service.rb').to_dos SERVICE_NAME="Test Service" if ARGV[0] case ARGV[0] when "install" Service.new( :service_name => SERVICE_NAME, :service_type => Service::WIN32_OWN_PROCESS, :start_type => Service::AUTO_START, :error_control => Service::ERROR_NORMAL, :binary_path_name => "#{rubyexe} #{SERVICE_FILE}", :description => 'Run nginx, jruby all in one' ) when "uninstall" Service.delete(SERVICE_NAME) end end
注意:为何重载String.strip
原因在于中文版windows在安装服务过程中调用get_last_error会返回utf-8的字符,此时win32-service gem的error.rb会报invalidate byte sequence的错误。
原因是对字符串进行了strip
如果不进行strip则没有任何问题。
服务部分的代码如下:
#service.rb require 'win32/daemon' include Win32 SERVICE_LOG = File.expand_path(File.dirname(File.dirname(__FILE__)))+ '/services.log' JR_PATH = 'c:\jruby-1.7.0\bin' JR_LOG = File.expand_path(File.dirname(File.dirname(__FILE__)))+ '/jruby.log' class Daemon def service_main while running? if @pid.nil? @pid = Process.spawn('c:\nginx-1.2.1\nginx.exe', chdir: 'c:\nginx-1.2.1', out: SERVICE_LOG, err: :out) Process.detach @pid if @pid_jruby.nil? @pid_jruby = [] start_jruby end Process.waitpid(@pid) else sleep(3) end end end def service_stop if @pid pid_kill = Process.spawn('c:\nginx-1.2.1\nginx.exe -s stop', chdir: 'c:\nginx-1.2.1', out: SERVICE_LOG, err: :out) Process.waitpid(pid_kill) end if @pid_jruby.size > 0 @pid_jruby.each do |pid| pid_kill = Process.kill(9, pid) end end end def start_jruby if @pid_jruby.empty? [3000, 4000].each do |port| cmd = "#{JR_PATH}\\jruby.exe -S trinidad -e production -p #{port}" pid = Process.spawn(cmd, chdir: 'C:\app\', out:JR_LOG, err: :out) @pid_jruby << pid Process.detach pid end end end end Daemon.mainloop
结果:
以上代码在ruby 1.9.3 win7 上通过
如在win7上报安装权限不足,请使用administrator 启动cmd console。
代码尚有refactory的空间,时间仓促,敬请谅解。
相关推荐
nginxs 2020-11-14
Guanjs0 2020-11-13
小木兮子 2020-11-11
yserver 2020-11-11
ssihc0 2020-11-11
windle 2020-11-10
HanksWang 2020-11-10
liuchen0 2020-11-10
Freshairx 2020-11-10
ccschan 2020-11-10
liwf 2020-11-10
Guanjs0 2020-11-09
AderStep 2020-11-09
zrtlin 2020-11-09
mqfcu 2020-11-10
windle 2020-10-29