我应该如何在Apache Ignite服务中嵌入Jetty服务器?

时间:2017-10-17 06:37:37

标签: scala jetty microservices embedded-jetty ignite

我试图在Apache Ignite服务中嵌入Jetty服务器(根据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$2.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中是否需要以不同的方式配置某些内容才能使其正常工作?

2 个答案:

答案 0 :(得分:2)

您应该在init方法中实例化jetty Server类,因为它将在服务部署后立即在目标计算机上调用。在构造函数中实例化Server类是没用的 - 在创建Service实例后(在大多数情况下可以在其他节点上执行),此实例将被序列化并添加到内部缓存中,并且只有在目标机器上启动它之后。

我认为很清楚Jetty Server对象无法正确序列化。例如,无法完成ThreadPool的序列化,因为Thread实现包含本机代码块。

答案 1 :(得分:0)

我只是想出来了,但我会把它留给其他有同样问题的人。

事实证明,您无法在构造函数中实例化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")
    }
}