找不到 Vertx Web 资源

Vertx Web Resource Not Found

在我正在进行的项目之一中,我将路由动态注册到 Router,如下所示。

vertx.eventBus().consumer("REGISTER_ROUTE", handler -> {
      JsonObject message = (JsonObject) handler.body();
      HttpMethod method = HttpMethod.valueOf(message.getString("method"));
      router.route(method, message.getString("url"))
        .order(1)
        .handler(cxt -> cxt.json(new JsonObject().put("message", "This works..!!")));
    });

并且这个事件是从另一个像这样的Verticle触发的

vertx.eventBus().send("REGISTER_ROUTE",
        new JsonObject()
          .put("url", "/test-route")
          .put("method", "GET")
      );

问题是在 windows 机器上这几乎总是有效。但是在 AWS

上的测试 linux 实例上

最后两个场景不太确定与数字 3 的相关性(因为此 success/error 响应似乎在 3 个后续请求的循环中刷新)。认为它可能是服务器 Verticle 的实例数。但是修改实例计数也不会改变这种行为。

我有一个 404 的自定义错误处理程序,如下所示

router.errorHandler(404, routingContext -> {
      LOGGER.info("HTTP-404 Error Handler invoked");
      LOGGER.info("Router :" + router.toString() + " Routes Size: " + router.getRoutes().size());
      JsonObject error = new JsonObject()
        .put("error", "Resource not found");
      routingContext.response()
        .setStatusCode(404)
        .putHeader(HttpHeaders.CONTENT_TYPE, "application/json")
        .end(error.toBuffer());
    });

每当收到 404 响应时,我都可以从日志中看到路由器状态确实显示了使用给定 PATH 和 HTTP 方法组合声明的路由。

我已经尝试使用 HTTP 方法特定语法注册路由,例如 router.get(url),这似乎也没有任何区别。

Vert.x版本:4.2.7

JDK: Eclipse 铁木林 11.0.14.1+1

OS: EC2 上的 Centos 7

问题是问题并不总是发生,因此越来越难以确定根本原因并加以解决。

请让我知道这里是否有任何 wrong/missing。我还创建了一个示例项目 here。这是我在实际项目中所拥有的内容的近似复制品。 注意:这个问题通常不会在 Windows 发生在我身上(无论出于何种原因)。

Appclass中,每个Verticle部署了4个实例。

vertx.deployVerticle(Server.class.getName(), new DeploymentOptions().setInstances(4))
      .compose(server -> {
        return vertx.deployVerticle(RouteRegistration.class.getName(), new DeploymentOptions().setInstances(4))
          .onSuccess(id -> LOGGER.info("Application started Successfully"))
          .onFailure(LOGGER::catching);
      });vertx.deployVerticle(Server.class.getName(), new DeploymentOptions().setInstances(4))
      .compose(server -> {
        return vertx.deployVerticle(RouteRegistration.class.getName(), new DeploymentOptions().setInstances(4))
          .onSuccess(id -> LOGGER.info("Application started Successfully"))
          .onFailure(LOGGER::catching);
      });

这意味着:

  • 将在 Server verticle 的实例之间创建共享 HTTP 服务器和传入连接 load-balanced。
  • RouteRegistration Verticle 实例发送的消息将在消费者之间 load-balanced(eventBus.send 是 point-to-point)。

因此,连接将由具有不同设置的不同路由器处理。

在你的本地机器上,我不知道为什么会这样,也许你部署了一个单一的实例?

无论如何,要解决此问题,您必须在每个路由器实例中具有相同的路由器配置,因此 RouteRegistration 必须 publish 消息以便每个消费者实例都能获得它:

vertx.eventBus().publish("REGISTER_ROUTE",
      new JsonObject()
        .put("url", "/test-route")
        .put("method", "GET")
    );