问题描述
目前在应用程序启动时,我正在部署一个 Verticle 并调用 createHttpServer(serverOptions)
。
我设置了一个 request().connection().closeHandler
来处理关闭的连接事件,主要是当客户决定取消他们的请求时,我们会停止执行该请求。
但是,当我在同一个 Verticle 中设置该处理程序时,它似乎只在任何同步代码执行完毕后才执行 closeHandler
代码,并且我们正在等待数据库通过 Futures 和异步处理程序进行响应。
如果不是这样,我为每个新的 HTTP 请求部署一个工作线程,它会正确地中断执行以执行 closeHandler
代码。
据我所知,HttpServer 已经应该自己处理请求的可伸缩性,因为它可以一次处理多个请求而无需部署新的 Verticle。从本质上讲,这听起来像是一种黑客的解决方法,一旦我们的应用程序全面展开,它可能会影响我们的线程负载或类似的事情。所以我的问题是:
这是正确的做法吗?
如果不是,那么应该遵循的正确方法或范式是什么?
如何从其自身的 Verticle 和 closeHandler
内部取消 Verticle 的执行?取消执行是指包括所有等待完成的期货。
为什么 closeHandler 在执行这种多垂直方法时只异步执行?使用正常方式并使用分配的线程池简单地执行请求会推迟 closeHandler 的执行,直到 eventloop 完成其队列,我们需要异步发生
解决方法
我认为你需要更好地理解 Vert.x。 Vert.x 不会根据请求启动和停止线程。 Verticles 的生命周期很长,每个都在其生命周期内处理多个事件,但不会同时处理。此外,您不应为每个请求部署工作(或非工作)Verticles。
你要做的是部署一个 Verticles 池(worker 和 non),Vert.x 在它们之间分配负载。一个 HTTP 服务器被放置在前面,它将接收请求并将它们转发给要处理的 Verticle。
为了停止处理请求,您需要在某处保留一个标志,如果连接关闭,则设置该标志。然后您可以在您的流程中检查它并停止处理。只是不要忘记在每个请求开始时清除标志。
,部署或取消部署顶点不会影响线程数。 Vert.x 使用有限大小的线程池。
取消部署 Verticle 是缩减服务规模的一种手段。理想情况下,您根本不应取消部署顶点。部署或取消部署确实会影响性能。
closeHandler
,正如我之前提到的,是一种释放资源的回调方法。
Vert.x Future
不提供取消方式。原因是即使是 Java 的 Future.cancel()
也是 cooperative operation。
作为解决此问题的一种方法,可能按照上面的建议传递对 AtomicBoolean
的引用,并在每个同步步骤之前检查它是最好的方法。但是,您仍然会被同步操作阻止。