问题
I am trying to scale an application which does a blocking call to an external application to fetch some data (Request and response order does not matter)
Since, its a blocking call as described in the vertx docs I am using worker verticle with worker pool set to 5 and I have deployed 5 instances of the worker verticle
When I submit multiple queries(when I tested I just fired 3 queries) even though my verticle is defined as worker with multiple instances with sufficient worker threads to process my requests in parallel they are not handled concurrently looks like they are handled sequentially (see logs below)
I also tried to create one master verticle and 4 worker verticles(Handles blocking call) where the initial request from the client is received on the master verticle, master sends the request to worker via event bus and it responds back but even this way I see the same behavior as explained above
Please suggest if I misunderstood something and if I am trying to achieve concurrency in an incorrect way. If so please suggest what the best way to achieve concurrency for this use case
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());
}
});
}
Logs:
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$0
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$0
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$0
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
回答1:
In vertx a normal verticle is associated with an event loop. So any request to that verticle has to wait till the event loop becomes free; even if no other instance of the same verticle is running. The worker verticle relax this by allowing a verticle to run in any of the worker thread, but an instance of a worker verticle cannot process two requests concurrently. To go even further you can use multi threaded worker verticles which can execute multiple requests concurrently.
So to answer your question, you can either create multiple instances of worker verticles or you can create multi threaded worker verticle.
you can find more info at http://vertx.io/docs/vertx-core/java/#_verticle_types
回答2:
Problem was partially with my testing approach - I issued multiple requests from different browser tabs & it was getting processed sequentially as the logs say above (I havent found out the answer why) hence I wrote a simple async client and issued multiple requests simultaneously and these were getting processed in parallel from different worker verticles
I was side tracked by my testing and I think I spoke a bit too early hence posting my findings
来源:https://stackoverflow.com/questions/39688488/worker-verticles-not-processing-requests-in-parallel