异步应用服务器与多个阻塞服务器

Async App Server versus Multiple Blocking Servers

tl;dr 许多 Rails 个应用程序或一个 Vertx/Play!应用程序?

我一直在与我的团队的其他成员讨论使用 Play!框架(建立在 Netty 上)与旋转 Rails 应用服务器的多个实例。

我知道 Netty 是 asynchronous/non-blocking,这意味着在数据库查询、网络请求或类似的异步调用期间,事件循环线程将允许事件循环线程从阻塞的请求切换到另一个准备就绪的请求 processed/served。这将使 CPU 保持忙碌而不是阻塞和等待。

我赞成或使用诸如 Play 之类的东西!框架或 Vertx.io,非阻塞的东西......可扩展。另一方面,我的团队成员说您可以通过使用 Rails 应用程序的多个实例获得相同的好处,开箱即用的只有一个线程并且没有真正的并发性JVM 上的应用程序。他们说只需使用足够的应用程序实例来匹配一个 Play 的性能!应用程序(或我们使用的许多 Play! 应用程序),当 Rails 应用程序阻止时,OS 会将进程切换到不同的 Rails 应用程序。最后,他们说 CPU 将执行相同数量的工作,我们将获得相同的性能。

所以这是我的问题:

这两种方法都可以而且已经奏效。因此,如果切换会导致高昂的开发成本 and/or 进度命中,那么它可能不值得付出努力……但是。当成本变得高得无法接受时进行转换。考虑使用微服务作为一种渐进的切换策略。

如果您处于开发周期的早期,那么尽早进行转换可能是有意义的。重写是一种痛苦。

或者也许您永远不必切换并且 rails 会像魅力一样适合您的用例。而且您已经非常成功地让您的客户满意,以至于现金正在滚滚而来。

阻塞式单服务器方法的一些缺点:

  • 内存使用量增加。来源:多进程、内存泄漏、缺少共享数据结构(这会增加通信成本并带来一致性问题)。

  • 缺乏并行性。这有两个后果:更多的盒子和更多的延迟。您可能需要更多的盒子来处理相同的负载。因此,如果您需要扩展并担心资金问题,那么这可能是个问题。如果这不是一个问题,那就没关系。在服务器中,这意味着延迟增加,这种延迟无法通过增加进程来改善,这可能是一个致命的论点,具体取决于您的应用程序。

从 rails 到 node.js 和 golang 的一些例子:

这些帖子代表的论点可能说明了您的小组正在经历的事情。不幸的是,这个决定并不明显。

这取决于您正在构建的内容的性质、您的团队的性质、资源的性质、您的技能的性质、您的目标的性质以及您如何评价所有不同的权衡。

成本真的会下降吗?不管有多少台服务器,计算量不都是一样的吗?

取决于所完成工作的类型和规模。通常 Web 服务是 IO 绑定的,等待来自其他服务(如数据库、缓存等)的响应。

如果您使用的是单线程服务器,则进程在 IO 上会被阻塞很多,因此它经常什么都不做。相比之下,非阻塞服务器将能够处理许多请求,而单线程服务器被阻塞。你可以继续添加进程,但是单台机器只能添加这么多进程运行。非阻塞服务器可以拥有相同数量的进程,同时保持 CPU 尽可能忙于处理请求。使用非阻塞服务器时,通常可以在更小、更便宜的机器上处理更高的负载。

如果您的预期请求率可以由可接受数量的盒子处理,并且您不希望出现巨大的峰值,那么您可以使用单线程服务器。非阻塞服务器非常擅长吸收负载峰值,而不必添加机器。

如果您的工作是响应延迟并不重要,那么您可以使用更少的节点。

如果您的工作负载受到 CPU 限制,那么无论如何您都需要更多的盒子,因为不会有相同的并行机会,因为服务器不会阻塞 IO。