关于Revel
Revel是一个高生产力的Go语言Web框架,原型是由Java的Play! Framework演变而来。其实除了Revel之外,Go语言的Web框架已经有很多了,这里就不再一一列举。就Revel框架本身而言,已经具备和提供了一些非常不错的特性,比如支持运行时的代码热编译(Hot Code Reload),提供诸多的组件,包括:路由, 参数解析, 验证, session/flash, 模板, 缓存, 计划任务, 测试, 国际化等功能。
虽然目前Revel正式release的版本还只是v0.12.0版本(2015-03-25 – Daffodil release),不过此框架已经有被应用到生产环境中的实际案例,并且并发性能良好。因此,Revel也成为我们最近一个项目的首选框架。
Revel应用的部署
介绍完了Revel框架,进入正题,分享一下Revel应用部署到生产环境的几种方式。
由于Go的静态特性,所有的程序是需要先编译才能运行的。这也意味着,编译好的应用,直接成为可执行文件,在运行的时候,不依赖于任何运行时。因此,Revel应用的部署也大致分为两种方式:
在本地编译发布
在服务端编译运行
两种方式各有优点,部署的方式也稍有区别,可以根据实际的需求进行选择。
在客户端编译发布
采用这种方式,直接在客户端编译代码得到可执行程序,然后将Revel应用上传部署到服务端。Revel框架本身也提供了一个命令,用以直接在客户端本地编译出最终需要发布的应用和相关的web资源文件,供部署。
例如,使用命令revel build,将编译好的应用输出到当前deploy目录:
revel build import/path/to/app ./deploy
接下来需要做的,是将deploy目录发布到服务器,你可以用scp命令,也可以用rsync。
除此之外,Revel还提供了一个更为方便的命令:
revel package import/path/to/app
运行后,revel会编译你的应用,并直接打包为app.tar.gz,将其上传到服务端解压并部署即可。
使用本地编译方式的好处,是服务端不需要安装和配置Go环境,也不需要安装Revel框架,服务端上运行的是编译好的应用,不用部署源代码到服务端。
在客户端编译发布,需要注意的是交叉编译的问题。如果客户端的操作系统以及CPU架构跟服务端不一致,需要在编译发布的时候提供目标机器的环境变量设置。
例如客户端机器是windows,CPU是32位,而服务端机器是linux系统,CPU是64位,则需要在编译打包的时候,提供如下环境变量:
GOOS=linux GOARCH=amd64 revel package import/path/to/app
在服务端编译运行
采用这种部署方式,可以避免交叉编译的不便,不过需要在服务端安装Go环境和Revel框架。通过使用Git,客户端提交的代码可以直接在服务端通过git pull获取所有改动,然后直接在服务端编译和运行。
由于git本身是增量获取代码改动,所以相比客户端编译后上传应用能节约不少时间。
与Upstart的结合
部署运行后,在生产环境还需要对应用本身运行状态进行监控。这类相关的工具有很多,比如Supervisor或者forever。但是这两个工具在服务器意外重启后,没法自动启动,也就没法继续守护我们的进程了。所以还得搞定如何在机器重启后自动启动Supervisor或者forever的问题。
相比之下,Upstart是个很不错的选择。Upstart 是一个基于事件的守护进程,用来替代 /sbin/init ,它既能在系统启动/关机时启动/关闭任务和服务进程,也能在系统运行阶段监控这些任务和服务进程。简直就是居家旅行必备之工具……
使用Upstart为我们的应用创建配置文件,保存到/etc/init/my-revel.conf。配置文件内容如下:
description "My Revel Website"
start on (local-filesystems and net-device-up IFACE!=lo)
kill signal TERM
kill timeout 60
respawn #自动重启
respawn limit 10 5 #尝试10次,间隔5秒
setgid deployuser
setuid deployuser
script
/var/www/current/run.sh
end script
配置中的start on参数,指定了Upstart会在机器启动完毕,并且网络连接正常之后运行我们的程序。respawn参数则表示自动重启进程,并在5秒内尝试10次。把配置文件中的script部分,指向编译后revel应用中的run.sh即可。
最后,通过命令启动守护进程:
sudo start my-revel
这样,Revel已经成为后台进程运行了,并且会在机器意外重启后自动启动,程序异常退出后,也会被自动启动。可以直接用kill命令杀掉进程,发现新的Revel进程会立马被创建和运行。