使用Vert.x構建Web服務器和消息系統

若是你對Node.js感興趣,Vert.x多是你的下一個大事件:一個創建在JVM上一個相似的架構企業制度。 這一部分介紹Vert.x是經過兩個動手的例子(基於Vert.x 2.0)。html

當Node.js出現,許多開發者興奮的感到能夠用不尋常的方法來構建可擴展的服務器端應用程序。 而不是開始,將服務使用多線程的請求重量級的容器。Node.js是啓動多個輕便單線程的服務器和流量路由到他們。java

如今,相似的框架已經出現,它的服務器部署在一個JVM中,使用JVM設施來管理流量輕量級服務器進程。 本批中的開源Java項目 ,您將瞭解Vert.x,事件驅動的架構相似的Node.js,是創建在JVM系列還擴展它在某些重要的新途徑。python

Vert.x亮點

Vert.x應用程序是事件驅動,異步和單線程的。 Vert.x過程經過事件總線,這是Vert.x的事件驅動架構的內置一塊通訊。 結合異步處理,單線程組件和事件總線產生高度的可擴展性,並編寫單線程應用對習慣於多線程併發Java的人來講是一種解脫。 能夠說,Vert.x的最好的部分是其模塊化的基於JVM的架構。 Vert.x應用程序能夠運行在幾乎全部的操做系統,而且可使用任何支持的JVM兼容的編程語言來編寫。 一個Vert.x應用可徹底在單一語言編寫,也能夠是用不一樣的編程語言模塊的跨界混搭。 Vert.x模塊集成了Vert.x事件總線上。web

在Vert.x基於事件的編程

Vert.x的基於事件的編程模型的標準和獨特的功能組合。 Vert.x應用在很大程度上是經過定義事件處理程序。 不一樣於傳統的基於事件的應用程序,可是,Vert.x應用保證不被阻塞。 而不是打開一個socket到服務器,請求資源,而後等待(阻塞)的響應,Vert.x發送到應用程序異步地響應,經過事件處理程序,並經過事件總線傳遞消息寫入。算法

Vert.x的編程框架包括一些白話,這將有助於更好的瞭解,經過兩個演示應用程序在本文的後面:sql

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

  • Verticles在Vert.x實例中運行。 每一個Vert.x實例在其本身的JVM實例運行,而且能夠承載多個verticles。 一個Vert.x實例確保verticles彼此經過運行每一個在其本身的類加載器分離,因此沒有修改一個靜態變量是另外一個實例的風險。 主機能夠運行一個單一的Vert.x實例或多個的。數據庫

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

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

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

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

  • Vert.x使用相對較少的線程來建立一個事件循環和執行verticles。 但在某些狀況下,須要verticle作一些要麼昂貴計算,或可能阻塞,如鏈接到數據庫。 當發生這種狀況Vert.x可讓你標記verticle實例做爲worker verticle 。Vert.x確保worker verticles將永遠不會被同時執行,因此要他們保持在最低水平,但他們在那裏幫助你,當你須要他們,在這種狀況下,將由後臺執行的線程池執行。

圖1示出Vert.x系統包括Vert.x實例,verticles,JVM中,服務器主機,以及事件總線的體系結構。

圖1. Vert.x系統的體系結構

Vert.x核心服務和模塊

Vert.x功能能夠分爲兩類:核心服務和模塊核心服務是可從verticle直接調用幷包括用於TCP / SSL,HTTP和網絡套接字的客戶端和服務器上的服務。 服務來訪問Vert.x事件總線; 定時器,緩衝區,流量控制,文件系統訪問,共享maps 和 sets,訪問配置,SockJS服務器,以及部署和取消部署verticles。 核心服務是至關靜態的,預計不會改變,所以全部其餘的功能由模塊提供。

Vert.x應用和資源能夠很容易地打包成模塊,並經過Vert.x共享的公共模塊庫 。 與模塊的交互是經過Vert.x事件總線異步:用JSON發送模塊的消息,你的申請將獲得答覆。 模塊和集成經過服務總線之間的這種脫鉤意味着模塊能夠在任何支持的語言編寫和其它任何支持的語言使用。 因此,若是有人寫在Ruby中,你想在你的Java應用程序使用這個模塊,是徹底能夠的!

編寫一個基於Java的Vert.x Web服務器

一個基本的Web服務器應用程序和消息傳遞系統。 首先下載vert.x 寫這篇文章的是2.0.0.final。 當地解開並添加它的bin文件夾到你的PATH 。 請注意,您須要安裝Java 7,若是你尚未。

若是你是一個Maven的人跟我同樣,那麼你能夠簡單如下的依賴添加到您的POM文件:

清單1. Maven的POM對Vert.x

<dependency> <groupId> io.vertx </groupId> <artifactId> vertx-core </artifactId> <version> 2.0.0-final </version> </dependency> <dependency> <groupId> io.vertx </groupId> <artifactId> vertx-platform </artifactId> <version> 2.0.0-final </version> </dependency>

清單2顯示了Server.java文件內容

清單2. Server.java

package com.geekcap.vertxexamples; import org.vertx.java.core.Handler; import org.vertx.java.core.http.HttpServerRequest; import org.vertx.java.deploy.Verticle; public class Server extends Verticle { public void start() { vertx.createHttpServer().requestHandler(new Handler<HttpServerRequest>() { public void handle(HttpServerRequest req) { String file = req.path().equals("/") ? "index.html" : req.path(); req.response.sendFile("webroot/" + file); } }).listen(8080); } }

前幾行清單2導入所需的Vert.x類:

  • Handler是全部處理器的基類!

  • HttpServerRequest表明Vert.x.服務器端的HTTP請求 這個類的一個實例將爲由服務器處理的每一個請求建立,而後傳遞到經過您的應用程序Handler實例(你會使用已註冊HttpServer )。

  • Verticle是在Vert.x應用程序部署的基本單位。 爲了使用Vert.x,你須要擴展Verticle類和重寫start()方法,這你的Verticle 入口點。

注意vertx清單2中的變量: 該Verticle類定義vertx做爲受保護的成員變量(繼承Verticle),它提供了訪問Vert.x運行。 該vertx變量的類型的Vertx,這暴露了如下方法:

  • createHttpClient()建立一個HTTP / HTTPS客戶端

  • createHttpServer()建立一個HTTP / HTTPS服務器

  • createNetClient()建立了一個TCP / SSL客戶端

  • createNetServer()建立了一個TCP / SSL服務器

  • creatSockJSServer()建立一個包裝了HTTP服務器SockJS服務器

  • eventBus()提供事件總線您的應用程序訪問

  • fileSystem()提供對文件系統的應用程序訪問

  • sharedData()提供應用程序訪問共享數據對象,它能夠被用來共享Verticles之間的數據

清單2中的代碼建立一個新的HTTP服務器,檢索其請求處理程序的參考,並將請求處理程序到新建立的HttpServerRequest處理程序。 該Handle接口定義了一個方法命名handler()並使用泛型定義實例傳遞給它的類定義的類型; 在這種狀況下HttpServerRequest 。 該HttpServerRequest而後定義如下字段:

  • method 是一個String包含給定請求的方法中,如GET , POST , PUT , DELETE ,等等。

  • path 是一個String包含所請求的路徑,如/index.html 。

  • query 是一個String包含查詢參數,如遵循如下問號部分: ?key=value 。

  • response 是一個基準HttpServerResponse表示對HTTP請求的響應。

  • uri 爲請求的完整URI。

清單2完成對經過映射一個空的請求- 「 / 」 -到index.html ,而後調用HttpServerResponse的sendFile()方法來告訴Vert.x流指定的文件返回給調用者。

綜上所述, Server級訪問Vert.x運行時,要求它建立一個新的HTTP服務器,並註冊一個Handler (即指望一個HttpServerRequest變量)的HttpServer 。 在處理器的handle()方法時, Server類從位於文件系統提供文件服務webroot目錄,這是相對的。

構建web服務器

讓咱們來構建示例應用程序,那麼咱們將使用Vert.x執行它。 此項目的Maven的POM文件顯示清單3所示。

清單3. Maven的POM構建Web服務器

<project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelVersion> 4.0.0 </modelVersion> <groupId> com.geekcap </groupId> <artifactId> vertx-examples </artifactId> <version> 1.0-SNAPSHOT </version> <packaging> jar </packaging> <name> vertx-examples </name> <url> http://maven.apache.org </url> <properties> <project.build.sourceEncoding> UTF-8 </project.build.sourceEncoding> </properties> <build> <plugins> <plugin> <groupId> org.apache.maven.plugins </groupId> <artifactId> maven-compiler-plugin </artifactId> <version> 2.0.2 </version> <configuration> <source> 1.6 </source> <target> 1.6 </target> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId> io.vertx </groupId> <artifactId> vertx-core </artifactId> <version> 2.0.0-final </version> </dependency> <dependency> <groupId> io.vertx </groupId> <artifactId> vertx-platform </artifactId> <version> 2.0.0-final </version> </dependency> <dependency> <groupId> junit </groupId> <artifactId> junit </artifactId> <version> 4.11 </version> <scope> test </scope> </dependency> </dependencies> </project>

兩個依賴添加到POM文件是vertx-code和vertx-platform的,這是須要開發的Java應用程序Vert.x。要構建這個應用程序,請執行如下Maven命令:

mvn clean install

這將產生一個名爲vertx-examples-1.0-SNAPSHOT.jar,將須要在你的CLASSPATH,以啓動您的verticle。這個示例應用程序提供了在發現網絡資源Web根目錄相對於該應用程序的啓動目錄。所以,你須要建立一個webroot的目錄,並創建一些資源從它服務。要啓動這個verticle,執行vertx在Vert.x的應用bin目錄,以下所示:

$VERTX_HOME/bin/vertx run com.geekcap.vertxexamples.Server -cp vertx-exampl

該vertx命令接受幾個選項,包括咱們使用它的人,運行。這是一個擴展類的只是名字Verticle和包含的start()方法和一個可選的參數集。在這種狀況下,咱們設置CLASSPATH使用-cp參數,並傳入JAR,咱們剛剛建立的文件。服務器將啓動,但不輸出任何內容到屏幕上,但你能夠將瀏覽器指向的網址:HTTP://localhost:8080。

對於個人例子中,我建立了一個簡單的HTML文件,該文件說:「Hello, Vert.x」,將其命名爲index.html的,並把它放在個人根目錄的目錄。這裏是個人輸出:

$ curl http://localhost:8080
<html><html> <head><title>Hello, Vert.x</title></head><head><title>Hello, Vert.x</title></head> <body><body> <p>Hello, Vert.x</p><p>Hello, Vert.x</p> </body></body> </html></html>

與Vert.x通訊

Vert.x的最重要的特色之一是它的事件總線。所述Vert.x事件總線容許verticles,可能用不一樣的編程語言,在使用任意點對點通訊彼此通訊或發佈/訂閱消息。在本節中,你會獲得怎樣的功能使用這兩種方法的不一樣verticles整合的感受。

在咱們開始以前,你爲何要使用消息在一個更傳統的基於事件的編程模型?一方面,消息支持的用不一樣的編程語言應用程序和組件的集成。這也使鬆散耦合,這意味着您能夠編寫代碼的多個任務爲中心的做品,而不是單一的,複雜的程序。最後,verticles之間的異步通訊提升了系統的可擴展性。異步通訊容許您定義系統的容量,由於它的發展。消息可能備份您的系統負荷增長,但他們最終會被處理。Vert.x對分佈式事件總線的支持也給了你啓動額外verticles以處理增長的負載的選項。

爲了創建一個Vert.x消息系統,則須要得到該事件總線。經過執行啓動eventBus()上的方法vertx類的實例:

EventBus eb = vertx.eventBus();

一旦你鏈接到EventBus您能夠經過如下兩種方式之一發布消息:

  • publish()發佈一個消息給使用地址發佈/訂閱消息,這意味着每subscriber到給定的地址將接收發布的消息。地址只是一個String,因此你要選擇有意義的事,但在何時是這兩個出版商和用戶配置爲使用相同的字符串。若是你熟悉Java消息系統(JMS),publish()起一樣地做用,發佈消息到一個topic。

  • send()發送消息到使用地址點對點的消息,這意味着只有一個訂戶將接收該消息。若是有多個用戶的地址,而後Vert.x將使用循環算法發送消息。使用循環算法的優勢是可擴展性:若是你沒有足夠的資源在一個Vert.x實例來支持你的負擔,那麼你能夠簡單地啓動其餘Vert.x實例,並登記他們做爲聽衆指定的地址。

發佈/訂閱VS點對點通訊

在發佈/訂閱消息模型中,發佈者將消息發送到被廣播到全部用戶的一個話題。使用發佈/事件驅動的架構訂閱了點至點的消息意味着組件只對所發生事件的發佈負責。發佈商並不須要知道它的訂閱者,以便廣播到它們。圖2是一個典型的Vert.x的流程圖發佈/訂閱消息架構。

圖2.發佈/訂閱消息

在點 - 點通訊,將消息從發佈者直接經過一個隊列發送給消費者。點對點的消息是一個很好的選擇,當你想消息消耗正好一次時,或者當兩個組件要異步地相互通訊。點 - 點消息架構顯示在圖3。

圖3.點對點通訊

咱們將使用Vert.x在下面的章節探討兩個郵件系統。

發佈/訂閱消息的例子

清單4更新我原來的服務器類(清單1)在幾個方面。首先,它部署了一個所謂的新verticle AuditVerticle經過調用(如清單5中定義)deployVerticle()的方法容器實例,其被定義爲母體的一部分Verticle類,提供了通向容器verticle中運行;所以,它是部署新verticles適當的位置。

清單4. Server.java 點至點消息

package com.geekcap.vertxexamples; import org.vertx.java.core.Handler;import org.vertx.java.core.Handler; import org.vertx.java.core.eventbus.EventBus;import org.vertx.java.core.eventbus.EventBus; import org.vertx.java.core.http.HttpServerRequest;import org.vertx.java.core.http.HttpServerRequest; import org.vertx.java.core.logging.Logger;import org.vertx.java.core.logging.Logger; import org.vertx.java.platform.Verticle;import org.vertx.java.platform.Verticle; public class Server extends Verticle {public class Server extends Verticle { public void start() {public void start() { // Create our dependent verticles// Create our dependent verticles container.deployVerticle("com.geekcap.vertxexamples.AuditVerticle");.deployVerticle("com.geekcap.vertxexamples.AuditVerticle"); // Create an HTTP Server that serves files// Create an HTTP Server that serves files vertx.createHttpServer().requestHandler(new Handler<HttpServerRequest>() {.createHttpServer().requestHandler(new Handler<HttpServerRequest>() { public void handle(HttpServerRequest req) {public void handle(HttpServerRequest req) { Logger logger = container.logger();Logger logger = container.logger(); if (logger.isDebugEnabled()) {if (logger.isDebugEnabled()) { logger.debug("Received a request for resource: " + req.path());.debug("Received a request for resource: " + req.path()); }} logger.fatal("Where are my logs!?!?");.fatal("Where are my logs!?!?"); logger.info("Here is an info message");.info("Here is an info message"); // Serve up our files// Serve up our files String file = req.path().equals("/") ? "index.html" : req.path();String file = req.path().equals("/") ? "index.html" : req.path(); req.response().sendFile("webroot/" + file);.response().sendFile("webroot/" + file); // Let's tell the world (via the event bus) that we received a request// Let's tell the world (via the event bus) that we received a request EventBus eb = vertx.eventBus();EventBus eb = vertx.eventBus(); eb.publish( "com.geekcap.vertxexamples.Server.announcements", "We received a request for resource: " + req.path() );.publish( "com.geekcap.vertxexamples.Server.announcements", "We received a request for resource: " + req.path() ); }} }).listen(8080);}).listen(8080); }} }}

清單4執行deployVerticle()來部署AuditVerticle。所述deployVerticle()方法部署一個標準Verticle到容器上,它保持它本身的事件循環。處理傳入的HTTP請求(如清單1所示)以後,清單4將消息發佈到事件總線。第一,它得到經過接入到事件總線vertx實例變量的話,就執行eventBus()方法。一旦有EventBus對象將調用其發佈方法,這是一個發佈/訂閱的時尚門戶發佈的消息。

消息鬆耦合

在過去的三年裏,我以事件驅動的架構工做過,並且我發現,發佈/訂閱消息,有時也被稱爲topic,是一個偉大的方式,以鬆散耦合的系統。信息發佈者不須要知道他們的用戶,因此新用戶能夠在任什麼時候候加入不影響發行人。

清單5顯示了源代碼AuditVerticle類。

清單5. AuditVerticle.java

package com.geekcap.vertxexamples; com.geekcap.vertxexamples; import org.vertx.java.core.Handler;import org.vertx.java.core.Handler; import org.vertx.java.core.eventbus.EventBus;import org.vertx.java.core.eventbus.EventBus; import org.vertx.java.core.eventbus.Message;import org.vertx.java.core.eventbus.Message; import org.vertx.java.core.logging.Logger;import org.vertx.java.core.logging.Logger; import org.vertx.java.platform.Verticle;import org.vertx.java.platform.Verticle; public class AuditVerticle extends Verticle {public class AuditVerticle extends Verticle { @Override@Override public void start() {public void start() { // Let's register ourselves as a listener to Server notifications// Let's register ourselves as a listener to Server notifications EventBus eb = vertx.eventBus();EventBus eb = vertx.eventBus(); Handler<Message> auditHandler = new Handler<Message>() {Handler<Message> auditHandler = new Handler<Message>() { @Override@Override public void handle(Message message) {public void handle(Message message) { Logger logger = container.logger();Logger logger = container.logger(); logger.info( "AuditVerticle here, someone requested resource: " + message.body() );.info( "AuditVerticle here, someone requested resource: " + message.body() ); }} };}; eb.registerHandler( "com.geekcap.vertxexamples.Server.announcements", auditHandler );.registerHandler( "com.geekcap.vertxexamples.Server.announcements", auditHandler ); }} }}

該AuditVerticle清單5的行爲很像一個報告引擎:它監聽來自「announcements」 server類,而後寫出來的那些做爲信息的日誌信息。若是感興趣的東西在發生服務器類,它能夠將它發佈到其announcements的topic,不一樣的用戶能夠作不一樣的事情,好比記錄的消息或在Hadoop集羣中供之後分析插入。

清單5而後建立一個處理程序在線實例(建立一個匿名內部類,並分配給一個變量,而無需建立一個單獨的文件中的類)記錄消息。接着,註冊一個處理程序的「com.geekcap.vertxexamples.Server.announcements經過調用」地址EventBus的registerHandler()方法。如今,在任什麼時候候服務器類將消息發佈到該目的地,AuditHandler的handle()方法將被調用。

點 - 點通訊實例

當要僅由單個消費者或做爲機構組件相互異步通訊進行處理的消息的點至點的消息時使用,也能夠。在這一節中,我經過建立依賴於一個worker verticle作的工做是一個新的類演示了後者,而後該worker verticle通訊的結果返回給服務器2。

清單6顯示了源代碼Server2類。

清單6. Server2.java

package com.geekcap.vertxexamples; com.geekcap.vertxexamples; import org.vertx.java.core.Handler;import org.vertx.java.core.Handler; import org.vertx.java.core.eventbus.EventBus;import org.vertx.java.core.eventbus.EventBus; import org.vertx.java.core.eventbus.Message;import org.vertx.java.core.eventbus.Message; import org.vertx.java.core.http.HttpServerRequest;import org.vertx.java.core.http.HttpServerRequest; import org.vertx.java.core.logging.Logger;import org.vertx.java.core.logging.Logger; import org.vertx.java.deploy.Verticle;import org.vertx.java.deploy.Verticle; import java.util.concurrent.ConcurrentMap;import java.util.concurrent.ConcurrentMap; public class Server2 extends Verticle {public class Server2 extends Verticle { public void start() {public void start() { // Create our dependent verticles// Create our dependent verticles container.deployWorkerVerticle("com.geekcap.vertxexamples.MyWorkerVerticle");.deployWorkerVerticle("com.geekcap.vertxexamples.MyWorkerVerticle"); // Start a server that handles things with point-to-point messaging// Start a server that handles things with point-to-point messaging vertx.createHttpServer().requestHandler(new Handler<HttpServerRequest>() {.createHttpServer().requestHandler(new Handler<HttpServerRequest>() { @Override@Override public void handle(final HttpServerRequest req) {public void handle(final HttpServerRequest req) { // Set a shared variable// Set a shared variable ConcurrentMap<String, String> map = vertx.sharedData().getMap("mymap");ConcurrentMap<String, String> map = vertx.sharedData().getMap("mymap"); map.put("mykey", "myvalue");.put("mykey", "myvalue"); // Let's send a message to a worker verticle and wait for it to respond// Let's send a message to a worker verticle and wait for it to respond EventBus eb = vertx.eventBus();EventBus eb = vertx.eventBus(); eb.send("request.worker", req.path, new Handler<Message<String>>() {.send("request.worker", req.path, new Handler<Message<String>>() { @Override@Override public void handle(Message<String> message) {public void handle(Message<String> message) { Logger logger = container.getLogger();Logger logger = container.getLogger(); logger.info( "Received a reply from our worker: " + message.body );.info( "Received a reply from our worker: " + message.body ); req.response.headers().put("Content-Length", Integer.toString(message.body.length()));.response.headers().put("Content-Length", Integer.toString(message.body.length())); req.response.write(message.body);.response.write(message.body); }} });}); }} }).listen(8080);}).listen(8080); }} }}

該Server2類經過部署一個工人verticle開始。worker verticles是 從在它們不包含事件外表和預期由事件總線消息來觸發標準verticles不一樣。worker verticles由得到訪問Vert.x部署容器並調用其deployWorkerVerticle()方法。

接着,Server2得到訪問EventBus經過調用,再次eventBus()的方法vertx實例變量。此時的Server2調用的send()方法,它是通往在點對點方式發送消息。在這種狀況下,將請求發送路徑到一個命名爲「request.worker 」。到的第一個參數的send()方法是目的地,第二個參數是數據發送到目的地,和一個可選的第三個參數是一個處理程序可以由消息的接收者被回調。

該MyWorkerVerticle,這是清單7所示,旨在構建指定的請求路徑的響應和發送響應返回給Server2上的處理程序。該處理程序記錄的響應,而後寫入該響應返回給HttpServerRequest發起的動做。咱們可以寫回以前HttpServerRequest咱們須要指定HTTP 內容長度的響應,這是咱們返回的字符串只是長度。

另外兩個Vert.x的功能被添加到Server2類:

  • 日誌記錄:該容器變量命名的方法getLogger()提供了訪問Vert.x的記錄。此記錄是很是類似的log4j的,並提供了方法,如debug() ,info() ,和fatal()記錄在不一樣的日誌記錄級別的消息。默認狀況下,日誌信息將被回顯到標準輸出和將被寫入一個文件名 爲vertx.log位於TMPDIR -defined目錄。

  • 共享數據:verticles之間共享數據是經過執行sharedData()的方法來實現vertx實例,而後調用的共享數據訪問方法之一。在清單4中,咱們存儲在數據MAP是經過調用檢索的GetMap() ; 你一樣能夠找回共享數據的設置經過調用GETSET() 。全部在Vert.x實例verticles的訪問使用相同的模式相同的共享數據,因此它是爲你verticles之間共享不可變數據的一種方式。

清單7顯示了源代碼MyWorkerVerticle類。

清單7. MyWorkerVerticle.java

package com.geekcap.vertxexamples; import org.vertx.java.core.Handler; import org.vertx.java.core.eventbus.EventBus; import org.vertx.java.core.eventbus.Message; import org.vertx.java.core.logging.Logger; import org.vertx.java.platform.Verticle; import java.util.concurrent.ConcurrentMap; public class MyWorkerVerticle extends Verticle { @Override public void start() { // Register a listener EventBus eb = vertx.eventBus(); Handler<Message> workerHandler = new Handler<Message>() { @Override public void handle(Message message) { Logger logger = container.logger(); logger.info( "MyWorkerVerticle just received a request for: " + message.body() ); // Examine our shared map ConcurrentMap<String, String> map = vertx.sharedData().getMap("mymap"); logger.info( "Shared data: " + map.get( "mykey" ) ); message.reply( "<html><head><title>Worker Response</title></head><body>Hello, from the worker verticle</body></html>" ); } }; eb.registerHandler( "request.worker", workerHandler ); } } 

該MyWorkerVerticle類建立一個新的處理程序與實例handle()從處理消息的方法Server2的類。從清單6中的傳遞給一個參數召回的send()方法是一個處理程序,能夠經過郵件收件人調用實例。清單7調用message.reply() ,它發送一個響應返回給始發者(在該示例中是服務器2的處理程序)。

該MyWorkerVerticle類得到訪問EventBus,而後註冊其處理程序以偵聽發送到「request.worker」目標的消息,以完成循環。

至於功能性,MyWorkerVerticle簡單地構造一個HTML文檔,並返回它回到Server2類。能夠經過鏈接到一個數據庫或讀取數據從另外一個服務器以檢索與該創建響應中的數據創建在這個例子。

並且你會發現,MyWorkerVerticle從檢索共享數據vertx的sharedData()map。

結論

隨着企業系統的複雜演變,融合已經成爲了軟件開發人員的編程最大的挑戰之一。Vert.x解決一體化的幾種方法複雜:首先,它是圍繞一個事件總線,鬆散的耦合verticles同時支持多種編程語言構建的。無論代碼是用Java編寫的,ruby,python,或JavaScript,能夠無縫經過Vert.x事件車內集成。此外,該事件總線自己支持異步消息和事件驅動架構,它產生的高可擴展性和鬆耦合。

本文展現Vert.x,其獨特的語言,那它結合打造高度可擴展的企業級解決方案的核心組件的概述。我展現兩個web服務器和寫入Vert.x一個消息傳送系統中,採用後者的例子來開發一種發佈/訂閱消息和點至點的消息的解決方案。在後者的例子中,我還證實事件記錄,共享數據,以及標準和worker verticles之間的差別。雖然這篇文章介紹中,我談到了一些,說明Vert.x,相似的Node.js,但它主要功能是創建在JVM的一個解決方案。我但願啓發你,更多地瞭解Vert.x,它解決了類型的編程挑戰。

轉自:https://www.cnblogs.com/miaoqing/p/5584360.html

相關文章
相關標籤/搜索