Worker Verticles 不并行处理请求

Worker verticles not processing requests in parallel

我正在尝试扩展一个对外部应用程序进行阻塞调用以获取一些数据的应用程序(请求和响应顺序无关紧要)

因为,它是一个阻塞调用,如 vertx 文档中所述,我正在使用 worker verticle 并将 worker pool 设置为 5,并且我已经部署了 5 个 worker verticle 实例

当我提交多个查询时(当我测试时我只触发了 3 个查询)即使我的 Verticle 被定义为具有多个实例的工作线程有足够的工作线程来并行处理我的请求他们没有同时处理看起来他们是按顺序处理(请参阅下面的日志)

我还尝试创建一个 master verticle 和 4 个 worker verticle(处理阻塞调用),其中在 master verticle 上接收到来自客户端的初始请求,master 通过事件总线将请求发送给 worker 并响应但是即使这样,我也看到了与上面解释的相同的行为

如果我误解了什么以及我是否试图以不正确的方式实现并发,请提出建议。如果是这样,请建议实现此用例并发的最佳方法

VertxMain.java

public class VertxMain  {
public static final Logger LOG =Logger.getLogger(VertxMain.class.getName());
public static void main(String[] args) {      
MyFirstVerticle mfv = new MyFirstVerticle();
DeploymentOptions deploymentOptions = new DeploymentOptions().setWorker(true).setInstances(5);
  Vertx vertx = Vertx.vertx(new VertxOptions().setWorkerPoolSize(5));
  vertx.deployVerticle(MyFirstVerticle.class.getName(), deploymentOptions, res ->{
      if(res.succeeded()) {
          LOG.info("first verticle deployed");
      } else{
          LOG.info("first verticle failed to deployed" + res.cause());
      }
  });

MyFirstVerticle.java

public class MyFirstVerticle extends AbstractVerticle {
public static final Logger LOG = Logger.getLogger(MyFirstVerticle.class.getName()); 
Integer requestCount = 0;

@Override
public void start(Future<Void> fut) {
    InputStream is = this.getClass().getClassLoader().getResourceAsStream("qa.properties");
    Scanner sc = new Scanner(is);
    String line = sc.nextLine();

    Router router = Router.router(vertx);

    router.route("/qa").handler(routingContext -> {
         requestCount++;
        Date d = new Date();

         System.out.println("Received request #" + requestCount.toString() + " on " +d.toString());
         try {
                LOG.info("Processing request");
                Thread.sleep(20000);
                d.setTime(System.currentTimeMillis());
                System.out.println("Responding to request #" + requestCount.toString() + " on " +d.toString());
            } catch (Exception e) {
            }

        routingContext.response().end("<h1>Hello from my first " + 
                " Vert.x 3 application using " + Thread.currentThread().getName() + line + "</h1>");
    });

    vertx
    .createHttpServer()
    .requestHandler(router::accept)
    .listen(8081, result -> {
        if (result.succeeded()) {
            LOG.info("Webserver started to serve requests!!");
            fut.complete();
        } else {
            fut.fail(result.cause());
        }
    });
}

日志:

INFO: first verticle deployed
Received request #1 on Sun Sep 25 11:06:10 EDT 2016
Sep 25, 2016 11:06:10 AM com.myvertx.MyFirstVerticle lambda[=11=]
INFO: Processing request
Responding to request #1 on Sun Sep 25 11:06:30 EDT 2016
Received request #2 on Sun Sep 25 11:06:30 EDT 2016
Sep 25, 2016 11:06:30 AM com.myvertx.MyFirstVerticle lambda[=11=]
INFO: Processing request
Received request #1 on Sun Sep 25 11:06:36 EDT 2016 ->( *Looks like request is routed to a different instance of the verticle* )
Sep 25, 2016 11:06:36 AM com.myvertx.MyFirstVerticle lambda[=11=]
INFO: Processing request
Responding to request #2 on Sun Sep 25 11:06:50 EDT 2016
Responding to request #1 on Sun Sep 25 11:06:56 EDT 2016

在vertx中,一个普通的verticle与一个事件循环相关联。因此,对该 Verticle 的任何请求都必须等到事件循环变得空闲;即使同一 Verticle 的其他实例没有 运行ning。 worker verticle 通过在任何 worker 线程中允许一个 verticle 运行 来放松这一点,但是 worker verticle 的一个实例不能同时处理两个请求。为了更进一步,您可以使用可以同时执行多个请求的多线程 worker Verticle。

因此,为了回答您的问题,您可以创建多个 worker Verticle 实例,也可以创建多线程 worker Verticle。

您可以在 http://vertx.io/docs/vertx-core/java/#_verticle_types

找到更多信息

部分问题出在我的测试方法上——我从不同的浏览器选项卡发出了多个请求,并且按照上面的日志所说的顺序进行处理(我还没有找到原因的答案)因此我编写了一个简单的异步客户端并发出同时有多个请求,并且这些请求是从不同的 worker Verticle 并行处理的

我的测试被旁观了,我觉得我说得太早了,因此发布我的发现