最近想選高效,簡潔,擴充性強的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。多線程