【问题标题】:Vertx add handler to Spring data APIVertx 将处理程序添加到 Spring 数据 API
【发布时间】:2018-04-11 05:49:30
【问题描述】:

在vertx中,如果我们要执行jdbc操作,不会阻塞主循环,我们使用以下代码,

client.getConnection(res -> {
  if (res.succeeded()) {

    SQLConnection connection = res.result();

    connection.query("SELECT * FROM some_table", res2 -> {
      if (res2.succeeded()) {

        ResultSet rs = res2.result();
        // Do something with results
      }
    });
  } else {
    // Failed to get connection - deal with it
  }
});

在这里,我们添加了将在我们的操作完成时执行的处理程序。

现在我想使用Spring Data API,但是和上面的方法一样吗

现在我按如下方式使用它

@Override
public void start() throws Exception {
    final EventBus eventBus = this.vertx.eventBus();
    eventBus.<String>consumer(Addresses.BEGIN_MATCH.asString(), handler-> {
        this.vertx.executeBlocking(()-> {
            final String body = handler.body();
            final JsonObject resJO = this.json.asJson(body);
            final int matchId = Integer.parseInt(resJO.getString("matchid"));
            this.matchService.beginMatch(matchId);//this service call method of crudrepository
            log.info("Match [{}] is started",matchId);
         }
    },
    handler->{});
}

这里我使用了执行阻塞,但它使用工作池中的线程,是否可以替代包装阻塞代码?

【问题讨论】:

  • 为什么要避免使用线程工作池?

标签: java vert.x


【解决方案1】:

回答这个问题:如果:

  • 您在单独的 pid 中运行多个 verticle 实例(使用 systemd 或 docker 或任何允许您在恢复模式下安全运行独立 java 进程的工具)并在集群模式下监听相同的 eventbus 通道(例如使用 hazelcast)。
  • 按照 tsegismont 在对此答案的评论中的建议,您将 verticle 的多个实例作为工作 verticles 运行。

另外,它与问题无关,这确实是个人意见,但我还是给出了它:我认为在 vert.x 应用程序中使用 Spring 依赖项是个坏主意。 Spring 与至少使用 Spring Core 的基于 Servlet 的应用程序相关。我的意思是,这与在完全基于 Spring 的生态系统中使用相关。否则,您会将许多未使用的大依赖项带回您的 jar 文件中。

几乎每个 Spring 模块都有具有相同目的的小型、轻量级和独立库。例如,对于 IoC,您有 guicehk2weld...

如果我需要使用基于 SQL 的数据库,我个人会受到 Spring 的 JdbcTemplateRowMapper 模型的启发,而无需使用任何 Spring 依赖项。用这样一个简单的界面来重现它非常简单:

import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;

public interface RowMapper<T extends Serializable> {
    T map(ResultSet rs) throws SQLException;
}

另外一个接口DatabaseProcessor 有这样的方法:

<T extends Serializable> List<T> execute(String query, List<QueryParam> params, RowMapper<T> rowMapper) throws SQLException;

还有一个 QueryParam 类,其中包含查询参数的值、顺序和名称(以避免 SQL 注入漏洞)。

【讨论】:

  • 我相信你应该改写答案的第一部分。 verticle 应部署为具有多个实例的 worker verticle。然后对 executeBlocking 的需求就消失了。至于第二部分,如果你有不想丢弃的遗留代码,我认为使用 Spring 很好
  • @tsegismont 我曾经基于多值 systemd 服务实例独立运行我的 verticles,例如:systemctl start myverticleA@1systemctl start myverticleA@2 或基于 docker 容器的多个实例。在这两种情况下,在集群模式下使用带有 hazelcast 的事件总线(它允许我对活动或不活动的实例进行更多监控,并使恢复更容易)。我会添加您的建议,但您认为我的方式不好吗?你对这个问题的看法对我来说很有价值。提前致谢。
  • @tsegismont 关于在 vert.x 中使用 spring 的部分:我不是很客观,但我认为鼓励不要从 vert.x(甚至是一般)使用与基于 servlet 的应用程序相同的旧反射。当然,我们必须保持务实,有时我们必须维护遗留代码(但在这种情况下,我会选择使用 Spring boot 来代替此类服务)。
  • @tsegismont 你所做的并没有错——尽管 SO 评论仅限于完全理解 :) 但我的观点是部署多个工作节点实例以与应用程序的阻塞部分进行交互是常见的 Vert.x 模式
  • 感谢您的回答,我已更新答案以添加此模式
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-21
  • 1970-01-01
  • 1970-01-01
  • 2021-04-24
  • 2021-02-26
  • 2018-08-24
  • 2011-07-03
相关资源
最近更新 更多