我来自概念一个请求=一个线程,现在我想使用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) {
它将停止事件循环,直到超时结束
提前谢谢
答案 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秒。您也应该看到有关此事的警告。