我正在尝试使用Vert.x,并且对基于事件循环而不是线程/连接模型的服务器还很陌生。
public void start(Future<Void> fut) {
vertx
.createHttpServer()
.requestHandler(r -> {
LocalDateTime start = LocalDateTime.now();
System.out.println("Request received - "+start.format(DateTimeFormatter.ISO_DATE_TIME));
final MyModel model = new MyModel();
try {
for(int i=0;i<10000000;i++){
//some simple operation
}
model.data = start.format(DateTimeFormatter.ISO_DATE_TIME) +" - "+LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
r.response().end(
new Gson().toJson(model)
);
})
.listen(4568, result -> {
if (result.succeeded()) {
fut.complete();
} else {
fut.fail(result.cause());
}
});
System.out.println("Server started ..");
}
- 我只是试图模拟一个长时间运行的请求处理程序来理解这个模型是如何工作的。
- 我观察到所谓的事件循环在我的第一个请求完成之前被阻塞。无论需要多少时间,直到前一个请求完成后,后续请求才会得到响应。
- 很明显,我在这里缺少一件事情,这就是我想问的问题。
- 接受所有请求难道不被认为是异步吗?如果只有在前一个连接被清除后才能接受新连接,那么它如何是异步的呢?
- 假设一个典型的请求需要100毫秒到1秒的任意时间(根据请求的种类和性质)。这意味着,即使在一秒钟内结束,事件循环也不能接受新的连接直到上一个请求完成。如果我作为一个程序员不得不考虑所有这些,并将这样的请求处理程序推送到工作线程中,那么它与线程/连接模型有什么不同呢?
- 我只是试图了解这个模型如何比传统的线程/连接服务器模型更好?假设没有I/O操作或者所有的I/O操作都是异步处理的,那么它如何解决c10k问题,当它不能启动所有并发请求并行处理,必须等待前一个请求终止时才能处理下一个请求?
- 即使我决定将所有这些操作推送到一个工作线程中(池化的),那么我不是回到了同样的问题吗?在线程之间进行上下文切换? 根据答案编辑并置顶此问题以获取悬赏
- 我完全不明白这个模型被称为异步的原理。
- Vert.x有一个异步JDBC客户端(异步是关键词),我试图将其与RXJava适配。
- 以下是一个代码示例(相关部分)
server.requestStream().toObservable().subscribe(req -> {
LocalDateTime start = LocalDateTime.now();
System.out.println("Request for " + req.absoluteURI() +" received - " +start.format(DateTimeFormatter.ISO_DATE_TIME));
jdbc.getConnectionObservable().subscribe(
conn -> {
// Now chain some statements using flatmap composition
Observable<ResultSet> resa = conn.queryObservable("SELECT * FROM CALL_OPTION WHERE UNDERLYING='NIFTY'");
// Subscribe to the final result
resa.subscribe(resultSet -> {
req.response().end(resultSet.getRows().toString());
System.out.println("Request for " + req.absoluteURI() +" Ended - " +LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME));
}, err -> {
System.out.println("Database problem");
err.printStackTrace();
});
},
// Could not connect
err -> {
err.printStackTrace();
}
);
});
server.listen(4568);
- 查询需要大约3秒钟才能返回完整的表格转储。
- 当我同时发送请求(仅尝试了2个),我发现第二个请求完全等待第一个请求完成。
- 如果JDBC选择是异步的,那么有没有一个合理的期望是在等待选择查询返回任何内容时,框架处理第二个连接?