2017-03-08 2 views
1

Ich bin neu in Vert.x und ich möchte mehrere verticles durch jar ausführen. Ich habe zwei Dateien, eine ist MyFirstVertice.java und es leitet den Pfad "/ q1/" und etwas zurück. Die zweite ist MySecondVertice.java, die den Pfad "/ q2/" leitet. Der zweite Scheitelpunkt wird im ersten Scheitelpunkt bereitgestellt.Wie mehrere Vertices in Vert.x ausgeführt werden?

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()); 
     } 
    }); 
} 

}

Mein 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> 

Ich führe es durch java -jar xxx-fat.jar.

Wenn ich localhost: 8080/q1/xxx in den Browser eintippe, kann der gewünschte Inhalt zurückgegeben werden. Aber wenn ich versuche, localhost zu besuchen: 8080/q2/xxx, sagt es "Ressource nicht gefunden". Kannst du mir sagen, wie man zwei Verticles einsetzt, die unterschiedliche Wege leiten? Ich weiß, dass ich verschiedene Pathes in demselben Verticle routen kann, ich möchte nur wissen, wie man mehrere Vertices einsetzt und ausführt. Danke im Voraus!

+1

scheint wie eine schlechte Design-Idee. Sie können mehrere Routen auf demselben Router mit verschiedenen Handlern haben.Sie benötigen wirklich nur einen Web-Service-Verticle, nicht zwei.Sie können den Vert.x-Parameter "-instanzen #" verwenden, um mehrere Verticles des gleichen Web-Server-Verticle zu starten, wenn Sie möchten die Last etwas verteilen – Quintium

Antwort

4

Das Problem, das Sie haben, ist, dass beide Verticles versuchen, an denselben Port ( 8080) zu binden, was Sie nicht tun können. So die zweite Verticle ist wahrscheinlich werfen BindException und nicht zu kommen. Die erste Verticle hat dann keine Ressource bei /q2 weshalb Sie die Resource Not Found bekommen.

per Kommentar von tsegismont Aktualisiert:

Vert.x mehrere Verticles erlaubt auf dem gleichen Port in einem Feature als server sharing bekannt zu starten. Wenn dies geschieht, verwendet Vert.x eine Round-Robin-Strategie, um Anfragen nacheinander an jede Verticle zu senden. Sie sollten also 50% der Anfragen für /q1 und 50% der Anfrage für /q2 sehen. Aber - wie von segismond bemerkt, verwendet Ihr Browser persistent connections, so dass er eine Verbindung zu einem einzigen Verticle aufrecht erhält. Sie sollten feststellen, dass die Verwendung von Curl oder ein anderer Browser Ihnen ein besseres Ergebnis liefern kann. Wie auch immer, das ist wahrscheinlich nicht das, was Sie wollen.

Sie sollten denken, wenn Sie 2 Verticles benötigen. Im Allgemeinen möchten Sie an eine Verticle als Einstiegspunkt in Ihre Anwendung denken - es ist ein Weg bootstrapping Ihre Anwendung/Microservice.

Wenn Sie wirklich 2 Verticles benötigen, dann müssen Sie separate Ports wählen oder auf separaten Boxen laufen. Wenn nicht, dann erstellen Sie einfach 2 routes auf demselben router.

Siehe http://vertx.io/docs/vertx-web/java/ für weitere Informationen auf Vert.x Web

+0

Wenn zwei verticles einen Server für den gleichen Port starten, wird der Datenverkehr zwischen ihnen balanciert. Keine 'BindException'. Der Grund, warum @di-Luo nach dem Die erste Anforderung ist, dass Browser persistente Verbindungen verwenden, so dass der Datenverkehr immer noch zur ersten verticle geht url, sollten Sie sehen, dass die eine Hälfte der Anfragen bei 404 fehlschlägt und die andere Hälfte die zweite verticle erreicht. Ansonsten sieht deine Antwort gut für mich aus. – tsegismont

+0

@tsegismont Ja du bist sehr richtig - mein Fehler. Ich habe den Load-Balancing immer nur ausnutzen können, indem ich das gleiche "Verticle" mehrmals gestartet habe, also habe ich nicht darüber nachgedacht. Ich werde meine Antwort entsprechend aktualisieren – Will

0

Es ist nicht ganz klar, was Sie erreichen wollen, aber auch so kann man nicht zwei HTTP-Server an denselben Port gebunden laufen - oder praktisch alles.

Sie müssen verschiedene Ports für Ihren Ansatz angeben, oder - und das ist der Ansatz, den ich am meisten mag - haben Sie nur einen HTTP-Server und "spawnen mehrere Instanzen" davon. Sie können mehr darüber lesen here.

Für Ihren Fall können Sie sicher MySecondVetice.java löschen; Update MyFirstVertice.java und den /q2/* Endpunkt (und Handler dafür). Dann müssen Sie einige Änderungen tun (n), wenn Sie es einsetzen (Sie nicht den Code haben, setzt MyFirstVertice.java so werde ich „improvisiert“ in dieser Sache:

@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(); 
     } 
    }); 
    } 
} 
Verwandte Themen