最近想选高效,简洁,扩充性强的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。多线程