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

问题描述 投票:0回答:2

我来自一个请求 = 一个线程的概念,现在我想使用

Vertx
来理解事件循环的概念。根据文档,如果我们使用阻塞操作,我们应该将其传递给
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')";

    }

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

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

1)事件循环如何在请求之间切换(从输出中它首先获取一些请求,然后给它们响应)?

2)我使用

executeBlocking
方法,但是你如何看到上面的代码仅使用名为
vert.x-eventloop-thread-0

的事件循环线程

3)根据第一个问题,vertx事件循环在请求之间切换,但如果我将方法

execute
更改为:

 private String execute(){ 
        Thread.sleep(3000);
            return "insert into rubbish (name) values ('test')";      
    }

它将停止事件循环,直到超时未完成

提前谢谢您

java vert.x event-loop
2个回答
3
投票

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
,并且你的同步基本上是0ms。

您可以通过以下代码看到这一点:

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 秒。您还应该看到有关此的警告。


0
投票

添加参数“false”

vertx.executeBlocking(f -> {
           System.out.println("Future on " + Thread.currentThread().getName());
           f.complete();
       }, false ,r -> {
           System.out.println("Re enter code here`sult on " + Thread.currentThread().getName());
       });
© www.soinside.com 2019 - 2024. All rights reserved.