【问题标题】:Scala server with Spray Akka overthreading具有 Spray Akka 超线程的 Scala 服务器
【发布时间】:2016-06-19 23:29:42
【问题描述】:

我在我的 freebsd 1CPU/2GB 服务器上使用 spray.io 和 akka.io,我正面临着 线程问题。当我得到 OutOfMemory 异常时,我已经开始注意到它 因为“无法创建本机线程”。

我经常查看Thread.activeCount(),我发现它增长巨大。 目前我使用这些设置:

myapp-namespace-akka {
  akka {
    loggers = ["akka.event.Logging$DefaultLogger"]
    loglevel = "DEBUG"
    stdout-loglevel = "DEBUG"

    actor {
      deployment {
        default {
          dispatcher = "nio-dispatcher"
          router = "round-robin"
          nr-of-instances = 1
        }
      }

      debug {
        receive = on
        autoreceive = on
        lifecycle = on
      }

      nio-dispatcher {
        type = "Dispatcher"
        executor = "fork-join-executor"

        fork-join-executor {
          parallelism-min = 8
          parallelism-factor = 1.0
          parallelism-max = 16
          task-peeking-mode = "FIFO"
        }

        shutdown-timeout = 4s
        throughput = 4
        throughput-deadline-time = 0ms
        attempt-teamwork = off
        mailbox-requirement = ""
      }

      aside-dispatcher {
        type = "Dispatcher"
        executor = "fork-join-executor"

        fork-join-executor {
          parallelism-min = 8
          parallelism-factor = 1.0
          parallelism-max = 32
          task-peeking-mode = "FIFO"
        }

        shutdown-timeout = 4s
        throughput = 4
        throughput-deadline-time = 0ms
        attempt-teamwork = on
        mailbox-requirement = ""
      }
    }
  }
}

我希望nio-dispatcher 成为我的默认非阻塞(比如说单线程) 调度员。我在aside-dispatcher 上执行我所有的未来(数据库、网络查询)。

我通过我的应用程序获取我的上下文,如下所示:

trait Contexts {
  def system: ActorSystem
  def nio: ExecutionContext
  def aside: ExecutionContext
}

object Contexts {
  val Scope = "myapp-namespace-akka"
}

class ContextsImpl(settings: Config) extends Contexts {
  val System = "myapp-namespace-akka"
  val NioDispatcher = "akka.actor.nio-dispatcher"
  val AsideDispatcher = "akka.actor.aside-dispatcher"
  val Settings = settings.getConfig(Contexts.Scope)

  override val system: ActorSystem = ActorSystem(System, Settings)
  override val nio: ExecutionContext = system.dispatchers.lookup(NioDispatcher)
  override val aside: ExecutionContext = system.dispatchers.lookup(AsideDispatcher)
}

// Spray trait mixed to service actors
trait ImplicitAsideContext {
  this: EnvActor =>
  implicit val aside = env.contexts.aside
}

我认为我确实搞砸了配置或实现。帮帮我。 通常我现在在我的应用程序上看到数千个线程,直到它崩溃(我设置 freebsd 预处理限制为 5000)。

【问题讨论】:

    标签: java multithreading scala akka spray


    【解决方案1】:

    如果您的应用确实启动了这么多线程,这通常可以追溯到 ForkJoinPools 中的阻塞行为(做坏事!),我在这里的答案中详细解释了这个问题:blocking blocks,所以您可能想要在那里阅读它并验证在您的应用程序中创建了哪些线程以及原因 - ForkJoinPool 没有静态上限。

    【讨论】:

    • 但是为什么默认 ForkJoinPool(例如在 PlayFramework 中),如果我有主要的 I/O 阻塞逻辑,比 ThreadPool 有什么优势?
    • 它是所有操作的 default 池,它应该是响应式的 - 例如所有参与者,除非您为他们指定不同的调度程序。应该对阻塞进行管理,而不仅仅是空手而归,说一切都在阻塞:-)
    猜你喜欢
    • 2015-09-15
    • 1970-01-01
    • 2016-04-24
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多