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


如果你對Node.js感興趣,Vert.x可能是你的下一個大事件:一個建立在JVM上一個類似的架構企業制度。 這一部分介紹Vert.x是通過兩個動手的例子(基於Vert.x 2.0)。

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

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

Vert.x亮點

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

在Vert.x基於事件的編程

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

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

  • 一個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將永遠不會被同時執行,所以要他們保持在最低水平,但他們在那里幫助你,當你需要他們,在這種情況下,將由后台執行的線程池執行。

圖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,它解決了類型的編程挑戰。h


免責聲明!

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



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