TekPub是一个面向开发人员的站点,致力于为开发人员提供一系列主题的在线培训,主题范围非常广泛,从微软的O/R Mapping框架Microsoft Entity Framework,到如何使用Ruby on Rails技术编写自己的日志引擎等内容都有涉及。该网站是由前微软员工Rob Conery与Lounge的老板James Avery创立的。
TekPub是个很有趣的学习案例,公司开始时使用ASP.NET MVC框架,之后很快迁移到了Ruby on Rails上。InfoQ与Rob和James探讨了这次迁移之旅。
InfoQ:和我们谈谈TekPub吧,对于哪些不熟悉你们的产品的读者,TekPub意味着什么?
James Avery(简称JA):TekPub为程序员提供了高质量的技术视频演示。我们的目标是帮助一些人在几个小时内学习一项新技术,主要方式就是观看一些牛人的演讲视频。他们对演讲的技术非常了解,演讲内容不仅仅覆盖基础知识,还深入到了这些具体技术在真实项目中的应用。与其等几个月才拿到一本很可能已经过时的书,还不如订阅我们的产品立刻获得新技术的提升。我们已经完成ASP.NET MVC 2的系列视频,但目前还没有与这个主题相关的书籍。
InfoQ: James Avery和Rob Conery有什么来头?
JA:除了TekPub之外,我还搞了几个科技创业公司。我运营了Lounge和Ruby Row广告网络,分别关注.NET和Ruby开发人员。我还帮助运营DotNetKicks公司,一个.NET开发人员的社区网站。我最新的关注点是Adzerk,这是我自己构建的Web服务器,用来有效的运行Lounge和Ruby Row,让其他人来使用。从90年代中期我就开始使用Web,.NET发布后,我开始转移到微软的技术上。最近我一直再用.NET、Ruby on Rails和MongoDB等,还有任何让我感兴趣的技术。
Rob Conery(简称RC):我自1991年以来一直从事软件行业,做一些数据库,CGI和HTML之类的开发。从1997年开始使用ASP,从那之后一直坚持使用微软技术。2006年我开始为微软工作,主要职责是帮助人们学习和使用新的ASP.NET MVC框架。2009年我离开了微软开始做些不同的事情(更多的关注开源平台),之后和James Avery一起创办了Tekpub。
InfoQ:能介绍一下你们刚创业时TekPub的架构吗?
JA:TekPub的第一个版本是基于Ruby on Rails构建的,当时Rob花费了整整一个周末的时间。之后我们仔细的进行了讨论,最终决定放弃这个版本。由于我们都很了解ASP.NET MVC技术,所以决定用ASP.NET MVC来实现TekPub。我相信,当开始一项新业务时是没有时间尝试和学习新技术的。Rob和我过去都写过Rails应用,但真正使用时,我们都觉得ASP.NET MVC比Rails好得多。于是我们放弃了Rails转而使用ASP.NET MVC技术开发网站。后来我们取消该站点并重新构建它,因为它已经变得太复杂。在我们开始进行技术迁移时,TekPub的版本是3,主要技术是ASP.NET MVC,C#和MS SQL Server。
InfoQ:从网站使用者的角度你遇到了什么样的挑战?从网站管理者的角度呢?
RC:最初,或者说网站运营的第一天,我们就遇到了网络带宽的问题。我们在Twitter上宣布网站开张,这直接导致我们的ISP由于带宽的需求被淘汰。他们毫不夸张的让工程师“坐在开关上”来保证网站的正常运行,但最终网站还是停了。之后两小时内我把我们所有免费的内容都放到了亚马逊的S3上,这对我们帮助非常大。
还有,一小部分人不喜欢Silverlight,不愿意安装它。我们在Reddit上投放了广告,人们却简单的认为我们的网站是微软资助的一个什么东西——这是和我们的目标背离的。对我们来说这是个大问题。
JA:ASP.NET MVC运行的很好,Windows架构也不错。事实上我们在这个领域没碰到什么麻烦。主要的挑战来自于我们决定使用Silverlight播放流媒体。很多用户不愿意安装Silverlight,这给我们带来很大的困扰。与Rob确认后,我们不得不迁移到Flash技术。迁移到Flash之后还没有一个人抱怨过。我们希望HTML5很快面世。
InfoQ:架构如何应对用户需求?
RC:我们从来没有遇到底层框架的问题——它处理的很好。这并不是一个负载非常大的网站(在功能方面),所以我们从没真正遇到那方面的问题
InfoQ:既然平台运行的非常好,为什么要做架构的改变呢?
RC:成本。我们加入了微软的BizSpark计划,而且它的确给了我们一个很棒的起点,但是随着项目的发展,我们发现,3年以后,从我们使用的数据库到开发环境,每一件事情都需要付费。而且我们很可能需要为Silverlight(使用流媒体)提供一个分离的服务器,用来播放视频,这样就需要再支付一个使用许可的费用——此外,为了使视频流平滑输出,我们还需要买媒体编码器。
对于大公司来说,这的确不算什么,但当我们坐下来看帐单时——噢,这可是个5位数啊。最终我们发现,根据我们现有的业务规模,是无法承担这笔费用的。
不仅仅如此,James和我都清楚Rails非常好用。我们意识到可以把所有事情都推到云端,只需支付很低的价格就可以获得很好的流媒体和吞吐量。
JA:正如Rob提到的,成本压力是其中一个因素,BizSpark是很好,但却像一个定时炸弹。我觉得比成本更重要的推动因素是每天我们希望使用什么技术。ASP.NET MVC和.NET技术在某些领域是有缺陷的,而这些领域的工作对我们非常重要。在.NET上做测试就并不让人满意,你不得不大费周章才能以正确的方式设计你的应用,处理测试,而且编写测试本身也不像其他语言那么清晰和有用。另一个问题是部署,虽然有很多种方式可以处理,但确实不如Capistrano好用。
InfoQ:那么现在TekPub平台是什么样子的?
RC:我们迁移到Rails 2.3.5,使用了针对MongoDB的MongoMapper技术。我们做了一个报告设置,用MySQL来跟踪反馈使用DataMapper的情况。我们还植入了New Relic RPM,来跟踪我们的站点和健康情况——所有的这些,平均成本仅仅是我们使用BizSpark的1%。
JA:这解决了我们所有与使用许可有关的问题,我们每月需要为Amazon EC2平台上的一个Ubuntu实例支付$80,这是保留实例后的费用。Rob和我都很喜欢这种技术,我们使用Cucumber做了大量测试,用Capistrano部署变得非常简单容易。
InfoQ: 能给我们讲讲你们的技术架构细节吗?
RC:使用Rails 2.3.5及其对应的MongoMapper/MongoDB,使用MySQL 5.2和O/R Mapping工具DataMapper。我们还用了New Relic RPM工具,非常棒。
JA:我们选择使用Rails 2.3.5和Ruby 1.8.7,通过Passenger运行Rails应用。在数据库方面,我们通过使用优秀的MongoMapper gem访问MongoDB 1.3.4。我们还通过DataMapper实现MySQL 5.1的数据访问。我们并不使用很多其他的Gem,只是用Pony发邮件,rpx_now访问RPX做身份验证。同时我俩还都是HAML的爱好者,所有的界面都是基于HAML实现的。
InfoQ:你们的EC2怎么配置的?
JA:所有的内容都是托管在云端,相当于一个比较小的服务器,也就是一个单独的EC2实例(虚拟双核,2个计算单元,7G内存)。在这个实例上运行着Ubuntu 9.1(karmic)和Apache。我希望未来有更多的资源,你知道,运行在EC2上,想增加资源是非常容易的。
InfoQ:为什么选择Ruby on Rails?
RC:James和我都知道,插件的世界是非常吸引人的。例如New Relic,简直是上帝送来的礼物。我不担心服务器挂掉,而且我能看到所有代码的“瓶颈点”。他们还能跟踪最高发生频率的问题,甚至会提出改进意见。
MongoMapper是一个令人难以置信的数据工具,而MongoDB本身的速度比闪电还快。Rails的平台已经成熟到了这样的地步,几乎难以说服自己*不*使用它。
JA:我们遇到的所有问题(使用许可、测试和部署)都得到了很好的解决。我们还能使用一些变通的办法,例如写自己的部署框架等。随之而来的是我们都很享受与Rails工作,我们喜欢Rails社区,还有很多工具和类库可用。经过迁移之后最棒的地方就是,这一切让我们变的非常高兴。
InfoQ:相对很多传统数据库例如MySQL或者PostgreSQL,你们为什么选择MongoDB?
RC:速度和扩展性。使用MongoDB非常简单——不用担心迁移,非常灵活。而且它不可思议的快——这一点对用户带来的感受是巨大的。
JA:事实上我们都用了,我们用MongoDB做那些它最擅长的(灵活存储产品、用户和订单等信息),同样我们也这么使用MySQL,我们用MySQL提供正在发生的持久事务日志。
InfoQ:完成了新的设计和重写应用之后,最直接的好处是什么?
RC: 最直接的——第一件事就是人们发现网站变快了。他们还注意到一个“更严格”的设计,诚实的说,确实有些繁琐,但它让我们能更多的关注服务器端。
不仅仅如此——当出现问题时,我们可以在几秒钟之内消除它。这是由于基于Capistrano的部署是如此简单。问题的修复、推出——仅需几秒。
我们的测试套件使用的非常好——使用Cucumber做一些事情简直是一种享受,但用ASP.NET MVC就会很困难。例如——使用ASP测试PayPal的支付接口时就会很麻烦。
基于Rails/Cucumber/Webrat,在这样的框架下要做的就是填空并提交——然后确认所有事情都是按照计划执行的。我想我们的用户会看到很多功能在按照预期的方式运行——这确实很棒。
最直接的好处是我们想做一些变化时,可以快速完成,并且这种响应速度直接反应到了产品上。在原来基于ASP.NET MVC技术的网站上,我经常会写些SQL脚本来处理一些复杂的支持需求,比如改变某人的OpenID,或合并帐户什么的。但现在我只需花30-60分钟的时间写了几行的Ruby脚本就能完成。
在重写网站过程中另一个重大的改变之一是如何处理用户的文件。过去我们从自己的服务器或运行在EC2上的Wowza媒体服务器上以流的方式处理文件。这两种方案都可以,但是太贵了,而且在其他国家就运行的没那么好了。这次我们开始重新设计亚马逊服务,提供了从云端和云端流来处理私有内容的能力。现在我们的全部内容都是通过云端处理,并使用了安全签名的URL,这就意味着世界上任何地方的用户都可以进行高速下载。这也节省了我们的成本,因为我们只需支付使用带宽的费用,不需要额外的设备或许可费用。
InfoQ: 在你们当前的实现中,TDD测试方法包含哪些内容,引入模拟对象了吗?
JA:我们用Cucumber和Pickle实现测试驱动开发。这方面Rob应该比我更清楚。
RC:没有进行模拟测试,都是BDD(行为驱动开发)。我痛恨那种拖拉的感觉,就像我需要做“代码覆盖率”一样——事实上我们有个商业应用在运行,我更需要确认用户获得良好的体验,这对我来说就是BDD。Cucumber扮演了一个真正的重要角色——就像Pickle和Factory Girl做的那样——它与MongoMapper配合的好极了,对比我在微软框架下做的和我现在能做的事情,这让我高兴的笑了好几次。我几乎完全在考虑业务——甚至没有注意到测试方法这回事。
InfoQ: 你们现在的测试方法和以前在微软使用的方法有什么不同?
RC:100%不同。测试微软的东西是极其痛苦的,当时你很穷,还有三个月钱就花完了,在这种情况下,测试就是变成了一个很难判断的的东西。不可否认——我为我们的第一次修改几乎写了一吨的垃圾。如果你没有客户,那么你的应用系统好不好用就无关紧要,我真正需要确定的是不出现那些不可预期的错误。所以我进行了一些测试,但并没有得到想要的结果。我们对PayPal的东西进行了大量地测试,这是你必须要做的。当开始使用他们的API时,我在他们的沙箱环境中折腾了整整三天,还是会不断的出问题。
另一边呢——感觉是黑夜和白天的对比。现在我们覆盖了所有的行为类型,我想James甚至抽时间写了一些。
JA:对微软产品的测试总是像打一场战争,主要是因为C#和静态语言对测试的支持不是很好。在.NET上测试时你总是需要在各种循环中跳来跳去。话虽这么说,.NET的SpecFlow框架看上去还是很乐观,但我对它能解决.NET的测试方面的所有问题持怀疑态度。
InfoQ: 在微软框架上做测试会有多少困难?为什么会这样?
RC:语言和工具造成的。假如微软对这一点想的多一些,测试可能会更容易一些。使用RSpec进行测试,没有其他语言比Ruby做得更好了——它让测试变得非常容易。微软可以利用DLR实现这些功能……但是他们没有这么做。因为这不符合“.NET Story”,那么好吧,这是他们的商业决策,我们这次的迁移也是一样。
InfoQ: 在这次全面的重新设计中,你们有什么经验教训吗?
RC:没什么——我想James和我都知道,我们到了需要调整和重写的那个点。这是我的第三次创业,对James来说应该是第五次。开始时我们经过很长的时间讨论采用什么技术。我们都同意我们要“跟随你所知道的,并且去实现它”——于是我们就做了。
我们很幸运把握住了这个机会——然后我们进入了这样一个状态:“好吧,让我们开始为之后的3-5年规划,进入可控的增长模式”——这就是我们现在的状态。我们不想做得很大,我们不想引入IT人员或一组开发人员。我们想自己做而且保持小的规模——重点放在了我们的创意上。
对于我们这样的两个家伙来说,Rails超级简单,易于维护。我们有世界上最可靠的支撑(可自动扩展的亚马逊EC2),我们对正在做的事情非常满意,获得了很多乐趣。
JA:我想大部分人看到这个故事,会认为我们应该从开始就使用Rails,事实上我很高兴我们没有那么做。开始创业时我想我们要相信自己的直觉,哪些是当时我们认为最好的,我们应该关心所有的业务问题,而不是使用什么工具。现在业务已经正常运转,在这样一个坚实的基础之上,我们就有了很多美妙的时光,释放内心的渴望做一些好玩的事情。平台移植让我们享受了很多乐趣。
InfoQ: 你们现在的架构有什么缺点吗?如果今天开始重新做一遍的话,有什么改变吗?
RC:从我的观点来看没什么——我爱现在的一切。对我来说这很不可思议——我在很长一段时间内曾是一名微软员工,并被扣上了这样一顶帽子……其实这对我们来说并不意味着什么。我非常喜欢硬件成本的可扩展性——我想在很长时间之内我们不再需要其他的硬件方案了。我们的服务器非常灵活,完全根据需求动态扩展。使用微软技术你就没法做到这些(据我所知),如果你想搞一台独立的机器,那你就需要支付一大笔款项。
JA:针对现有架构,我唯一想做的改变就是把MongoDB从我们的单一服务器上分离出来,同时运行两个MongoDB对我们来说是有意义的,但现在这部分功能被废弃了,对我们来说更有意义的事就是等MongoDB开发新的配对策略。但是考虑到额外的两个虚拟机的成本,以及我们的业务在现有的单一服务器上运行良好,我们暂时还不准备这么做。
InfoQ: 感谢Rob和James抽时间接受我们的访谈。
关于TekPub的更多信息,请参考公司网站。
查看英文原文:Architecting TekPub - Moving from ASP.NET MVC to Ruby on Rails