2017-01-03 18 views
5

同一のJVMで複数のSparkjavaサーバインスタンスを実行する方法はありますか?私はそれはそれは大きく静的を中心に構築されていることを、コードを見て、私には思える単一の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) 

を引き起こす私のプラグインの複数のインスタンスが起動されるかもしれない外部の状況に基づいて、「プラグイン」ソフトウェアでそれを使用していますフィールドのコードでは、私はクラスローダーのトリックやSparkServerFactoryとどういうわけかSparkBaseを取り除くことを考えています。

+0

これらのインスタンスは同じポート番号を使用しています。 sparkインスタンスを起動するときには、それ自身のポートで実行する必要があります –

+1

いいえ、ポートが同じであるかどうかにかかわらず、2番目のインスタンスを初期化しようとすると発生します。最初の初期化ではフラグがtrueに設定され、ほとんどの設定メソッドのそのポイントからはロックダウンされます。 – jabal

+0

sparkjavaとの統合テストを実行するときに同じ問題が発生しました。回避策として、Mavenフェールセーフプラグインが独自のJVMプロセスで各テストクラスを実行するためには、forkCount = 1/reuseForks = falseを設定してください(http://maven.apache.org/surefire/maven-surefire-plugin/examples/を参照)。 fork-options-and-parallel-execution.html) – asmaier

答えて

4

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

例:

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!"); 
} 

私は個人的にそれらを初期化し、このような何か:私は約読むことをお勧めします

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

how to use those services outside your main method、これはIここでは大いに役立つと思う。

1

このトリックは、spark.Sparkで実装されたSparkの外部静的シェルを無視して、内部でspark.webserver.SparkServerと直接動作することです。回避策が必要なコードにはいくつかの障害があります。 spark.webserver.JettyHandlerはパブリックではないので、コードからインスタンス化することはできませんが、自分のクラスをそのパッケージに配置してパブリックにすることができます。

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

そして、あなたのコードベースにラップ方式を複製する必要があります:

だから、解決策は、これらの線に沿っている

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

あなたは、複数のスパークのサーバーを必要とする場合、これは実行可能な回避策のようですあなたのアプリで。あなたがignite()を使用することができスパーク2.5から

関連する問題