Heroku上的Thin和Unicorn有何区别?

34

想了解人们对于在Rails服务器上使用Unicorn和Thin的看法。大部分在线文章或基准测试结果都显得非常不完整,因此建立一个集中讨论的地方会很不错。

Unicorn是一个多进程服务器,而Thin是一个事件驱动/非阻塞服务器。如果您的代码是异步或非阻塞的,那么事件驱动服务器是很好的选择 - 纯Vanilla Rails则是阻塞的。因此,除非您使用非阻塞Rails库,否则我真的不认为使用Thin有什么优势。更糟糕的是,在非阻塞服务器中,如果您的I/O循环是阻塞的,则将阻塞整个循环,并且在阻塞调用返回之前无法处理任何其他请求。阻塞库会拖慢Thin的速度!

为什么Heroku选择Thin作为默认服务器(用于cedar)?他们是聪明的家伙,所以我相信他们肯定有理由。

以下链接建议使用4个Unicorn工作进程来替换Thin - 这对我来说非常有道理。 在Heroku上使用4个Unicorn进程


1
我并没有完整的答案回答你的问题。不过有一件事情我可以告诉你,那就是Unicorn非常适合调试,你可以查看它在github上的README文档:https://github.com/defunkt/unicorn#readme - Dillon Benson
3个回答

25

Thin易于配置 - 不是最优的,但在Heroku环境中可以正常工作。

Unicorn可能更高效,但需要进行配置:有多少个workers?预加载应用程序?该如何选择?

我发布了带有3、5和8个worker的Unicorn Heroku应用程序 - 这仅基于每个应用程序的大小 - 所使用的代码量、内存量和流量量都会影响选择这个数字,您需要随时监控以确保您得到正确的数字,并且您的应用程序没有耗尽内存。

Preload false - 这将使您的应用程序启动较慢,但是当Unicorn重启worker时,这对网络连接(memcache、postgres、mongo等)更加“安全”。

Preload true - 这样做更好,但您需要在pre和post fork代码中正确处理服务器重新连接问题。

Thin开箱即用,没有这些问题,但您只能获得一个执行进程。

总结:对于每个人而言,将Unicorn配置良好(或者根本无法运行)真的很难,而Thin可以直接工作,从而减少对支持请求的需求。


1
预加载设置只影响部署时的加载时间 - 所以这并不是一个大问题。还有什么需要注意的吗? - EugeneMi
1
Preload false 可能会导致您的应用在部署期间超过 Heroku 的 30 秒请求队列时间。我曾经遇到过这种情况,不得不切换回 Preload true - 然后您必须知道如何处理重新连接,例如 ActiveRecord、Memcache、MongoDB、Redis、NewRelic 等等。 - Tom Fakes
1
你知道在使用Unicorn时修改全局变量是否会有问题吗?我想知道不同的工作进程是否共享一个全局命名空间,还是它们保留自己的全局变量。谢谢! - Brian Armstrong
4
慢客户端怎么办?由于Heroku不像nginx那样在Unicorn前面使用Web服务器,所以会有影响吗? (注:unicorn是一种Rack HTTP服务器) - djburdick
1
@Brian - 这些工作线程都是独立的实例。它们共享尚未被使用的内存,而在Ruby当前的垃圾回收机制下,这种共享量其实并不多。 - Tom Fakes
Heroku表示他们不会在应用程序前面放置nginx,但我的日志显示他们确实这样做了。我也在我的应用程序中看到了Varnish头,而他们表示不会为Cedar应用程序这样做。 - Tom Fakes

13

最近(仅几个月前),Phusion Passenger 的开发人员为 Heroku 提供了支持。这是一个你应该尝试并查看是否符合你的需求的替代方案。

即使只有 1 个 dyno,它也非常快,并且响应时间的下降是明显的。在 GitHub 上托管了一个简单的Passenger Ruby Heroku 示例

Passengers on Heroku 的主要优点包括:

  • 通过 Nginx 进行静态资源加速 - 不要让你的 Ruby 应用程序提供静态资产,让 Nginx 为你完成这项任务并卸载你的应用程序以进行真正重要的任务。Nginx 做得更好。

  • 多个工作进程 - Phusion Passenger 在单个 dyno 上运行多个 worker,从而充分利用其资源,为你提供更大的性价比。这种方法类似于 Unicorn 。但与 Unicorn 不同的是,Phusion Passenger 根据当前流量动态缩放工作进程的数量,因此在不必要时释放资源。

  • 内存优化 - Phusion Passenger 比 Thin 和 Unicorn 使用更少的内存。它还支持与代码预加载结合使用的写时复制虚拟内存,从而在运行 Ruby 2.0 时使你的应用程序使用更少的内存。

  • 请求/响应缓冲 - 包含的 Nginx 缓冲请求和响应,从而保护你的应用程序免受慢客户端(例如移动网络上的移动设备)的影响,并提高性能。

  • 带外垃圾回收 - Ruby 的垃圾回收器很慢,但为什么要让你的访问者遭受长时间的响应时间呢?通过在正常请求-响应周期之外运行垃圾回收来解决这个问题!这个概念最初由 Unicorn 提出,已得到改进:Phusion Passenger 确保每次只有一个请求正在运行带外垃圾回收,从而消除了 Unicorn 带外垃圾回收的所有问题。

  • JRuby支持 - Unicorn比Thin更好,但不支持JRuby。Phusion Passenger提供支持。

  • 希望这可以帮到您。


    10

    Heroku不使用智能路由——它会随机将作业分配给dynos,而不管dyno是否忙碌。因此,如果您的dyno无法同时处理多个作业,即使您支付了许多其他空闲的dynos,您也会遇到延迟(可能是巨大的延迟)。"没错——如果您的应用程序需要具有智能路由的80个dynos,则需要具有随机路由的4,000个。" http://news.rapgenius.com/James-somers-herokus-ugly-secret-lyrics

    Heroku表示他们正在解决这个问题,并计划使使用Unicorn更加容易。他们基本上说:“哎呀,我们几年来没有注意到这是一个问题……现在看来,对于Thin来说肯定是一个问题……所以我想你需要使用与我们一直推广的不同程序。” http://news.rapgenius.com/Jesper-joergensen-routing-performance-update-lyrics

    来自Heroku官方解释(上面的第二个链接):

    “事实上,Rails目前还不支持可靠的并发请求处理。这使得Rails开发人员无法利用Cedar堆栈提供的额外并发能力,除非他们转向像Puma或Unicorn这样的并发Web服务器。”

    使用Thin部署到Cedar的Rails应用程序可能会很快出现请求排队问题。因为Cedar路由器不再代表应用程序排队,所以在dyno处排队的请求必须等待单个Rails进程通过队列。许多客户遇到了这个问题,我们没有采取行动并为他们提供更好的部署Rails应用程序的方法。

    另外值得注意的是,他们的性能工具,包括New Relic,在dyno队列中花费的时间没有被报告。

    糟糕。

    http://news.rapgenius.com/Lemon-money-trees-rap-genius-response-to-heroku-lyrics


    2
    感谢您阅读 Rapgenius 文章,了解 Heroku 的如此巨大的失败和误导,令人惊讶/失望。我想我们可以从中得出结论:最好利用 Unicorn 的多进程并发,因为 Heroku 的 dyno 级别并发是虚假的。 - Yarin
    1
    这就是运行像Torquebox这样的集群应用服务器可以真正获得一些好处的地方。如果您有一个高流量的应用程序,请离开Heroku并部署3个集群化的Torquebox应用服务器。智能负载均衡的Web和后台进程,滚动部署,集群化的memcached和队列构建。这是一个完整的堆栈。 - brightball

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接