Spray.io:何时(不)使用非阻塞路由处理?

2024-01-01

如果我们正在考虑生产级 REST API,我们是否应该尽可能使用非阻塞,例如

def insertDbAsync(rows: RowList): Future[Unit] = ...
...
val route =
path("database" / "insertRowList") {
  post {
    entity(as[RowList]) { rows =>
      log.info(s"${rows.length} rows received")
      val async = insertDbAsync(rows)
      onComplete(async) {
        case Success(response) =>
          complete("success")
        case Failure(t) =>
          complete("error")
      }
    }
  }
}

我认为答案很可能是“是”,但是在决定什么应该和不应该是阻止代码时有哪些指导原则,为什么?


Spray 使用 Akka 作为底层平台,因此建议与 actor 相同(阻塞需要仔细管理 http://doc.akka.io/docs/akka/snapshot/general/actor-systems.html)。阻塞代码可能需要太多线程,这可能:

  • 杀死actor的轻量性:默认情况下,数百万个actor可能在一个线程上运行。例如,假设一个非阻塞参与者需要 0.001 个线程。一个被阻塞的 Actor(阻塞时间比平时多 100 倍)将平均占用 1 个线程(并不总是相同的线程)。首先,拥有的线程越多,释放的内存就越多,每个被阻塞的线程都保存在阻塞之前分配的完整调用堆栈,包括堆栈中的引用(因此 GC 无法删除它们)。其次,如果你有超过number_of_processors线程 - 你会失去性能。第三,如果您使用一些动态池 - 添加新线程可能会花费大量时间。

  • 导致线程饥饿 - 您可能有一个充满线程的池,这些线程什么也不做 - 因此在阻塞操作完成之前无法处理新任务(0%CPU负载,但有100500条消息等待处理)。甚至可能会导致死锁。然而,Akka 默认使用 Fork-Join-Pool,所以如果你的阻塞代码被管理(用scala.concurrent.blocking - Await.result内部有这样的环境) - 它将通过创建新线程而不是阻塞线程的成本来防止饥饿,但它不会弥补其他问题。

  • 传统上会导致死锁,因此不利于设计

如果代码被外部阻塞,你可以用 future 包围它:

 import scala.concurrent._
 val f = Future {
     someNonBlockingCode()
     blocking { //mark this thread as "blocked" so fork-join-pool may create another one to compensate
        someBlocking()
     }  
 }

里面单独的演员:

 f pipeTo sender //will send the result to `sender` actor

内部喷涂路线:

 onComplete(f) { .. }

最好在单独的池/调度程序(基于 fork-join-pool)内执行此类 future。

附:作为 futures 的替代方案(从设计角度来看它们可能不太方便),您可以考虑Akka I/O http://doc.akka.io/docs/akka/2.0/scala/io.html, 继续/协程 http://jim-mcbeath.blogspot.com/2010/09/scala-coroutines.html, 演员的pools http://doc.akka.io/docs/akka/snapshot/scala/routing.html(也在单独的调度程序内)、Disruptor 等。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spray.io:何时(不)使用非阻塞路由处理? 的相关文章

  • Scala 工作表在 Intellij 中不起作用

    我有 Intellij IDEA 13 1 2 已编辑 之前为 13 0 2 我使用 scala 插件 我正在尝试使用工作表来评估代码 但我得到的只是两个错误 bad macro impl binding versionFormat is
  • 如何删除spark输出中的compactbuffer

    下面是我在spark shell中运行的程序 但是当我将输出保存在HDFS中时 我得到带有compactbuffer的输出 如何删除spark输出中的compactbuffer Program val a sc textFile datag
  • Scala [2.11.6] 编译 Stackoverflow 错误(似乎对迄今为止发现的建议有抵抗力)

    scala版本 2 11 6 我当然尝试过clean很多次以及update 不确定是否有clean deeper刷新 jar 库 真正奇怪的是 这种情况同时发生在两台机器上 其中一台在没有执行任何特殊操作的情况下恢复了 而另一台仍然没有恢复
  • Spark 对 RDD 中按值排序

    我有一个火花对 RDD 键 计数 如下 Array String Int Array a 1 b 2 c 1 d 3 使用spark scala API如何获取按值排序的新RDD对 所需结果 Array d 3 b 2 a 1 c 1 这应
  • 避免函数内装箱/拆箱

    对于数字密集型代码 我编写了一个具有以下签名的函数 def update f Int Int Double gt Double Unit 然而 因为Function3不是专门的 每个应用程序f结果对 3 个参数和结果类型进行装箱 拆箱 我可
  • 在 Scala 中设计方便的默认值映射

    我发现自己使用了很多嵌套映射 例如 Map Int Map String Set String 并且我希望在访问新密钥时自动创建新的 Map Set 等 例如 像下面这样 val m m 1992 foo bar 请注意 如果不需要 我不想
  • collect_list() 是否保持行的相对顺序?

    想象一下我有以下 DataFrame df id featureName featureValue id1 a 3 id1 b 4 id2 a 2 id2 c 5 id3 d 9 想象一下我运行 df groupBy id agg coll
  • Scala+Slick 3:将一个查询的结果插入到另一张表中

    这个问题是关于 slick 3 0 或 3 1 的 我对此很灵活 我有一个中间查询 我用它来处理map for等等以获得我想要的结果 最后我有一个 val foo DBIOAction Seq MySchema Bar NoStream E
  • 组合多个任意长度的列表

    我正在寻找一种通过以下方式加入多个列表的方法 ListA a b c ListB 1 2 3 4 ListC Resulting List a 1 b 2 c 3 4 换句话说 元素按顺序排列 从第一个列表开始组合到结果列表中 任意数量的输
  • kafka ProducerRecord 和 KeyedMessage 有什么区别

    我正在衡量卡夫卡生产者生产者的表现 目前我遇到了两个配置和用法略有不同的客户 Common def buildKafkaConfig hosts String port Int Properties val props new Proper
  • 在 Java 中使用 Scala 常量

    我目前正在评估 Scala 的未来项目 并发现了一些奇怪的事情 我在 JSP 中为我们创建了以下常量 val FORMATED TIME formatedTime 但这没有用 经过一番尝试后 我决定反编译以了解其真相 private fin
  • Scala 函数定义参数列表中不同的括号样式

    Scala 中以下两个函数定义有什么区别 1 def sum f Int gt Int a Int b Int Int code 2 def sum f Int gt Int a Int b Int Int code SBT 的控制台 RE
  • 帮助我理解这段 Scala 代码:scalaz IO Monad 和隐式

    这是后续this https stackoverflow com questions 7404495 help me understand this scala code scalaz io monad问题 这是我试图理解的代码 它来自ht
  • 对列表中的相邻元素进行分组

    假设我想编写一个函数来执行此操作 输入 1 1 3 3 4 2 2 5 6 6 输出 1 1 3 3 4 2 2 5 6 6 它将相同的相邻元素分组 这个方法的名称应该是什么 此操作有标准名称吗 In 1 1 3 3 4 2 2 5 6 6
  • Akka/Scala:映射 Future 与 pipelineTo

    In Akka参与者 在发送一个Future结果给另一个演员 A 映射Future发挥作用tell结果给演员 B 定义一个onSuccess未来的回调 其中tell结果给演员 C 管道Future结果给演员pipeTo 其中一些选项已在上一
  • 为什么我不能将 Scala 的 Function1 隐式转换为 java.util.function.Function?

    我正在尝试创建 Scala Function1 到 java util function Function 的隐式转换 这是我的代码 object Java8ToScala extends App implicit def javaFunc
  • 具有动态命名参数的 Scala 案例类副本

    对于具有参数数量的 scala 案例类 21 e g case class Car type String brand String door Int 其中类型 吉普车 品牌 丰田 门 4 etc 还有一个复制方法允许使用命名参数覆盖 Ca
  • Scala:需要类类型,但找到了 T

    我发现了与此特定问题类似的问题 但是该问题是由于有人试图直接实例化 T 造成的 在这里 我试图创建一个特征 它是一个通用接口来扩展类并将它们自动存储在数据库中 例如 Riak 使用classOf T 使用 Scala 2 10 这是我的代码
  • 在 Spark 中将流式 XML 转换为 JSON

    我是 Spark 新手 正在开发一个简单的应用程序 将从 Kafka 接收的 XML 流转换为 JSON 格式 Using 火花2 4 5 斯卡拉 2 11 12 在我的用例中 kafka 流采用 xml 格式 以下是我尝试过的代码 val
  • akka http配置中的idle-timeout和request timeout有什么区别?

    我查阅了文档并发现了这些 空闲连接自动关闭的时间 设置infinite完全禁用空闲连接超时 空闲超时 10 秒 Defines the default time period within which the application has

随机推荐

  • 如何隐藏

    我试图隐藏这些 p p
  • Lollipop 的应用程序兼容性、兼容性和支持库(如果最低 SDK = 14)

    我们有一个现有的 Android 应用程序 支持 API 级别 8 至 18 我们使用兼容性库 19 1 0 现在我们正在更改 升级为 最低 SDK 14 目标 android 22 现在考虑到不同版本都有 v4 v7 v13 支持 兼容性
  • ResolveEventArgs.RequestingAssembly 为 Null

    我正在尝试通过反射动态加载程序集 我有这样的文件夹结构 project BIN myApp exe SOMEEXTENTION1 someExtention1 dll itsDependency1 dll SOMEEXTENTION2 so
  • R 以编程方式更改 IP 地址

    目前通过将不同的字符串传递给来更改 user agenthtml session method 还有一种方法可以在抓取网站时更改计时器上的 IP 地址吗 您可以通过以下方式使用代理 它会更改您的IP use proxy如下 html ses
  • Cucumber + 测试 JS 警报

    我正在尝试使用 Cucumber on Rails 测试 JS 确认对话框 我有一个 window onbeforeunload 事件处理程序 如果您尝试离开该页面 它会提示您一个确认对话框 但我不知道如何测试它 有人知道如何做到这一点吗
  • 我可以使用最新的稳定 TypeScript 还是应该坚持使用 AngularCLI 附带的版本?

    我找不到任何关于是否使用可用的最新稳定版本升级 TypeScript 版本的官方建议 npm 版本自动设置在package json创建新项目时通过 AngularCLI 目前是 typescript 2 4 2 这意味着最新的2 4 x版
  • 在单个 ROC 图上绘制线性判别分析、分类树和朴素贝叶斯曲线

    数据显示在页面的最底部 称为 LDA scores 这是一个分类任务 我在数据集上执行了三种监督机器学习分类技术 提供所有编码以显示这些 ROC 曲线是如何生成的 我很抱歉提出了一个有问题的问题 但近两周来我一直在尝试使用不同的代码组合来解
  • 如何合并多个 BIRT 报告

    我们目前拥有一整套报告设计 涵盖了我们应用程序的各个部分 并且这些报告是根据用户的需求生成的 我希望能够将其中几个报告捆绑成一个报告以返回给用户 我最初破解了一个自定义报告生成器 它使用报告库文件中的段生成报告设计文件 然后运行生成的设计
  • 在 PERL 中从 Windows 访问 Microsoft SQL Server

    我正在使用 SQL Server 驱动程序 但这是我得到的以下错误 DBI connect Driver SQL Server database host cartertest failed Microsoft ODBC Driver Ma
  • 如何使用另一个模块的反应式数据帧更新闪亮模块

    该模块的目标是创建一个根据数据选择器模块的输出而变化的反应性条形图 不幸的是 条形图没有更新 它停留在选定的第一个变量上 我尝试创建观察者函数来更新条形图 但无济于事 我还尝试将选择器服务器模块嵌套在 barplot 模块中 但出现错误 警
  • 装配性能调整

    我正在编写一个编译器 更多的是为了好玩 但我想尝试使其尽可能高效 例如 我被告知在英特尔架构上使用除EAX执行数学运算会产生成本 大概是因为它交换为EAX进行实际的数学计算 这里至少有一个来源说明了这种可能性 http www swanso
  • MediaTek 处理器上的双精度值计算错误

    我发现我在市场上发布的一款应用程序在某些手机上产生了奇怪的结果 经过调查发现 一个计算两个地理点之间距离的函数存在问题 有时它会返回完全错误的值 此问题仅在具有以下功能的设备上重现联发科MT6589 http www mediatek co
  • localstorage - 保存数组[重复]

    这个问题在这里已经有答案了 我有本地存储 可以保存输入并将它们推送到列表中 现在我想将列表保存在本地存储中 因为当我重新加载列表时 列表会重置var fav new Array 在此开头定义jsFiddle http jsfiddle ne
  • 如何在 java 中解组 ruby​​ 对象?

    我有一个对象 我想用java获取它的内容 唯一的问题是目前在 ruby 中 irb main 050 0 gt blah gt BAh7ByIeYXV0aGVudGljYXRpb25fc3RyYXRlZ2llczAiCXVzZXJpBg 2
  • AVAudioEngine 在 iOS14 中获取 inputNode 属性崩溃

    这是一个启动audioEngine的函数 void startAudioEngine NSError error nil if self audioEngine isRunning self audioEngine AVAudioEngin
  • Python 装饰器有哪些常见用途? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 虽然我喜欢将自己视为一名相当有能力的 Python 程序员 但我从未理解过的语言的一个方面是装饰器 我知道它们是什么 表面上 我读过 St
  • 如何使用 Sublime Text 3 配置 MinGW?

    我最近安装了 MinGW 并且一直试图让它与 Sublime Text 3 一起使用 以便在编译脚本时打开 cmd 但是没有任何效果 当我去工具 gt 构建系统 gt 新构建系统并保存此脚本 我不断收到错误 C 不被识别为内部或外部命令 可
  • C 中数组索引减去字符意味着什么?

    include
  • 将多个控件放入更新面板的正确方法是什么?

    我有一份注册表单 其中包含 3 到 4 个下拉控件和 2 个日期选择器 现在当选择下拉控件值时 触发 selectedindex 更改 那么我不希望我的页面回发 我已经使用更新面板来停止这种帖子行为 如下所示
  • Spray.io:何时(不)使用非阻塞路由处理?

    如果我们正在考虑生产级 REST API 我们是否应该尽可能使用非阻塞 例如 def insertDbAsync rows RowList Future Unit val route path database insertRowList