2017-03-08 22 views
1

我是Vert.x的新手,我想通過jar運行多個Verticle。我有兩個文件,一個是MyFirstVertice.java,它路由路徑「/ q1/」並返回一些內容。第二個是路由「/ q2/」的MySecondVertice.java。第二個頂點被部署在第一個頂點。如何在Vert.x中運行多個頂點?

MyFirstVertice.java

public class MyFirstVerticle extends AbstractVerticle { 
@Override 
public void start(Future<Void> fut) throws Exception { 

    HttpServer server = vertx.createHttpServer(); 
    Router router = Router.router(vertx); 
    router.route("/q1/*").handler(routingContext -> { 
     HttpServerRequest request = routingContext.request(); 
     String Y = request.getParam("key"); 
     String cipherText = request.getParam("message"); 

     HttpServerResponse response = routingContext.response(); 

     response.setChunked(true); 
     response.putHeader("content-type", "text/plain"); 
     response.write(Y + "\n"); 
     response.write(cipherText + "\n"); 
     response.end(); 

     vertx.deployVerticle(new MySecondVerticle(), stringAsyncResult -> { 
      System.out.println("Second verticle is deployed successfully."); 
     }); 
    }); 

    server.requestHandler(router::accept).listen(8080, httpServerAsyncResult -> { 
     if (httpServerAsyncResult.succeeded()) { 
      fut.complete(); 
     } else { 
      fut.fail(httpServerAsyncResult.cause()); 
     } 
    }); 
} 

}

MySecondVetice.java

public class MySecondVerticle extends AbstractVerticle { 
@Override 
public void start(Future<Void> fut) throws Exception { 

    HttpServer server = vertx.createHttpServer(); 
    Router router = Router.router(vertx); 
    router.route("/q2/*").handler(routingContext -> { 
     HttpServerResponse response = routingContext.response(); 
     response.setChunked(true); 
     response.putHeader("content-type", "text/plain"); 

     response.end("q2"); 
    }); 

    server.requestHandler(router::accept).listen(8080, httpServerAsyncResult -> { 
     if (httpServerAsyncResult.succeeded()) { 
      fut.complete(); 
     } else { 
      fut.fail(httpServerAsyncResult.cause()); 
     } 
    }); 
} 

}

我的pom.xml

<plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-shade-plugin</artifactId> 
      <version>2.3</version> 
      <executions> 
       <execution> 
        <phase>package</phase> 
        <goals> 
         <goal>shade</goal> 
        </goals> 
        <configuration> 
         <transformers> 
          <transformer 
            implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> 
           <manifestEntries> 
            <Main-Class>io.vertx.core.Starter</Main-Class> 
            <Main-Verticle>tutorial.diluo.MyFirstVerticle</Main-Verticle> 
           </manifestEntries> 
          </transformer> 
         </transformers> 
         <artifactSet/> 
         <outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jar</outputFile> 
        </configuration> 
       </execution> 
      </executions> 
     </plugin> 

我運行它通過java -jar xxx-fat.jar

當我在瀏覽器中輸入localhost:8080/q1/xxx時,它可以返回所需的內容。但是當我嘗試訪問localhost:8080/q2/xxx時,它會顯示「未找到資源」。你能告訴我如何部署兩個不同路徑的Verticle嗎?我知道我可以在同一個Verticle中路由不同的pathe,我只想知道如何部署和運行多個頂點。提前致謝!

+1

似乎是一個糟糕的設計理念。您可以在同一個路由器上的多個路線,不同的處理程序。你真的只需要一個Web服務Verticle,而不是兩個。您可以使用Vert.x參數「-instances#」開始在同一Web服務器Verticle如果多個Verticles你想分散負載一些。 – Quintium

回答

4

您遇到的問題是 Verticles正試圖綁定到您無法做到的同一端口( 8080)。 所以第二個 Verticle很可能會拋出一個 BindException並未能出現。第一個 Verticle然後,在 /q2沒有資源,這就是爲什麼你得到 Resource Not Found

更新按照評論從tsegismont:

Vert.x允許多個Verticles在被稱爲server sharing功能開始在同一端口上。發生這種情況時,Vert.x將使用循環策略輪流向每個Verticle發送請求。因此,您應該看到/q1的50%的請求以及/q2的請求的50%。但是 - 正如tsegismont指出的那樣,您的瀏覽器使用persistent connections,因此它保持與單個Verticle的連接。你會發現使用curl或其他瀏覽器可能會給你一個更好的結果。無論哪種方式,這可能不是你想要的。

如果您需要2 Verticles,您應該有一個想法。一般而言,您想將Verticle作爲您的應用程序的入口點 - 這是您的應用程序/微服務的一種方式bootstrapping

如果你真的需要2 Verticles那麼你將不得不選擇單獨的端口或運行在單獨的盒子上。如果你不這樣做,那就在同一個router上創建2 routes

更多信息,請參見http://vertx.io/docs/vertx-web/java/Vert.x Web

+0

其實,如果兩個verticles啓動服務器的同一端口,交通將負載它們之間的平衡。沒有'BindException'。爲什麼@二羅沒有看到後什麼原因第一個請求是瀏覽器使用持久性連接,所以流量仍然會流向第一個verticle,如果你對c做同樣的處理url,你會看到一半請求失敗,404,另一半到達第二個verticle。除此之外,你的回答對我來說很好。 – tsegismont

+0

@tsegismont是的,你是非常正確的 - 我的錯誤。我只用了多次啓動相同的'Verticle'來利用負載平衡,所以沒有考慮它。我會相應地更新我的答案 – Will

0

這不是很清楚你想要達到的目標,但即便如此,你不能運行綁定到同一端口兩個HTTP服務器 - 或者幾乎任何東西。

您需要爲您的方法聲明不同的端口,或者 - 和這是我喜歡most-只有一個HTTP服務器和它的「重生多個實例」的做法。你可以閱讀更多關於它here

對於你的情況,你可以安全地刪除MySecondVetice.java;更新MyFirstVertice.java和包括/q2/*端點(和處理它)。然後,你需要做一些修改(S),當你部署它(你沒有這樣的部署MyFirstVertice.java所以我會「即興」在得知此事代碼:

@Slf4j 
public final class Application extends AbstractVerticle { 
    @Override 
    public void start(final Future<Void> startFuture) { 
    deploy(MyFirstVertice.class, new DeploymentOptions().setInstances(4)); 
    LOGGER.info("Module(s) and/or verticle(s) deployment...DONE"); 
    //startFuture.complete(); 
    } 

    @Override 
    public void stop(final Future<Void> stopFuture) { 
    LOGGER.debug("Undeploying verticle(s)...DONE"); 
    LOGGER.info("Application stopped successfully. Enjoy the elevator music while we're offline..."); 
    stopFuture.complete(); 
    } 

    private void deploy(final Class<? extends AbstractVerticle> clazz, final DeploymentOptions options) { 
    vertx.deployVerticle(clazz.getName(), options, handler -> { 
     if (handler.succeeded()) { 
     LOGGER.debug("{} started successfully (deployment identifier: {})", clazz.getSimpleName(), handler.result()); 
     } else { 
     LOGGER.error("{} deployment failed due to: ", clazz.getSimpleName(), handler.cause()); 
     //stop(); 
     } 
    }); 
    } 
} 
相關問題