当前位置: 首页 > 知识库问答 >
问题:

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

车子平
2023-03-14

我来自一个请求=一个线程的概念,现在我想使用Vertx来理解事件循环的概念。根据文档,如果我们使用阻塞操作,我们应该将其传递给执行阻塞方法。

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)我使用了< code>executeBlocking方法,但是您可以看到上面的代码只使用了名为< code > vert . x-event loop-thread-0 的事件循环线程

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

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

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

提前谢谢你

共有1个答案

赫连越
2023-03-14

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

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

然后EventLoop将弹出队列中的第一个元素,并将其结果放回队列:请求处理程序(R2)getConntions(R1)

然后第三个请求可能会进来,而我们弹出requestHandler (R2):getConnection ( R1) requestHandler (R3) getConnection (R2)

并且重复,因此循环

2)实际上,您在阻塞处理程序中不做任何事情。在< code > if(closehndlr . failed()){ 之前添加一些大循环,您会看到警告。

现在发生的是,你在做< code >异步-

您可以使用以下代码看到这一点:

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

 类似资料:
  • 问题内容: 我也在学习Java和android。我们可以在while循环中执行的几乎所有事情都可以在while循环中执行。 我发现一个简单的条件,使用while循环比for循环更好 如果我必须在程序中使用counter的值,那么我认为while循环要比for循环好 使用while循环 在这种情况下,我发现while循环要比for循环好,因为如果要在for循环中实现相同的效果,则必须将counter

  • 我正在尝试使用Netty4.1编写一个TCP服务器,它将承载数千个持久连接(TL)。x、 在性能测试期间,我们观察到,如果有几千个到服务器的连接,然后我们得到一个突发的连接,比如说另外几千个连接,这些新的SSL握手会使工作线程长时间处于繁忙状态,这会导致现有连接开始超时。在internet上提供的所有Netty示例中,我看到服务器是这样引导的: 我想知道我是否可以使用两个工人组而不是一个。因此,我

  • 我对Java编码非常陌生,我已经研究这个问题大约4天了。我正在做一个选择你自己的结局故事。当我到达第69行时,如果读者选择是,我希望系统重新开始故事,如果他们选择否,则结束程序。我不确定我是否正确地编码了while循环,或者我甚至可以使用中断;操作员就像我在使用它一样。对不起,我的代码太难看了,哈哈,我正在努力变得更好。感谢您的建议! }

  • 我正在使用vert。x 2.1.5版本。我试图在我的项目中使用事件循环。下面给出了示例代码 在此代码中,我的事件总线在执行事件循环之前返回值。我需要根据事件循环输出填充我的输出 如何实现

  • 顶点似乎只由单个线程执行,并且总是由同一个线程执行。但是Vert. x能够通过每个CPU创建一个线程来使用机器中的所有CPU。每个线程可以向多个顶点发送消息。 但在性能测试期间,在标准verticle上评测Vertex http服务器时,我只能看到一个线程处理所有处理(vert.x-eventloop-thread-0)。 我该怎么做才能让我的8个事件循环线程都处理到verticle的消息?

  • 问题内容: Node.JS的最大优点是它具有非阻塞性。它是单线程的,因此不需要为每个新的传入连接生成新的线程。 在事件循环(实际上是单线程)的后面,有一个“非阻塞工作程序”。这个东西不再是单线程的,所以(据我了解),它可以为每个任务产生一个新线程。 也许我误会了一些东西,但是优势到底在哪里。如果要处理的任务很多,那么“非阻塞工作”会不会变成“阻塞工作人员”? 谢谢克里斯蒂安 问题答案: 您需要阅读