作者 | Noah Gibbs
译者 | 弯月,责编 | 屠敏
头图 | CSDN 下载自东方 IC
出品 | CSDN(ID:CSDNnews)
首先,我介绍一些很明显不应该使用Rails的场合,然后再探讨一些值得从技术角度去考虑的情况。
首先,最重要的是团队熟悉程度。如果你的团队根本不了解Rails,而且对Rails的学习也不是特别感兴趣,那么就不适合选择Rails。这种情况应该很明显,但仍然应该是第一考虑要素。
其次,当你知道其他框架更合适的时候。有时候你会特别关注一些方面。如果你需要使用Java语言的机器学习库,并且由于某种原因你不想使用JRuby,那么就不应该选择Rails。如果你需要编写WordPress插件,则会选用PHP。有些特定的兼容性问题往往比其他所有问题都重要。
如果能够发挥Rails的优点,同时缺点没有太大影响,则可以选用Rails。因此,下面我们来讨论优Rails的缺点。
另外,通常Rails只能用作HTTP服务器,因此某些任务不适合Rails。
不适合使用Rails的情况包括:
非常小且不会增长的任务。 如果某个服务的功能非常有限,那么使用Rails就有点大材小用。如果你不需要数据库,那么就没有必要建立数据库,对不对?如果只是一个流量非常低、不需要缓冲的中间服务器,那么使用Rails就得不偿失。
但是,你需要谨慎处理不断增长的任务,不断扩大小型服务器的规模会带来很多麻烦。如果你的服务需要通过Web浏览器向用户提供HTTP页面,那么必须考虑将来可能需要添加的功能。仅靠最简单的解决方案远无法应对这种情况。
简单的API服务器。 Rails并不擅长提供支持JSON的API服务器。Rails的许多HTTP安全性都无用武之地(例如SQL注入防护、XSS防护等)。虽然对于某些数据库而言,ActiveRecord是不错的选择,但当你构建需要与浏览器对话的HTML网站时,Rails才能发挥最大优势。一般,在仅供机器使用的小项目中,Rails的用处不大。
与之类似,如果你需要在浏览器中渲染HTML,而Rails只负责提供JSON数据。这时,许多Rails的安全功能和便捷功能就形同摆设了,但ActiveRecord、ActiveJob、ActionMailer等内部库仍然不容小觑。但如果你不在服务器上渲染HTML,而且非常确定以后绝对不会,那么就不要纠结Rails了。
Rails是为小型团队和中等规模的代码库设计的。超大型团队(许多程序员)和超大型代码库(大量的控制器、模型、代码行数)会拖垮标准的Rails应用结构。
在Ruby中,你可以编写带有非局部副作用的代码。不论是猴子补丁,还是写入数据库,或者是在运行时创建新的类型,对于一个200人的团队来说,如果你无法信任每个人,那么就不应该选用Ruby。有时方法太多,反而会让人头疼。有一些很好的工具可以方便在大规模团队中使用Ruby,但即使如此,也很容易遇到异常和困难。这并不是Ruby擅长的领域。
大多数时候,你可以将一个大型项目分割成多个较小的项目。如果一个Rails应用过大,那么通常可以将其分割成多个应用,或者一个较薄的应用加上多个后台服务,或者一个应用加上一个微服务,等等。不论哪种方式,总有办法将其分割成小部分。Ruby非常鼓励这种做法,而我也非常赞同。
有些结构虽然不太像Rails的风格,但能很好地扩展规模。Avdi Grimm(已退休)提出的Objects on Rails就是这方面的一次尝试,还有Hexagonalarchitecture for Rails也是,它与更古老、更通用的N-tier architecture有很多共通的地方。
但有时采用其他框架更好。一个明显的选择就是Hanami,在创建微型应用程序时它不像Rails那么快捷,但在大型团队中,它的扩展性更好。
个人而言,我还是会从Rails下手。如果只想快速开发,然后看看市场反响,那么没有任何框架的生产力可以与Rails媲美。等到市场成功,而且可以适当降低开发速度时,再用更坚实的框架重写就好。
另一个需要考虑的是性能问题。如果你要重写一个普通网站,那么实际上性能并不是问题,Rails在这种规模上依然能够良好地扩展。但如果面对几百倍大的网站(如B2C网站),那么有可能你的服务器费用会超过人工费用。住这种情况下,可以考虑降低工程师的工作效率,开发效率更高的网站,以节省服务器费用。可以查看一下你的应用服务器的账单,只看看运行Rails的应用服务器就好。然后对比一下Web工程师(即负责编写Rails应用的人)的工资。一般而言,工程师的工资要远远大于服务器的费用,所以应该使用廉价的服务器时间来换取昂贵的工程时间。但在某个点上,天平会倾斜,此时就应该考虑提高工程师的工资,以此来降低服务器开销。
在讨论Rails的假设是否正确之前,我们先看看这些假设是什么。
Rails有一些简单的假设:它假设你编写的是在服务器上渲染HTML的交互应用。它假设安全性非常重要(Rails为了安全性放弃了很多),而大多数情况下你不会自己构建安全系统。它假设你有一个精英小团队来做原型的工作,或者你有一个中型团队,但有完善的指南。
Rails还假设,你愿意用技术债务来换取更快的开发速度。换句话说,Rails的目标是快速构建应用程序。当技术执行力不是首要考虑的风险时,这种做法很合理。例如:如果你有一个小型的创业公司,你很确定你能构建网站,但人们并不一定会买你的产品,那么你最大的风险就是市场风险。此时Rais应当是首选。你需要迅速构建。因为就算你能做出完美的产品,也可能因为非技术原因(如“人们不愿意买”)而放弃。
鉴于“开发速度优于技术债务”的信条,Rails假设你会使用大量的gems,而且只要能加快开发速度,添加依赖也不是问题。
Rails假设你不在乎水平扩展应用服务器(即添加更多的应用服务器)。如果你能做到这一点,它就能很好地扩展。Rails假设CPU很便宜(一般来说这是实话)。相应地,Rails还假设数据库通常是最严重的性能瓶颈(一般对于Web应用程序来说,这是实情)。
Rails还假设你的应用程序需要进行一些计算或数据传输。它假设可以使用CPU,因为无论如何你都要用CPU做一些计算。
尽管Rails擅长做很多事情,但有一件事是它不擅长的:垫片(shim)。
所谓“垫片”指的是自身计算量非常少,功能只是将几个其他后台服务的结果集成到一起并转发的服务器。例如一个服务器,查询两个JSON服务,并将结果简单地字符串连接。它的计算量非常小,但需要处理许多事件。
这里的关键词是“事件”。
Node.js支持一种特殊的应用程序架构,叫做“Eventd”(事件)编程。它仅使用非常少的资源就可以支持上千甚至百万级别的同时连接。它可以同时实现高吞吐量和低延迟。如果用在合适的地方,它的性能无人企及。
Rails完全不如Eventd编程。其实没有哪个框架能比。Ruby也有Eventd编程框架(如EventMachine、Async),但Rails完全不同。
既然Eventd这么好,为什么不在所有场合下都使用呢?因为它并不适合一切场合。我特别想强调的是每个请求的计算量,如果每个请求都执行很多计算,Eventd服务器就会挂掉。对于一台能处理百万连接的服务器,如果每个连接需要几百毫秒的CPU时间,那么就大事不妙了,因为请求量太大,延迟也会非常糟糕。
换句话说,Rails和Node.js是适用于不同项目的不同工具。如果你认为“这个项目使用Rails或者Node都可以”,那么我建议你仔细想想你的项目(以及框架),直到找出明显的正确答案。这二者的用处完全不一样。
如果团队不想用或者不会用,那么Rails就是错误的选择。
如果很明显其他框架更好,或者某个需要兼容的库并不支持Rails,那么Rails就是错误的选择。
如果不在服务器上渲染HTML,特别是当项目非常小,并且不使用服务器时,那么Rails可能是错误的选择。
如果不做原型类的工作(最好是在小型、高竞争力的团队内做),那么Rails就是错误的选择。
如果开发团队或者应用代码太大,并且无法拆分项目时,那么Rails就是错误的选择。
如果项目需要Node.js的Eventd服务器或者EventMachine一类的功能,那么Rails就是错误的选择。
最后,如果你只想听关于这个话题的娱乐新闻,那么这篇文章就是错误的选择。
评论1:
我来根据我的经验说说为什么应该坚持使用Rails:
所有“轻量级Sinatra API(或者类似的API)”服务最后都会越来越像Rails应用。Rails给开发者提供了很多遍历,除非你自己开发一个轻量级API,否则都不会注意到这些。例如控制台、日志、数据库迁移、数据库连接池、rspec集成、i18n等。
没人喜欢自己写项目结构。代码放在哪里?是lib?core?还是app?你觉得ActiveRecord太臃肿而“无法扩展”,所以就自己编写了一个轻量级“数据映射器”模式?但不好意思没有人愿意花时间去学习。话虽如此,Rails项目还是有一些可以随便挑选的部分,只不过不符合大家的习惯。
大部分时候,开发者会假设数据库连接池是一件很自然的事情。系统管理员不想调试你的程序。在反反复复几个星期后你就会认识到,数据库连接池是Rails提供的。而仅仅在Sinatra应用中导入activerecord再建立连接,是没有数据库连接池的。
某天,某个负责生产环境维护的人忘记了rake任务的名字。在运行bundle exec rake时忘记了添加-T。默认的任务是rspec。结果把生产数据库删掉了。到时你就会明白,Rails会阻止类似的事情发生,而那些“轻量级API”不会。但是,这种教训显然还不够深刻,因为几年后类似的事情还会再发生一次。
评论2:
对我来说Rails不可或缺,你只需要15分钟就可以从零开始构建一个网站在Heroku上运行,顺便设置好SSL和域名。我特别懒,所以即使不用数据库我也会使用Rails。所以我甚至不知道能不能在没有数据库的情况下运行Rails。
说实话,即使是JSON API加上React前端的模式,我也会用Rails。因为实在太方便了。
评论3:
我还是会选用Rails。如果你想快速开发,然后看一看有没有人喜欢,那么没有任何框架能够比得上Rails。
我有5年的RoR经验,两年sprintboot/kotlin经验,1年的Django经验。一旦设置好工作流程后,生产力方面就不会有太大差别。痛点仅在设置初始项目,以及在库版本更新时随时保持更新。
django和spring boot缺乏的就是实体、控制器和视图的命令行生成器,以及快速设置流程。
Django和spring boot需要在设置上下点功夫。Django需要settings、应用程序数组、中间件定义等。一旦这些工作都做好了,编写实体、视图和路由都非常简单。
Springboot需要坚实的文件夹结构、应用程序属性文件,还需要仔细设置好数据库迁移和日志。所以并不是那么容易上手。但编写实体、控制器、服务、视图等还是很方便的。
原文:http://codefol.io/posts/when-should-you-not-use-rails/
本文为 CSDN 翻译,转载请注明来源出处。