我有一个程序,其中已部署了工人verticle(顶点版本3.6.3)。由此,我正在使用Vertx WebClient库发出一个HTTP请求。我的vertx工作池大小为20,事件循环池大小为10。紧接着,发出了HTTP请求(在send()调用之后),我正在阻塞使用可完成将来发出HTTP请求的工作线程(工作线程)。当我阻止工作线程时,HTTP请求永远不会响应,并且总是超时。当工作线程未被阻塞时,它会响应。我以为,如果我阻止工作线程,则池中还有其他工作线程可以接受HTTP请求。我在这里做错了什么?另外,我已经启用了网络日志活动,但是看不到任何网络日志被打印在日志中。
以下是我尝试过的程序,并且我正在运行示例HTTP服务器,该服务器在本地主机的端口8080处运行,该服务器可以正常响应。
import java.util.concurrent.TimeUnit;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.DeploymentOptions;
import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import io.vertx.core.buffer.Buffer;
import io.vertx.ext.web.client.HttpResponse;
import io.vertx.ext.web.client.WebClient;
import io.vertx.ext.web.client.WebClientOptions;
public class VertxTestMain extends AbstractVerticle {
private static int workerPoolSize = 20;
private static int eventLoopPoolSize = 10;
@Override
public void start() {
vertx.eventBus().consumer("vertx.address", event -> {
CompletableFuture<String> future = new CompletableFuture<>();
doAHttpRequest(vertx, future);
try {
//future.get(20, TimeUnit.SECONDS);
} catch (Exception e) {
System.out.println(Thread.currentThread().getName()+ " ----- HTTP request never responded");
e.printStackTrace();
}
});
}
private void doAHttpRequest(Vertx vertx, CompletableFuture<String> future) {
//System.setProperty("java.util.logging.config.file", "/opt/maglev/persisted/data/vertx-default-jul-logging.properties");
WebClientOptions options = new WebClientOptions();
options.setLogActivity(true);
WebClient webClient = WebClient.create(vertx, options );
int port = 8080;
String host = "localhost";
String url = "/";
System.out.println(Thread.currentThread().getName()+ " ----- Sending http://" + host + ":" + port + "/" + url);
// Send a GET request
webClient
.get(port, host, url)
.timeout(10000)
.send(ar -> {
if (ar.succeeded()) {
HttpResponse<Buffer> response = ar.result();
System.out.println(Thread.currentThread().getName()+ " ----- Received response. " + response.bodyAsString());
System.out.println(Thread.currentThread().getName()+ " ----- Received response with status code. " + response.statusCode());
future.complete("success");
} else {
System.out.println(Thread.currentThread().getName()+ " ----- Something went wrong. " + ar.cause().getMessage());
future.completeExceptionally(ar.cause());
}
});
}
public static void main(String[] args) {
DeploymentOptions deploymentOptions = new DeploymentOptions().setWorker(true).setInstances(2);
VertxOptions vertxOptions = new VertxOptions();
vertxOptions.setWorkerPoolSize(workerPoolSize);
vertxOptions.setEventLoopPoolSize(eventLoopPoolSize);
Vertx vertx = Vertx.vertx(vertxOptions);
vertx.deployVerticle(VertxTestMain.class.getName(), deploymentOptions, event -> {
if(event.succeeded()) {
System.out.println(Thread.currentThread().getName()+ " ----- VertxTestMain verticle is deployed");
vertx.eventBus().send("vertx.address", "send");
}
else {
System.out.println(Thread.currentThread().getName()+ " ----- VertxTestMain verticle deployment failed. " + event.cause());
}
});
}
}
答案 0 :(得分:1)
您不允许启动HTTP请求。
从您的方法中返回Future,而不是传递它:
private CompletableFuture<String> doAHttpRequest(Vertx vertx) {
CompletableFuture<String> future = new CompletableFuture<>();
WebClientOptions options = new WebClientOptions();
options.setLogActivity(true);
WebClient webClient = WebClient.create(vertx, options );
int port = 8080;
String host = "localhost";
String url = "/";
System.out.println(Thread.currentThread().getName()+ " ----- Sending http://" + host + ":" + port + "/" + url);
// Send a GET request
webClient
.get(port, host, url)
.timeout(10000)
.send(ar -> {
if (ar.succeeded()) {
HttpResponse<Buffer> response = ar.result();
System.out.println(Thread.currentThread().getName()+ " ----- Received response. " + response.bodyAsString());
System.out.println(Thread.currentThread().getName()+ " ----- Received response with status code. " + response.statusCode());
future.complete("success");
} else {
System.out.println(Thread.currentThread().getName()+ " ----- Something went wrong. " + ar.cause().getMessage());
future.completeExceptionally(ar.cause());
}
});
return future;
}
您还可以重用WebClient
,无需为每个请求都创建它。
还请查看Promise
Vert.x提供的API,因为它可能更适合您的用例: