scala - 如何使用适当的线程池调整 Play Framework 应用程序?

标签 scala playframework-2.3

我正在使用 Play Framework (Scala) 2.3 版。从文档:

You can’t magically turn synchronous IO into asynchronous by wrapping it in a Future. If you can’t change the application’s architecture to avoid blocking operations, at some point that operation will have to be executed, and that thread is going to block. So in addition to enclosing the operation in a Future, it’s necessary to configure it to run in a separate execution context that has been configured with enough threads to deal with the expected concurrency.



这让我对如何调整我的 webapp 有点困惑。具体来说,由于我的应用程序有大量的阻塞调用:JDBC 调用和使用阻塞 SDK 调用 3rd 方服务的混合,配置执行上下文和确定要提供的线程数的策略是什么?我需要一个单独的执行上下文吗?为什么我不能简单地将默认池配置为具有足够数量的线程(如果我这样做,为什么我仍然需要将调用包装在 Future 中?)?

我知道这最终将取决于我的应用程序的具体情况,但我正在寻找有关策略和方法的一些指导。 play 文档到处宣扬非阻塞操作的使用,但实际上,典型的 web 应用程序访问 sql 数据库有很多阻塞调用,我从阅读文档中得到的印象是,这种类型的应用程序的性能远非最佳默认配置。

最佳答案

[...] what is the strategy for configuring the execution context and determining the number of threads to provide



嗯,这是棘手的部分,这取决于您的个人要求。
  • 首先,您可能应该从 docs 中选择一个基本配置文件。 (纯异步、高度同步或许多特定线程池)
  • 第二步是通过分析和基准测试您的应用程序来微调您的设置

  • Do I need a separate execution context?



    不必要。但是,如果您想一次触发所有阻塞 IO 调用而不是按顺序触发,则使用单独的执行上下文是有意义的(因此数据库调用 B 不必等到数据库调用 A 完成)。

    Why can't I simply configure the default pool to have a sufficient amount of threads (and if I do this, why would I still need to wrap the calls in a Future?)?



    您可以,查看 docs :
    play {
      akka {
        akka.loggers = ["akka.event.slf4j.Slf4jLogger"]
        loglevel = WARNING
        actor {
          default-dispatcher = {
            fork-join-executor {
              parallelism-min = 300
              parallelism-max = 300
            }
          }
        }
      }
    }
    

    使用这种方法,您基本上将 Play 变成了一个每请求一个线程的模型。这不是 Play 背后的想法,但如果您正在执行大量阻塞 IO 调用,这是最简单的方法。在这种情况下,您不需要将数据库调用包装在 Future 中。

    简而言之,您基本上有三种方法:
  • 仅使用非阻塞和异步 API 调用的 (IO-) 技术。这允许您使用适合 Play
  • 性质的小型线程池/默认执行上下文。
  • 通过大幅增加默认执行上下文,将 Play 转变为每个请求一个线程的框架。不需要 future ,只需像往常一样调用您的阻塞数据库
  • 为您的阻塞 IO 调用创建特定的执行上下文并获得对您正在执行的操作的细粒度控制
  • 关于scala - 如何使用适当的线程池调整 Play Framework 应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26174220/

    相关文章:

    scala - 如何在scala中对相邻元素求和

    scala - 可从 Futures 观察 - 来自多个线程的 onNext

    scala - 从2.2迁移到2.3 : No implicit view available from Any

    java - Play Framework - 新项目中不存在包

    java - Play 框架使用 Deadbolt 从 2.1.x 迁移到 2.3.0

    scala - 将 java.util.stream.Stream 转换为 Scala Stream

    由于构造函数参数(属性)在基类和派生类中具有相同名称并在派生方法中使用,Scala 编译器错误

    scala - 为什么这不会给出类型错误?

    playframework - 使用 Ebean 和 Play 框架将条件放在列表字段上

    playframework - 转换为 postgres 时出错