Vertx executeBlocking使用事件循环而不是工作线程

时间:2018-03-24 03:54:31

标签: java vert.x event-loop

我来自概念一个请求=一个线程,现在我想使用executeBlocking进行事件循环的概念。根据文档,如果我们使用阻塞操作,我们应该将其传递给Verticles use the Vert.x worker pool for executing blocking actions, i.e executeBlocking or worker verticle. 方法。

http://vertx.io/docs/vertx-core/groovy/

我在public class JdbcVertx extends AbstractVerticle{ public static void main(String[] args) { Vertx v = Vertx.vertx(); v.deployVerticle(new JdbcVertx(),new DeploymentOptions().setWorkerPoolSize(10)); } @Override public void start() throws Exception { JDBCClient client = JDBCClient.createNonShared(this.vertx, new JsonObject() .put("url", "jdbc:postgresql://localhost:5432/test") .put("user", "postgres") .put("password", "pw") .put("driver_class", "org.postgresql.Driver") .put("max_pool_size", 30)); this.vertx.createHttpServer() .requestHandler(r -> { int i = (int) (Math.random() * 100); System.out.println("Req id: " + i+ " "+Thread.currentThread().getName()); client.getConnection(handler -> { if (handler.failed()) { throw new RuntimeException(handler.cause()); } else { final SQLConnection connection = handler.result(); this.vertx.executeBlocking(blockingCodeHandler->{ connection.execute(execute(), hndlr -> { connection.close(closehndlr -> { if (closehndlr.failed()) { throw new RuntimeException(closehndlr.cause()); } else { System.out.println("CON end: "+i+" "+Thread.currentThread().getName()); r.response().putHeader("content-type", "text/html").end("Response: " + i); } }); }); },false,as->{}); } }); }).listen(8080); } private String execute(){ return "insert into rubbish (name) values ('test')"; }

中有一些与此段落相关的问题

这是我的代码:

Req id: 45 vert.x-eventloop-thread-0
Req id: 22 vert.x-eventloop-thread-0
Req id: 96 vert.x-eventloop-thread-0
Req id: 85 vert.x-eventloop-thread-0
Req id: 33 vert.x-eventloop-thread-0
CON end: 22 vert.x-eventloop-thread-0
CON end: 33 vert.x-eventloop-thread-0
CON end: 45 vert.x-eventloop-thread-0
CON end: 85 vert.x-eventloop-thread-0

我向http服务器发送100个请求,这是输出:

executeBlocking

1)事件循环如何在请求之间切换(从输出开始,它首先得到一些请求,然后给出响应)?

2)我使用vert.x-eventloop-thread-0方法但你怎么看上面的代码只使用名为execute的事件循环线程

3)根据第一个问题,vertx事件循环在请求之间切换,但如果我将方法 private String execute(){ Thread.sleep(3000); return "insert into rubbish (name) values ('test')"; } 更改为:

void logical_jmp(int loc) { int branch_jmp(int loc) {

它将停止事件循环,直到超时结束

提前谢谢

1 个答案:

答案 0 :(得分:1)

1)你可以这样看看EventLoop:每次提供一个处理程序时,它都是另一个放在排序队列中的函数。

当您的第一个请求进入时,它可能看起来像这样 requestHandler (R1) requestHandler (R2)

然后是EventLoop l弹出队列中的第一个元素,并将其结果放回队列: requestHandler (R2) getConnection (R1)

当我们弹出requestHandler (R2)时,第三个请求可能会进入: getConnection (R1) requestHandler (R3) getConnection (R2)

然后重复,Loop

2)实际上,你在阻止处理程序中没有做任何事情。在if (closehndlr.failed()) {之前添加一些大循环,您将看到警告。

现在发生的事情是你正在做async->sync->async,你的同步基本上是0毫秒。

您可以使用以下代码查看此内容:

vertx.setPeriodic(1000, h -> {
        System.out.println("Periodic on " + Thread.currentThread().getName());
       vertx.executeBlocking(f -> {
           System.out.println("Future on " + Thread.currentThread().getName());
           f.complete();
       }, r -> {
           System.out.println("Result on " + Thread.currentThread().getName());
       });
    });

打印:

Periodic on vert.x-eventloop-thread-0
Future on vert.x-worker-thread-3
Result on vert.x-eventloop-thread-0
Periodic on vert.x-eventloop-thread-0
Future on vert.x-worker-thread-4
Result on vert.x-eventloop-thread-0

3)不要使用Thread.sleep(3000) :)通过这样做,你只需要让EventLoop停止3秒。您也应该看到有关此事的警告。