2017-01-03 2 views
5

Gibt es eine Möglichkeit, mehrere Instanzen des Sparkjava-Servers in derselben JVM auszuführen? Ich benutze es in einer „Plugin“ Software und basiert auf äußeren Umständen mehrere Instanzen mein Plugin werden bis könnte gestartet, die dannMehrere Spark-Server in einer einzelnen JVM

java.lang.IllegalStateException: This must be done before route mapping has begun 
at spark.SparkBase.throwBeforeRouteMappingException(SparkBase.java:256) 
at spark.SparkBase.port(SparkBase.java:101) 
at com.foo.bar.a(SourceFile:59) 

verursachen Es scheint mir, durch Blick auf den Code, dass es stark um statische gebaut Felder im Code, also denke ich über einen Classloader-Trick nach oder arbeite mit SparkServerFactory irgendwie Beseitigung SparkBase.

+0

Wahrscheinlich verwenden diese Instanzen die gleiche Portnummer. Wenn Sie eine Spark-Instanz starten, muss sie auf ihrem eigenen Port ausgeführt werden. –

+1

Nein, dies geschieht, wenn Sie versuchen, eine zweite Instanz zu initialisieren, unabhängig davon, ob der Port identisch ist oder nicht. Bei der ersten Initialisierung wird ein Flag auf "true" gesetzt und ab diesem Zeitpunkt werden die meisten Konfigurationsmethoden gesperrt. – jabal

+0

Ich hatte das gleiche Problem beim Ausführen von Integrationstests mit sparkjava. Stellen Sie als Workaround sicher, dass forkCount = 1/reuseForks = false gesetzt ist, damit das maven failsafe-Plugin jede Testklasse in einem eigenen JVM-Prozess ausführt (siehe http://maven.apache.org/surefire/maven-surefire-plugin/examples/). fork-options-and-parallel-execution.html) – asmaier

Antwort

4

Vom Funken 2.5 können Sie ignite() verwenden:

http://sparkjava.com/news.html#spark25released

Beispiel:

public static void main(String[] args) { 
    igniteFirstSpark(); 
    igniteSecondSpark(); 
} 

static void igniteSecondSpark() { 
    Service http = ignite(); 

    http.get("/basicHello", (q, a) -> "Hello from port 4567!"); 
} 

static void igniteFirstSpark() { 
    Service http = ignite() 
         .port(8080) 
         .threadPool(20); 

    http.get("/configuredHello", (q, a) -> "Hello from port 8080!"); 
} 

ich sie persönlich so etwas wie dies initialisieren:

import spark.Service 

public static void main(String[] args) { 
    Service service1 = Service.ignite().port(8080).threadPool(20) 
    Service service2 = Service.ignite().port(8081).threadPool(10) 
} 

Ich empfehle zu lesen how to use those services outside your main method, die ich denke, wäre hier von großem Nutzen.

1

Der Trick besteht darin, die externe statische Shell um Spark zu ignorieren, die in spark.Spark implementiert ist und direkt mit dem internen spark.webserver.SparkServer arbeitet. Es gibt einige Hindernisse im Code, die eine Problemumgehung erfordern, z. spark.webserver.JettyHandler ist nicht öffentlich, Sie können es also nicht aus Ihrem Code instanziieren, aber Sie können es mit Ihrer eigenen Klasse erweitern und es öffentlich machen.

So ist die Lösung in dieser Richtung:

SimpleRouteMatcher routeMatcher1 = new SimpleRouteMatcher(); 
routeMatcher1.parseValidateAddRoute("get '/foo'", "*/*", wrap("/foo", "*/*", (req, res) -> "Hello World 1")); 

MatcherFilter matcherFilter1 = new MatcherFilter(routeMatcher1, false, false); 
matcherFilter1.init(null); 
PublicJettyHandler handler1 = new PublicJettyHandler(matcherFilter1); 
SparkServer server1 = new SparkServer(handler1); 

new Thread(() -> { 
      server1.ignite("0.0.0.0", 4567, null, null, null, null, "/META-INF/resources/", null, new CountDownLatch(1), 
        -1, -1, -1); 
     }).start(); 

und brauchen die Wickelmethode in Ihrem Code-Basis zu duplizieren:

protected RouteImpl wrap(final String path, String acceptType, final Route route) { 
     if (acceptType == null) { 
      acceptType = "*/*"; 
     } 
     RouteImpl impl = new RouteImpl(path, acceptType) { 
      @Override 
      public Object handle(Request request, Response response) throws Exception { 
       return route.handle(request, response); 
      } 
     }; 
     return impl; 
    } 

Dieses eine tragfähige Abhilfe zu sein scheint, wenn Sie mehrere Spark-Server benötigen in deiner App

Verwandte Themen