java—单个jvm中的多个spark服务器

dwthyt8l  于 2021-07-09  发布在  Java
关注(0)|答案(3)|浏览(417)

有没有办法在同一个jvm中运行sparkjava服务器的多个示例?我在一个“插件”软件中使用它,基于外部环境,我的插件的多个示例可能会启动,然后导致

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 .

xsuvu9jc

xsuvu9jc1#

诀窍是忽略在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();

需要在代码库中复制wrap方法:

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

如果你的应用程序中需要多个spark服务器,这似乎是一个可行的解决方法。

mctunoxg

mctunoxg2#

我用spark运行单元测试时遇到了这个问题,为了解决这个问题,我修改了 pom.xml 文件。 forkCount=1 reuseForks=false ```

org.apache.maven.plugins
maven-surefire-plugin
${surefire.version}


org.junit.platform
junit-platform-surefire-provider
${junit.platform.version}



1
false

ifsvaxew

ifsvaxew3#

从spark 2.5你可以使用 ignite() :
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)
}

我建议您阅读有关如何在main方法之外使用这些服务的内容,我认为这在这里会很有用。

相关问题