我应该如何在 Apache Ignite 服务中嵌入 Jetty 服务器?
How should I embed a Jetty server in an Apache Ignite service?
我正在尝试将 Jetty 服务器嵌入到 Apache Ignite 服务中(根据 this thread),这样我就可以将 HTTP 端点作为我的数据管道的入口点。这是我的基本测试:
Main.scala
object Main {
def main(args: Array[String]): Unit = {
val ignite = Ignition.start()
val group = ignite.cluster.forLocal
val services = ignite.services(group)
services.deployNodeSingleton("myTestService", new TestServiceImpl)
}
}
TestService.scala
trait TestService {
def test()
}
class TestServiceImpl extends Service with TestService {
val server = new Server(8090)
def cancel(ctx: ServiceContext) = {
server.stop()
server.join()
}
def init(ctx: ServiceContext) = {
println("TestServiceImpl#init")
}
def execute(ctx: ServiceContext) = {
println("TestServiceImpl#execute")
server.start()
}
def test() = {
println("Tested")
}
}
当我 运行 它时,出现以下错误:
[01:52:57] Ignite node started OK (id=626c1302)
[01:52:57] Topology snapshot [ver=1, servers=1, clients=0, CPUs=8, heap=2.0GB]
TestServiceImpl#init
TestServiceImpl#execute
Oct 17, 2017 1:52:57 AM org.apache.ignite.logger.java.JavaLogger error
SEVERE: Service execution stopped with error [name=myTestService, execId=565f4fb4-5726-4c37-857d-0c74f3b334ce]
java.util.concurrent.RejectedExecutionException: org.eclipse.jetty.util.thread.NonBlockingThread@56a1831d
at org.eclipse.jetty.util.thread.QueuedThreadPool.execute(QueuedThreadPool.java:362)
at org.eclipse.jetty.io.SelectorManager.execute(SelectorManager.java:160)
at org.eclipse.jetty.io.SelectorManager.doStart(SelectorManager.java:258)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
at org.eclipse.jetty.server.AbstractConnector.doStart(AbstractConnector.java:256)
at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:81)
at org.eclipse.jetty.server.ServerConnector.doStart(ServerConnector.java:236)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.server.Server.doStart(Server.java:366)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at me.danellis.ignite.TestServiceImpl.execute(TestService.scala:23)
at org.apache.ignite.internal.processors.service.GridServiceProcessor.run(GridServiceProcessor.java:1160)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:748)
是否需要在 Ignite 或 Jetty 中进行不同的配置才能使其正常工作?
我刚刚弄明白了,但为了其他遇到同样问题的人的利益,我会保留它。
原来你不能在构造函数中实例化 Server
。您必须 在init
方法中进行。 (虽然不知道为什么——也许构造函数运行时线程池还没有设置。)
TestService.scala
class TestServiceImpl extends Service with TestService {
var server: Server = _
def cancel(ctx: ServiceContext) = {
server.stop()
server.join()
}
def init(ctx: ServiceContext) = {
println("TestServiceImpl#init")
server = new Server(8090)
}
def execute(ctx: ServiceContext) = {
println("TestServiceImpl#execute")
server.start()
}
def test() = {
println("Tested")
}
}
您应该在 init 方法中实例化 jetty Server class,因为它会在服务部署后立即在目标机器上调用。在构造函数中实例化 Server class 是没有用的——在创建服务实例之后(大多数情况下可以在其他节点上执行),该实例将被序列化并添加到内部缓存,并且只有在它启动后在目标机器上。
我认为很明显无法正确序列化 jetty Server 对象。例如,无法完成 ThreadPool 的序列化,因为 Thread 实现包含本机代码块。
我正在尝试将 Jetty 服务器嵌入到 Apache Ignite 服务中(根据 this thread),这样我就可以将 HTTP 端点作为我的数据管道的入口点。这是我的基本测试:
Main.scala
object Main {
def main(args: Array[String]): Unit = {
val ignite = Ignition.start()
val group = ignite.cluster.forLocal
val services = ignite.services(group)
services.deployNodeSingleton("myTestService", new TestServiceImpl)
}
}
TestService.scala
trait TestService {
def test()
}
class TestServiceImpl extends Service with TestService {
val server = new Server(8090)
def cancel(ctx: ServiceContext) = {
server.stop()
server.join()
}
def init(ctx: ServiceContext) = {
println("TestServiceImpl#init")
}
def execute(ctx: ServiceContext) = {
println("TestServiceImpl#execute")
server.start()
}
def test() = {
println("Tested")
}
}
当我 运行 它时,出现以下错误:
[01:52:57] Ignite node started OK (id=626c1302)
[01:52:57] Topology snapshot [ver=1, servers=1, clients=0, CPUs=8, heap=2.0GB]
TestServiceImpl#init
TestServiceImpl#execute
Oct 17, 2017 1:52:57 AM org.apache.ignite.logger.java.JavaLogger error
SEVERE: Service execution stopped with error [name=myTestService, execId=565f4fb4-5726-4c37-857d-0c74f3b334ce]
java.util.concurrent.RejectedExecutionException: org.eclipse.jetty.util.thread.NonBlockingThread@56a1831d
at org.eclipse.jetty.util.thread.QueuedThreadPool.execute(QueuedThreadPool.java:362)
at org.eclipse.jetty.io.SelectorManager.execute(SelectorManager.java:160)
at org.eclipse.jetty.io.SelectorManager.doStart(SelectorManager.java:258)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
at org.eclipse.jetty.server.AbstractConnector.doStart(AbstractConnector.java:256)
at org.eclipse.jetty.server.AbstractNetworkConnector.doStart(AbstractNetworkConnector.java:81)
at org.eclipse.jetty.server.ServerConnector.doStart(ServerConnector.java:236)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.server.Server.doStart(Server.java:366)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at me.danellis.ignite.TestServiceImpl.execute(TestService.scala:23)
at org.apache.ignite.internal.processors.service.GridServiceProcessor.run(GridServiceProcessor.java:1160)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:748)
是否需要在 Ignite 或 Jetty 中进行不同的配置才能使其正常工作?
我刚刚弄明白了,但为了其他遇到同样问题的人的利益,我会保留它。
原来你不能在构造函数中实例化 Server
。您必须 在init
方法中进行。 (虽然不知道为什么——也许构造函数运行时线程池还没有设置。)
TestService.scala
class TestServiceImpl extends Service with TestService {
var server: Server = _
def cancel(ctx: ServiceContext) = {
server.stop()
server.join()
}
def init(ctx: ServiceContext) = {
println("TestServiceImpl#init")
server = new Server(8090)
}
def execute(ctx: ServiceContext) = {
println("TestServiceImpl#execute")
server.start()
}
def test() = {
println("Tested")
}
}
您应该在 init 方法中实例化 jetty Server class,因为它会在服务部署后立即在目标机器上调用。在构造函数中实例化 Server class 是没有用的——在创建服务实例之后(大多数情况下可以在其他节点上执行),该实例将被序列化并添加到内部缓存,并且只有在它启动后在目标机器上。
我认为很明显无法正确序列化 jetty Server 对象。例如,无法完成 ThreadPool 的序列化,因为 Thread 实现包含本机代码块。