vert.x 學習筆記


Verticle

  • 一個verticle是部署在Vert.x.單位 每個verticle包含啟動它的主要手段。 一個應用程序可以是單個verticle或者可以由與彼此經由事件總線通信的多個verticles的。

  • Verticles在Vert.x實例中運行。 每個Vert.x實例在其自己的JVM實例運行,並且可以承載多個verticles。 一個Vert.x實例確保verticles彼此通過運行每個在其自己的類加載器分離,所以沒有修改一個靜態變量是另一個實例的風險。 主機可以運行一個單一的Vert.x實例或多個的。

  • 一個Vert.x實例,保證每個verticle實例總是在同一個線程執行。 並發Vert.x 是單線程的。

  • 在內部,Vert.x實例維護一組線程(通常為CPU核心數)是在執行一個事件循環 :檢查,看看是否有工作要做,做到這一點,去睡覺。

  • Verticles通過使用事件總線傳遞消息通信。

  • 雖然你可能會認為,共享數據和可擴展性截然相反。 Vert.x提供了一個共享的MAP和跨在同一Vert.x實例中運行verticles傳遞不可改變的數據共享一套設施,這時候數據是可變的唯一真正的 。

  • Vert.x使用相對較少的線程來創建一個事件循環和執行verticles。 但在某些情況下,需要verticle做一些要么昂貴計算,或可能阻塞,如連接到數據庫。 當發生這種情況Vert.x可以讓你標記verticle實例作為worker verticle 。Vert.x確保worker verticles將永遠不會被同時執行,所以要他們保持在最低水平,但他們在那里幫助你,當你需要他們,在這種情況下,將由后台執行的線程池執行。

Verticle

1,標准Verticle

這是最常見的一種,它是由一個event loop 線程來執行。它被創建的時候分分配到一個event loop線程,並使用這個線程調用它的start方法。它保證在這個實例中執行的代碼都是在同一個event loop線程中執行。

2,Worker Verticles

它使用worker 線程池中的一個線程執行,一個實例自始至終都是使用同一個線程執行。類似於標准Verticles,但是使用的是worker 線程池,它一般用來執行那些有阻塞的代碼,比如網絡請求,數據庫請求,文件創建等等,這樣它就不會阻塞event loop線程了。可以像下面這樣創建一個worker Verticles

DeploymentOptions options = new DeploymentOptions().setWorker(true);
vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", options);

 

3,多線程Worker Verticles

它也是使用wroker線程池中的一個線程執行,一個實現可以使用多個線程同時執行。它需要用戶自己保證每個Verticles的並發安全性。Vertx的客戶端和服務端不能在這里面創建,要不然它會拋出一個異常。

 

部署一個Verticles

Verticle myVerticle = new MyVerticle();
vertx.deployVerticle(myVerticle);

 

使用Json傳入配置

JsonObject config = new JsonObject().put("name", "tim").put("directory", "/blah");
DeploymentOptions options = new DeploymentOptions().setConfig(config);
vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", options);

 

Context 

獲取Context

Context context = vertx.getOrCreateContext();

判斷Context的類型

Context context = vertx.getOrCreateContext();
if (context.isEventLoopContext()) {
  System.out.println("Context attached to Event Loop");
} else if (context.isWorkerContext()) {
  System.out.println("Context attached to Worker Thread");
} else if (context.isMultiThreadedWorkerContext()) {
  System.out.println("Context attached to Worker Thread - multi threaded worker");
} else if (! Context.isOnVertxThread()) {
  System.out.println("Context not attached to a thread managed by vert.x");
}

 

Context中加入共享數據

final Context context = vertx.getOrCreateContext();
context.put("data", "hello");
context.runOnContext((v) -> {
  String hello = context.get("data");
});

 

定時

執行一次

long timerID = vertx.setTimer(1000, id -> {
  System.out.println("And one second later this is printed");
});

System.out.println("First this is printed");

執行多次

long timerID = vertx.setPeriodic(1000, id -> {
  System.out.println("And every second this is printed");
});

System.out.println("First this is printed");

在執行多次任務時,如果間隔時間太短,而任務執行的時間又太長,並不會阻止定時器的運行。建議可以使用執行一次,成功之后再添加執行一次。

 

Event Bus

它是整個系統的神經網絡,用於不同模塊數據之間的交互,有publish/subscribe, point-to-point, and request-response messaging.

如果發送消息之后希望接收返回消息,可以使用下面的方式:

發送者:

eventBus.send("news.uk.sport", "Yay! Someone kicked a ball across a patch of grass", ar -> {
  if (ar.succeeded()) {
    System.out.println("Received reply: " + ar.result().body());
  }
});

接收者:

MessageConsumer<String> consumer = eventBus.consumer("news.uk.sport");
consumer.handler(message -> {
  System.out.println("I have received a message: " + message.body());
  message.reply("how interesting!");
});

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM