之前由于CodeJam要做搜索引擎相关的功能,而我经过了多个市面上比较流行的搜索引擎的对比之后,最终选择了Solr,主要是Solr在各方面都比较切合需求,DSL的查询语言也足够Easy和Reasonable。唯一的缺陷就是Solr是Java程序,具有很强的Java风格,这种风格对我这样一个Ruby程序员来说非常不适应。这种风格总的来说就是,完全XML配置,必须放在Tomcat或是Jetty中才能使用。

开始的Index配置的还是很成功,参考资料主要是:http://www.gm100861.com/519.html,这是我Google到目前为止我认为最靠谱的一篇文章了。

但是由于我们的搜索需要两个索引,而Solr不像Sphinx或是ElasticSearch天然支持多索引的特性,不过关于Solr的多索引配置的文档依然相当多,手段主要是Multi-indexes, Multi-cores和Multi-collections。我一开始选中了Multi-indexes,按照网上的一些文章一步一步做,试遍了各种方法,但最后全部都失败了。失败原因主要是不了解Tomcat的运行机制,而我出现的错误又很尴尬,访问localhost:8080/solr1出现404错误,没有任何错误消息,完全不知道该怎么办才好了,而且日志既不出现在/var/log里,也没有标准输出,Tomcat自身的错误日志又很多,找了半天,不知道哪个是哪个(后来才知道Tomcat和Ruby程序习惯不一样的地方就是,Tomcat在启动是加载webapp的时候就已经发生错误了,而Ruby程序都是访问时才检测错误,所以我每次在出现404的时候去找错误信息,显然什么都没找到)。再加上Tomcat是Java写的,没有办法通过调试源码来发现错误。后来又尝试了Multi-cores,也是完全不成功。

于是求助于Ruby China@yesmeck给了我一个gist,里面提及了一种简单的依靠调用REST API创建Collection的方法,这种方法真的简单,而且一弄就成功了!然后可以通过localhost:8080/solr/collection{n}/的REST API来指定相应的Collection。但是很奇怪的是,只要我一重启Tomcat,那些自己创建的Collection都会自动丢失,必须重新创建,很无语。网上我也没有找到好的解决方案。虽然如此,我还是用了很久,从CodeJam开始到今天第一次Demo,我还写了个脚本,在每次重启Tomcat后执行用来创建Collection并进行data import,还是蛮方便的。

今天搞完第一次Demo后,我终于稍微松口气,可以再试一次Multi-indexes的配置了,由于做了一个多礼拜的Solr,我对Tomcat和Solr的理解已经开始清晰了。所以第二次做的时候,我不再想之前一样在网上跟各种步骤,而是只看http://www.gm100861.com/519.html这篇我最相信的文章,以及这篇官方文档

在基本做完了所需步骤后,其中Tomcat,随即查看tomcat/logs/catalina.out,经过一个多礼拜的使用,我已经确信这个日志文件综合了Tomcat的各种日志输出。从日志中我很快发现了错误:

java.lang.IllegalArgumentException: Document base /usr/local/apache-tomcat-7.0.42/webapps/solr1 does not exist or is not a readable directory

我按照官方文档在tomcat/conf/Catalina/localhost下创建了solr1.xml和solr2.xml,然后就出现了这个错误。我猜测在Tomcat中创建什么名字的配置文件就代表什么名字的webapp,就像Rails的Convention一样,而不管这个文件里面如何指定了war文件的路径,这点我在之前任何一个Google的搜索结果中都没有看到。随后我在webapps下将solr更名为solr1,并创建了符号链接solr2。为了防止放在目录下的solr.war重新创建solr目录,我把solr.war也改名为solr1.war,同时也创建了符号链接solr2.war。这步完成后,错误信息改为

SEVERE: Error filterStart

这个错误就更人无语了,我按照网上的文章把filter去掉没有起效,把JDK1.7装上去之后还是不行,最后突然看到一个帖子说有可能是哪个必要的jar包找不到,于是立刻想起http://www.gm100861.com/519.html中的最后部分提及了要拷贝一些jar包到指定目录的,而我之前没做这步,完成后重启,访问localhost:8080/solr1和localhost:8080/solr2就都成功了,而且也不会再出现重启后消失的诡异情况。

由于我所维护的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个小时,差不多足够了吧。

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

刚刚电子邮件收到的,共享下,方便大家下载。粗看了下,感觉这个版本主要就是在强化InnoDB。

点击下载

介绍

MySQL是当今在用的最值得信赖的开源数据库平台。基于其卓越的跨平台、应用程序栈以及瞩目 的性能、可靠性和易用性,现今,许多比较流行的,访问流量大的网站都选择使用MySQL数据库。现在MySQL Oracle提供了一个完整的LAMP(Linux、Apache、MySQL、PHP、Perl、Python 等)框架,基于LAMP,任何规模和志向的用户或客户均可利用现有的最佳技术解决方案和支持构建自己的应用程序和产品。MySQL 5.5 提供了一组专用功能集,在当今现代化、多功能处理硬件和软件以及中间件构架涌现的环境中,极大地提高了MySQL的性能、可扩展性、可用性。

MySQL 5.5融合了MySQL数据库和InnoDB存储引擎的优点,能够提供高性能的数据管理解决方案,包括:

  • InnoDB作为默认的数据库存储引擎
  • 提升了Windows系统下的系统性能和可扩展性
  • 改善性能和可扩展性,全面利用各平台现代多核构架的计算能力
  • 提高实用性
  • 提高易管理性和效率
  • 提高可用性
  • 改善检测与诊断性能

本白皮书介绍性的讲解了MySQL 5.5和InnoDB的一些增强性能,这些增强性能极大地提高了系统和MySQL的性能。下面,我们将详细介绍每一个关键的增强性能及其实现过程。