Vert.x 取消部署 Verticle 抛出 IllegalStateException 未知部署
Vert.x undeploy verticle throws IllegalStateException Unknown deployment
查看 Vert.x 应用程序的日志,我注意到在取消部署 Verticle 时出现以下异常(所有 3 个都是相同的异常):
Failed to undeploy netsci.graphservice.verticles.CommandVerticle
Failed to undeploy netsci.graphservice.verticles.QueryVerticle
Failed to undeploy netsci.graphservice.verticles.EventVerticle
java.lang.IllegalStateException: Unknown deployment
at io.vertx.core.impl.DeploymentManager.undeployVerticle(DeploymentManager.java:203)
at io.vertx.core.impl.VertxImpl.undeploy(VertxImpl.java:616)
at microservice.MasterMicroserviceVerticle.undeploySupportingVerticle(MasterMicroserviceVerticle.java:462)
at java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:193)
at java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1548)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at microservice.MasterMicroserviceVerticle.stopSupportingVerticles(MasterMicroserviceVerticle.java:433)
at microservice.MasterMicroserviceVerticle.lambda$stop(MasterMicroserviceVerticle.java:383)
at io.vertx.core.Future.lambda$compose(Future.java:270)
at io.vertx.core.impl.FutureImpl.tryComplete(FutureImpl.java:126)
at io.vertx.core.impl.FutureImpl.complete(FutureImpl.java:88)
at io.vertx.core.impl.FutureImpl.handle(FutureImpl.java:152)
at io.vertx.core.impl.FutureImpl.handle(FutureImpl.java:23)
at io.vertx.core.impl.FutureImpl.setHandler(FutureImpl.java:81)
at io.vertx.core.Future.lambda$compose(Future.java:275)
at io.vertx.core.impl.FutureImpl.tryComplete(FutureImpl.java:126)
at io.vertx.core.impl.FutureImpl.complete(FutureImpl.java:88)
at io.vertx.core.impl.FutureImpl.handle(FutureImpl.java:152)
at io.vertx.core.impl.FutureImpl.handle(FutureImpl.java:23)
at io.vertx.core.impl.FutureImpl.tryComplete(FutureImpl.java:126)
at io.vertx.core.impl.FutureImpl.tryComplete(FutureImpl.java:133)
at io.vertx.core.impl.FutureImpl.complete(FutureImpl.java:95)
at microservice.MasterMicroserviceVerticle.lambda$null(MasterMicroserviceVerticle.java:363)
at microservice.messaging.impl.BufferKafkaProducerService.lambda$shutdown(BufferKafkaProducerService.java:97)
at io.vertx.core.impl.FutureImpl.setHandler(FutureImpl.java:81)
at io.vertx.core.impl.ContextImpl.lambda$null[=11=](ContextImpl.java:287)
at io.vertx.core.impl.ContextImpl.lambda$wrapTask(ContextImpl.java:337)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:403)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:445)
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:858)
at java.lang.Thread.run(Thread.java:748)
但是,它们都已部署并具有部署 ID:
Deployed: 213f1978-a595-4af1-8129-29de872e9907
Deployed: e46839f1-2dd2-4cce-9e12-66e09677b97a
Deployed: 8fdfd492-e005-4503-875e-13d73c633b2c
部署 ID 存储在同步映射中,顶点 class 作为键,部署 ID 作为值。查询时显示正确存储:
class netsci.graphservice.verticles.QueryVerticle: e46839f1-2dd2-4cce-9e12-66e09677b97a
class netsci.graphservice.verticles.CommandVerticle: 8fdfd492-e005-4503-875e-13d73c633b2c
class netsci.graphservice.verticles.EventVerticle: 213f1978-a595-4af1-8129-29de872e9907
在调用 endeploy 之前,如果我检查正在取消部署的 Verticle,我可以看到有效的部署 ID 被传递到取消部署的调用中:
Undeploying: e46839f1-2dd2-4cce-9e12-66e09677b97a
Undeploying: 8fdfd492-e005-4503-875e-13d73c633b2c
Undeploying: 213f1978-a595-4af1-8129-29de872e9907
以下是相关的代码位:
public abstract class MasterMicroserviceVerticle extends MicroserviceVerticle {
private final Map<Class, String> supportingVerticles =
Collections.synchronizedMap(new HashMap<Class, String>());
...
private Future<Void> deploySupportingVerticle(Class verticle) {
Future<Void> future = Future.future();
vertx.deployVerticle(
verticle.getName(),
new DeploymentOptions().setConfig(config()),
asyncResult -> {
if (asyncResult.succeeded()) {
// Assign deployment ID to verticle map.
String depId = asyncResult.result();
System.out.println();
System.out.println();
System.out.println(depId);
System.out.println();
System.out.println();
supportingVerticles.put(verticle, depId);
healthStatusService.setHealth(verticle.getName(), HealthStatus.PASSING);
logger.info("Deployed {}", verticle.getName());
future.complete();
} else {
healthStatusService.setHealth(verticle.getName(), HealthStatus.FAILING);
logger.error("Failed to deploy {}", verticle.getName(), asyncResult.cause());
future.fail(asyncResult.cause());
}
});
return future;
}
...
@Override
public void stop(Future<Void> stopFuture) throws Exception {
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
for (Class c : supportingVerticles.keySet()) {
System.out.println(c + ": " + supportingVerticles.get(c));
}
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
...
return mongoFuture;
}).compose(handler -> {
Future<Void> verticlesFuture = Future.future();
stopSupportingVerticles(verticlesFuture.completer());
return verticlesFuture;
}).compose(handler ->
logger.info("Undeployed service");
stopFuture.completer();
}, stopFuture);
}
protected void stopSupportingVerticles(Handler<AsyncResult<Void>> handler) {
List<Future> undeployable = supportingVerticles
.keySet()
.stream()
.map(this::undeploySupportingVerticle)
.collect(Collectors.toList());
CompositeFuture.all(undeployable)
.setHandler(asyncResult -> {
if (asyncResult.succeeded()) {
handler.handle(Future.succeededFuture());
} else {
handler.handle(Future.failedFuture(asyncResult.cause()));
}
});
}
private Future<Void> undeploySupportingVerticle(Class verticle) {
Future<Void> future = Future.future();
System.out.println();
System.out.println();
System.out.println("Undeploying: " + supportingVerticles.get(verticle));
System.out.println();
System.out.println();
vertx.undeploy(supportingVerticles.get(verticle), asyncResult -> {
healthStatusService.setHealth(verticle.getName(), HealthStatus.FAILING);
if (asyncResult.succeeded()) {
logger.info("Undeployed {}", verticle.getName());
future.complete();
} else {
logger.error("Failed to undeploy {}", verticle.getName(), asyncResult.cause());
future.fail(asyncResult.cause());
}
});
return future;
}
}
请原谅所有 System.out.println()
的人,我把他们扔在那里是为了帮助我更好地了解正在发生的事情,并且可能应该将此信息记录在日志中。但就目前而言,如果能帮助我理解为什么 Vert.x 说部署未知?
,我将不胜感激
来自Vert.x specs:
You don’t need to manually undeploy child verticles started by a verticle, in the verticle’s stop method. Vert.x will automatically undeploy any child verticles when the parent is undeployed.
您可以通过覆盖子 Verticle 中的 stop()
方法来验证这一点。我会说,在 MasterMicroserviceVerticle
被取消部署的时候,其他的已经被取消部署了。
查看 Vert.x 应用程序的日志,我注意到在取消部署 Verticle 时出现以下异常(所有 3 个都是相同的异常):
Failed to undeploy netsci.graphservice.verticles.CommandVerticle
Failed to undeploy netsci.graphservice.verticles.QueryVerticle
Failed to undeploy netsci.graphservice.verticles.EventVerticle
java.lang.IllegalStateException: Unknown deployment
at io.vertx.core.impl.DeploymentManager.undeployVerticle(DeploymentManager.java:203)
at io.vertx.core.impl.VertxImpl.undeploy(VertxImpl.java:616)
at microservice.MasterMicroserviceVerticle.undeploySupportingVerticle(MasterMicroserviceVerticle.java:462)
at java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:193)
at java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1548)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at microservice.MasterMicroserviceVerticle.stopSupportingVerticles(MasterMicroserviceVerticle.java:433)
at microservice.MasterMicroserviceVerticle.lambda$stop(MasterMicroserviceVerticle.java:383)
at io.vertx.core.Future.lambda$compose(Future.java:270)
at io.vertx.core.impl.FutureImpl.tryComplete(FutureImpl.java:126)
at io.vertx.core.impl.FutureImpl.complete(FutureImpl.java:88)
at io.vertx.core.impl.FutureImpl.handle(FutureImpl.java:152)
at io.vertx.core.impl.FutureImpl.handle(FutureImpl.java:23)
at io.vertx.core.impl.FutureImpl.setHandler(FutureImpl.java:81)
at io.vertx.core.Future.lambda$compose(Future.java:275)
at io.vertx.core.impl.FutureImpl.tryComplete(FutureImpl.java:126)
at io.vertx.core.impl.FutureImpl.complete(FutureImpl.java:88)
at io.vertx.core.impl.FutureImpl.handle(FutureImpl.java:152)
at io.vertx.core.impl.FutureImpl.handle(FutureImpl.java:23)
at io.vertx.core.impl.FutureImpl.tryComplete(FutureImpl.java:126)
at io.vertx.core.impl.FutureImpl.tryComplete(FutureImpl.java:133)
at io.vertx.core.impl.FutureImpl.complete(FutureImpl.java:95)
at microservice.MasterMicroserviceVerticle.lambda$null(MasterMicroserviceVerticle.java:363)
at microservice.messaging.impl.BufferKafkaProducerService.lambda$shutdown(BufferKafkaProducerService.java:97)
at io.vertx.core.impl.FutureImpl.setHandler(FutureImpl.java:81)
at io.vertx.core.impl.ContextImpl.lambda$null[=11=](ContextImpl.java:287)
at io.vertx.core.impl.ContextImpl.lambda$wrapTask(ContextImpl.java:337)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:403)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:445)
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:858)
at java.lang.Thread.run(Thread.java:748)
但是,它们都已部署并具有部署 ID:
Deployed: 213f1978-a595-4af1-8129-29de872e9907
Deployed: e46839f1-2dd2-4cce-9e12-66e09677b97a
Deployed: 8fdfd492-e005-4503-875e-13d73c633b2c
部署 ID 存储在同步映射中,顶点 class 作为键,部署 ID 作为值。查询时显示正确存储:
class netsci.graphservice.verticles.QueryVerticle: e46839f1-2dd2-4cce-9e12-66e09677b97a
class netsci.graphservice.verticles.CommandVerticle: 8fdfd492-e005-4503-875e-13d73c633b2c
class netsci.graphservice.verticles.EventVerticle: 213f1978-a595-4af1-8129-29de872e9907
在调用 endeploy 之前,如果我检查正在取消部署的 Verticle,我可以看到有效的部署 ID 被传递到取消部署的调用中:
Undeploying: e46839f1-2dd2-4cce-9e12-66e09677b97a
Undeploying: 8fdfd492-e005-4503-875e-13d73c633b2c
Undeploying: 213f1978-a595-4af1-8129-29de872e9907
以下是相关的代码位:
public abstract class MasterMicroserviceVerticle extends MicroserviceVerticle {
private final Map<Class, String> supportingVerticles =
Collections.synchronizedMap(new HashMap<Class, String>());
...
private Future<Void> deploySupportingVerticle(Class verticle) {
Future<Void> future = Future.future();
vertx.deployVerticle(
verticle.getName(),
new DeploymentOptions().setConfig(config()),
asyncResult -> {
if (asyncResult.succeeded()) {
// Assign deployment ID to verticle map.
String depId = asyncResult.result();
System.out.println();
System.out.println();
System.out.println(depId);
System.out.println();
System.out.println();
supportingVerticles.put(verticle, depId);
healthStatusService.setHealth(verticle.getName(), HealthStatus.PASSING);
logger.info("Deployed {}", verticle.getName());
future.complete();
} else {
healthStatusService.setHealth(verticle.getName(), HealthStatus.FAILING);
logger.error("Failed to deploy {}", verticle.getName(), asyncResult.cause());
future.fail(asyncResult.cause());
}
});
return future;
}
...
@Override
public void stop(Future<Void> stopFuture) throws Exception {
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
for (Class c : supportingVerticles.keySet()) {
System.out.println(c + ": " + supportingVerticles.get(c));
}
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println();
...
return mongoFuture;
}).compose(handler -> {
Future<Void> verticlesFuture = Future.future();
stopSupportingVerticles(verticlesFuture.completer());
return verticlesFuture;
}).compose(handler ->
logger.info("Undeployed service");
stopFuture.completer();
}, stopFuture);
}
protected void stopSupportingVerticles(Handler<AsyncResult<Void>> handler) {
List<Future> undeployable = supportingVerticles
.keySet()
.stream()
.map(this::undeploySupportingVerticle)
.collect(Collectors.toList());
CompositeFuture.all(undeployable)
.setHandler(asyncResult -> {
if (asyncResult.succeeded()) {
handler.handle(Future.succeededFuture());
} else {
handler.handle(Future.failedFuture(asyncResult.cause()));
}
});
}
private Future<Void> undeploySupportingVerticle(Class verticle) {
Future<Void> future = Future.future();
System.out.println();
System.out.println();
System.out.println("Undeploying: " + supportingVerticles.get(verticle));
System.out.println();
System.out.println();
vertx.undeploy(supportingVerticles.get(verticle), asyncResult -> {
healthStatusService.setHealth(verticle.getName(), HealthStatus.FAILING);
if (asyncResult.succeeded()) {
logger.info("Undeployed {}", verticle.getName());
future.complete();
} else {
logger.error("Failed to undeploy {}", verticle.getName(), asyncResult.cause());
future.fail(asyncResult.cause());
}
});
return future;
}
}
请原谅所有 System.out.println()
的人,我把他们扔在那里是为了帮助我更好地了解正在发生的事情,并且可能应该将此信息记录在日志中。但就目前而言,如果能帮助我理解为什么 Vert.x 说部署未知?
来自Vert.x specs:
You don’t need to manually undeploy child verticles started by a verticle, in the verticle’s stop method. Vert.x will automatically undeploy any child verticles when the parent is undeployed.
您可以通过覆盖子 Verticle 中的 stop()
方法来验证这一点。我会说,在 MasterMicroserviceVerticle
被取消部署的时候,其他的已经被取消部署了。