vertx的一些问题

最近想选高效,简洁,扩充性强的web框作为移动平台后台,在对一系列框架对比后,选择了vertx。但通过一段使用后,发现vertx的一些问题。java

1.vertx使用共享资源产生的重复代码node

在vertx中,verticle是最基本的结构,简单的说相似j2ee servlet,可是verticle更加灵活,不只能够是服务,也但是客户端,verticle之间经过eventbus通信,实际上更相似akka的actor,vertx实现了相似nodejs express风格的web框架,可是java是多线程的,一般java的面向的目标环境更复杂。这样产生了一系列问题。
如jdbc链接池,在建立的时候必须在 verticle的start 中引入相似的语句程序员

JDBCClient client = JDBCClient.createShared(vertx, new JsonObject().clear()
                .put("provider_class", "io.vertx.ext.jdbc.spi.impl.HikariCPDataSourceProvider")
                .put("jdbcUrl", "jdbc:postgresql://127.0.0.1:5432/mydb")
                .put("username", "postgres")
                .put("password","password")
                .put("driverClassName", "org.postgresql.Driver")
                .put("maximumPoolSize", 30),"mypool");

若是有另一个verticle 须要使用链接池 mypool,也必须在start方法中加入这样一段。verticle 部署的是异步的多线程环境,这个createShared方法必须是线程安全的。若是有不少程序须要使用这个链接池 mypool,就会产生大量的冗余代码,这段代码必须是线程安全的。一个可行的方案是建立一个configuration verticle,这个verticle初始化全部的共享资源。而后经过这个verticle的静态方法访问系统的全部的共享资源。这样会减小大量的冗余代码,做为单例类,也没必要是线程安全的。web

须要注意是 当使用 vertx.deployVerticle 部署verticle (vertx是能够理解为一个verticle的环境),不能保证verticle的运行顺序,部署是异步的。为了保证configuration verticle的在其余verticle以前运行,必须使部署过程同步。同步方法并不复杂,能够用future实现。sql

try {
    log.info("deploy " + verticleID);
    CompletableFuture<Integer> future = new CompletableFuture<Integer>();
    vertx.deployVerticle(verticleID, deploymentOptions, res -> {
    if (res.succeeded()) {
        log.info("Deployment id is: " + res.result());
        future.complete(1);
    } else {
        log.error("Deployment failed!");
        future.complete(0);
    }});
    int result = future.get();
} catch (Throwable t) {
    log.error("error", t);
}

2.异步jdbcexpress

异步jdbc确实可以提升效率,vertx提供了基于sql 语句的异步api,下面是从vertx jdbc example 摘下来的一个例子。api

// create a test table
      execute(conn.result(), "create table test(id int primary key, name varchar(255))", create -> {
        // start a transaction
        startTx(conn.result(), beginTrans -> {
          // insert some test data
          execute(conn.result(), "insert into test values(1, 'Hello')", insert -> {
            // commit data
            endTx(conn.result(), commitTrans -> {
              // query some data
              query(conn.result(), "select count(*) from test", rs -> {
                for (JsonArray line : rs.getResults()) {
                  System.out.println(line.encode());
                }

                // and close the connection
                conn.result().close(done -> {
                  if (done.failed()) {
                    throw new RuntimeException(done.cause());
                  }
                });
              });
            });
          });
        });
      });
    });
  }

这是一个很是简单的事务,都须要写成这样,没法想象一个复琐事务的处理程序会变成什么样子。其实jdbc driver api依然是同步的,不过vertx提供了一个异步封装。语句级别异步api过细,若是程序员可以本身控制异步的粒度,将会改善这种状况。个人方案是提供jdbc同步api,而后程序员能够异步封装一个过程。这在vertx很容易实现。安全

executor.executeBlocking((Future<T> f) -> {
      try {
          jdbc_routine();
        }
        f.complete();
      } catch (SQLException e) {
        f.fail(e);
      }
    }, handler);

小结 vertx的体系结构无疑是很是先进的,多线程异步结构,内置metrics,支持cluster,支持高可用度,这些都不是nodejs轻易可以提供的。 可是目前使用起来确实有诸多不变,须要一点hack。多线程

相关文章
相关标签/搜索