单个 JVM 中的多个 Spark 服务器
Multiple Spark servers in a single JVM
有什么方法可以在同一个 JVM 中 运行 多个 Sparkjava 服务器实例?我在 "plugin" 软件中使用它,根据外部环境,我的插件的多个实例可能会启动,然后导致
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
。
诀窍是忽略 spark.Spark
中实现的 Spark 周围的外部静态 shell 并直接使用内部 spark.webserver.SparkServer
。代码中存在一些需要解决方法的障碍,例如spark.webserver.JettyHandler
不是 public,因此您无法从您的代码中实例化它,但您可以将自己的 class 放入该包中并将其转换为 public 来扩展它。
所以解决方案是这样的:
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 服务器,这似乎是一个可行的解决方法。
从 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)
}
我建议阅读 ,我认为它在这里很有用。
我有这个问题 运行 使用 Spark 进行单元测试,为了修复它,我修改了 pom.xml
文件。
forkCount=1
reuseForks=false
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire.version}</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>${junit.platform.version}</version>
</dependency>
</dependencies>
<configuration>
<forkCount>1</forkCount>
<reuseForks>false</reuseForks>
有什么方法可以在同一个 JVM 中 运行 多个 Sparkjava 服务器实例?我在 "plugin" 软件中使用它,根据外部环境,我的插件的多个实例可能会启动,然后导致
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
。
诀窍是忽略 spark.Spark
中实现的 Spark 周围的外部静态 shell 并直接使用内部 spark.webserver.SparkServer
。代码中存在一些需要解决方法的障碍,例如spark.webserver.JettyHandler
不是 public,因此您无法从您的代码中实例化它,但您可以将自己的 class 放入该包中并将其转换为 public 来扩展它。
所以解决方案是这样的:
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 服务器,这似乎是一个可行的解决方法。
从 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)
}
我建议阅读
我有这个问题 运行 使用 Spark 进行单元测试,为了修复它,我修改了 pom.xml
文件。
forkCount=1
reuseForks=false
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire.version}</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>${junit.platform.version}</version>
</dependency>
</dependencies>
<configuration>
<forkCount>1</forkCount>
<reuseForks>false</reuseForks>