RubyGem Introduction
Ruby中将代码块作为参数传入方法的几种方法及其区别

本地同时运行多个Rails App时同时监听80端口的办法

bachue posted @ 2012年10月18日 00:01 in Ruby with tags ruby rails apache Git debug twitter nginx pry ruby china , 3604 阅读

由于我所维护的Rails项目规模很大,所以被分割成了多个项目,而其中仅Rails项目就有不下6个,而我在开发我所属的子项目的时候,通常至少同时运行4个项目才能把流程完整的运行起来。而这四个项目中就有三个在生产环境上会监听默认端口(80/443),因此,这些项目的开发者都希望当其他项目与自己的项目产生交互的时候,会采用默认的端口。也许他们在自己开发的时候就是这么做的并且没有发生什么问题,但是作为另一个项目的开发者,遇到这种情况就非常麻烦了。虽然我们有时都会留下一个配置文件供开发者配置,但是由于这个配置文件本身也被Git托管(这个做法其实很不正规),所以我一旦修改配置文件,这个文件就至始至终保持被修改的状态,非常麻烦,经常干扰到我原本华丽而流畅的Git操作(瀑布汗。。)。

所以就希望能寻找到一种办法,能够使服务器不再根据端口,而是根据域名判断请求应该送达的服务器。这个功能其实Apache,Nginx等网页服务器都具备,但是开发环境下的Rails服务器不比真正的网页服务器,没有这种功能。

当然,不能直接简单地用个网页服务器了事,因为传统网页服务器不能实现对Ruby代码的Debug(何况最近还特别迷恋pry神器),而这是我需要的基本功能。除此以外,我还需要它的路由层次必须高于/etc/hosts文件,因为我们还要时常切换到QA环境或是生产环境,而我们切换的方法就是修改/etc/hosts。所以在防火墙甚至于更底层实现都是我不能接受的。

于是我在Twitter和Ruby China发起了提问(http://ruby-china.org/topics/6102),收到了不少响应,比如RVM+Pow的手法,确实不曾听说过,感觉不错的样子。还有Passenger + Apache的办法,来自于Railscasts介绍的办法:http://railscasts.com/episodes/122-passenger-in-development。不过,我更希望的是一种更加简单的办法,不需要复杂的GUI控制,完全透明,而且最好是平台无关的,毕竟我比起Mac OS X还是更希望用Linux开发,因此不希望采用Mac Only的办法。

在反复思虑后,选择了@RainFlying提出的用Apache/Nginx做反向代理的办法,将发送到Apache/Nginx的请求通过代理转发到真正的Rails服务器上,以此实现了让多个Rails App时同时监听80端口的假象。

于是,我就在目前正在使用的Ubuntu 12.04上安装了nginx-light包,这个包比起nginx-full来说仅仅包含了最核心的nginx,不带过多的Modules,保持环境的轻量。然后在/etc/nginx/sites-available里创建了一个新文件,内容如下:

server {
        server_name test1.com;
        location / {
                proxy_pass http://localhost:3000/;
        }
}

server {
        server_name test2.com;
        location / {
                proxy_pass http://localhost:3001/;
        }
}

由于每个站点的配置仅有简单的几行,因此我把所有配置都包含在一个文件里,看上去简洁明了。

然后修改/etc/hosts文件,将域名指向本地服务器。这个步骤也暗示了我随时随地可以通过修改/etc/hosts切换环境,而不需要任何其他操作,完全和以前一样。

最后运行

sudo service nginx restart

重启Nginx。虽然网上有说用

sudo service nginx reload

也可以,但是我在尝试后发现似乎并没能成功更新配置信息,因此还是使用restart命令。

到这里,其实反向代理因此可以工作了,但是由于Nginx服务器毕竟不比为开发设计的Rails服务器,所有的连接都有超时时间。如果在连接时进入了Debug模式,我希望连接能够一直保持等待直到Debug结束,在查阅了Nginx的文档后,发现可以用proxy_read_timeout选项设置Nginx等待被代理服务器的响应时间,默认为60秒,我将这个时间设置到了36000秒,即10个小时,差不多足够了吧。

明天就把这个方法在团队中推广下,大家以后不用再抢端口了吧。

linjunpop 说:
2012年12月11日 13:15

https://github.com/pyromaniac/hoof

Avatar_small
bachue 说:
2012年12月13日 22:01

@linjunpop: 恩 有空玩玩

Avatar_small
bachue 说:
2012年12月13日 22:05

话说这个方法我最后没有使用,因为Rails App其实不知道浏览器连接所用的端口,request.port里依然是服务器真实的端口,这个值在我们的项目中是有用的,所以不能用这个方法。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter