如何部署线程安全的异步 Rails 应用程序?

2024-02-19

我在网上阅读了大量有关不同版本的 Ruby 和 Rails 中的线程安全和性能的材料,我想我现在已经很好地理解了这些内容。

奇怪的是,讨论中似乎缺少的是如何实际部署异步 Rails 应用程序。当谈论应用程序中的线程和同步性时,人们想要优化两件事:

  1. 以最少的 RAM 使用量利用所有 CPU 核心
  2. 能够在之前的请求等待 IO 的同时处理新请求

第 1 点是人们对 JRuby 感到(正确地)兴奋的地方。对于这个问题我只是想优化第2点。

假设这是我的应用程序中唯一的控制器:

class TheController < ActionController::Base
  def fast
    render :text => "hello"
  end

  def slow
    render :text => User.count.to_s
  end
end

fast没有 IO,每秒可以处理数百或数千个请求,并且slow必须通过网络发送请求,等待工作完成,然后通过网络接收答案,因此比fast.

因此,理想的部署将允许数百个请求fast在请求时得到满足slow正在等待 IO。

网络上的讨论似乎缺少的是堆栈的哪一层负责实现这种并发性。薄有一个--threaded标志,它将“在线程中调用机架应用程序[实验]”——这是否会为每个传入请求启动一个新线程?在持续存在并等待传入​​请求的线程中缓冲机架应用程序实例?

瘦身是唯一的方法还是还有其他方法? ruby 运行时对于优化第 2 点重要吗?


适合您的方法在很大程度上取决于您的能力slow方法正在做。

在完美的世界中,您可以使用类似的东西sinatra 同步 https://github.com/kyledrake/sinatra-synchronygem 处理 Fiber 中的每个请求。您只会受到最大光纤数量的限制。不幸的是,纤维上的堆叠尺寸是硬编码的 http://bugs.ruby-lang.org/issues/3187,并且在 Rails 应用程序中很容易出现溢出。此外,我读过一些关于调试光纤的困难的恐怖故事,因为异步 IO 启动后会自动让步。使用纤维时,竞争条件仍然是可能的。目前,纤维化 Ruby 有点贫民窟,至少在 Web 应用程序的前端是如此。

不需要更改代码的更实用的解决方案是使用具有工作线程池(例如 Rainbows)的机架服务器!或彪马。我相信薄的--threadedflag 在新线程中处理每个请求,但启动本机操作系统线程并不便宜。最好使用池大小设置足够高的线程池。在 Rails 中,不要忘记设置config.threadsafe!在生产中。

如果您同意更改代码,您可以查看 Konstantin Haase 的优秀文章在实时 Rack 上交谈 http://confreaks.net/videos/727-rockymtnruby2011-real-time-rack。他讨论了使用EventMachine::Deferrable类在 Rack 构建的传统请求/响应周期之外生成响应。这看起来确实很简洁,但是您必须以异步风格重写代码。

还看一下Cramp http://cramp.in/ and Goliath http://postrank-labs.github.com/goliath/。这些可以让您实施您的slow方法在与 Rails 应用程序一起托管的单独 Rack 应用程序中,但您可能需要重写代码才能在 Cramp/Goliath 处理程序中工作。

至于你关于 Ruby 运行时的问题,这也取决于slow是在做。如果您正在进行 CPU 密集型计算,那么您将面临 GIL 出现问题的风险。如果你正在做 IO,那么 GIL不应该妨碍你。 (我说不应该是因为我相信我已经读过有关旧版 mysql gem 阻塞 GIL 的问题。)

就我个人而言,我已经成功地将 sinatra-synchrony 用于后端混搭 Web 服务。我可以并行向外部 Web 服务发出多个请求,并等待所有请求返回。同时,前端Rails服务器使用线程池,直接向后端发出请求。并不完美,但现在已经足够好了。

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

如何部署线程安全的异步 Rails 应用程序? 的相关文章

  • JavaFX Platform.runLater 的使用以及从不同线程访问 UI

    我有几个问题Platform runLater 我有一个 JavaFX 应用程序类 在这个类中 我运行一个线程 该线程从网络套接字读取数据 现在当我创建一个新的Stage在线程内部 系统抛出异常 JavaFX 事件调度程序线程和我的网络读取
  • ruby中如何将binary32转换为float

    我有一个以 IEEE 32 编码的 binary32 如何将 0x0040EDC2 转换为 118 625 我尝试了几种打包和解包选项 但没有成功 IEEE http en wikipedia org wiki Single precisi
  • 如何在其他核心上运行每个线程?

    我有一个 udp 服务器接收数据并计算它 每个角色我都有两个线程 我的CPU是8个多核 我以不同的速度发送数据 但最多我只使用了 cpu 两核 50 的 14 如果我发送更多的数据值 我的缓冲区将填满并且不会使用更多的CPU 为什么每个核心
  • 使用 AJAX 或多线程加速页面加载

    我的页面有 5 个部分 每个部分大约需要 1 秒来渲染 Page Load RenderSection1 1 sec RenderSection2 1 sec RenderSection3 1 sec RenderSection4 1 se
  • Java:使用 Java.util.concurrent 线程访问读取线程串行端口

    我正在尝试编写一个 Java 串行设备驱动程序并想使用 对我来说是新的 java util concurrent包裹 我有一种发送数据包然后等待 ACK 的方法 我打算有炭 接收在不同的线程中运行 如果接收线程收到 ACK 它应该使用发送数
  • 保护 REST 和 JSON

    我想利用 RESTful 架构构建提供 JSON 数据的 Web 服务 但我只想要我自己的客户端应用程序可以从我的网络服务请求 基本上 我的 Web 服务包含不供公众使用的敏感数据 但我想以这种方式构建它 以便我可以构建连接到我的 Web
  • ubuntu 12.04 ruby​​ 2.0 Rails:找不到“thread_safe”

    我正在 ubuntu 12 04 上安装 Rails 使用以下方法手动安装 如何在 Ubuntu 12 04 上正确安装 ruby 2 0 0 https stackoverflow com questions 16222738 how t
  • Rails 中的助手 - 构建 html 字符串时的最佳方法是什么?

    我通常这样写助手 def bloco vazio texto btn args titulo content tag h3 Vazio p content tag p texto content tag div titulo tag hr
  • 添加两个 ActiveRecord::Relation 对象[重复]

    这个问题在这里已经有答案了 如何将两个关系添加在一起 当我尝试 运算符时 它返回一个数组 但我需要它来返回关系 谢谢 麦克风 Try new relation relation merge another relation
  • 由于 MIME 类型不受支持,拒绝应用样式

    我不断收到一条错误消息 指出 MIME 类型 text html 不可执行或不是受支持的样式表 MIME 类型 并且启用了严格的 MIME 检查 我的链接代码是
  • 如何从数组中提取特定元素?

    如果我有一个数组a 1 2 3 4 5 6 7 8 9 10 我想要这个数组的一个子集 第 1 个 第 5 个和第 7 个元素 是否可以通过简单的方式从该数组中提取这些内容 我在想这样的事情 a 0 4 6 1 5 7 但这行不通 还有一种
  • Linux/POSIX:为什么 fork() 不分叉*所有*线程

    众所周知 POSIX下创建新进程的默认方式是使用fork 在 Linux 下 这在内部映射到clone 我想知道的是 众所周知 当一个人打电话时fork 子进程是用单个线程创建的 调用的线程fork cf https linux die n
  • 自动加载常量时检测到循环依赖

    我将 Rails 从版本 3 1 2 运行良好 升级到 4 0 并遇到以下错误 circular dependency detected while autoloading constant Foo 我创建了一个类ProductFactor
  • 将一幅图像合成到另一幅图像上时,RMagick 透明度不起作用

    在下面的代码中 我尝试在一些山脉的图像上覆盖一个透明的正方形 我认为它会起作用 但是通过设置background color none 它不会使图像透明 结果是左上角有一个黑色方块 所需的结果是黑色方块应该是透明的 require open
  • 我应该如何使用 alias_method_chain 作为构建方法?

    我正在使用 Ruby on Rails 3 2 13 我想正确使用alias method chain build option name声明 因为我收到一个奇怪的错误 那是 在我的控制器文件中我有 class Articles Comme
  • 更改 Active Storage 的默认 URL

    我们可以更改从活动存储创建的默认 永久 url 以重定向到 S3 类似于rails active storage representations 我不喜欢网址中的框架名称 Thanks UPDATE 最近 Rails 6 中增加了一个可配置
  • 在生产环境中使用 Rails 设置 sunspot solr

    我尝试了各种链接 但我似乎找不到关于创建与生产中的 Rails 一起运行的 solr 实例的好资源 我知道您必须为生产设置 solr 服务器 我已经尝试使用 tomcat 设置 solr 但我似乎无法将其链接到 Rails 应用程序 有什么
  • 无法在 Sqlite3 中添加默认值为 NULL 的 NOT NULL 列

    尝试将 NOT NULL 列添加到现有表时出现以下错误 为什么会发生这种情况 我尝试了 rake db reset 认为现有记录是问题所在 但即使重置数据库后 问题仍然存在 你能帮我解决这个问题吗 迁移文件 class AddDivisio
  • 如何在 iPhone 上使用带有线程的 sqlite + fdbm 库

    相关这个问题 https stackoverflow com questions 1082554 我想把数据加载放在后台 但是 我收到 库例程调用不按顺序 错误 In 这个所以线程 https stackoverflow com quest
  • 将记录批量插入到 Active Record 表中

    我发现我的Model create 当我一次添加大量记录时 语句需要很长时间才能运行 看着ActiveRecord 导入 https github com zdennis activerecord import wiki但它不适用于哈希数组

随机推荐

  • 打包时Maven NumberFormatException

    在项目上运行 mvn package 或 mvn install deploy 时 我在 Windows PC 上遇到非常奇怪的错误 此错误仅发生在本机上 在我的笔记本电脑和其他计算机上一切正常 我曾经能够毫无问题地打包 安装项目 但现在甚
  • 从 TableViewCell 中删除 imageView 子层

    当我有图像时 我使用 CAGradientLayer 插入子图层 layer name Gradient cell imageView layer insertSublayer layer atIndex 0 当 ImageView 没有图
  • 没有 jQuery 的粘性侧边栏 javascript

    如何制作带有塞子的粘性垂直侧边栏 但是withoutjQuery 有没有任何片段 插件 我不需要它来支持旧版浏览器 我的意思不仅仅是位置 固定 它必须保持在同一个位置 然后当您滚动超过某个点时开始粘性 固定 然后它必须在停止点停止跟随 Li
  • Java:在线纸牌游戏库/类/例如[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找在线纸牌游戏的java示例解决方案 库 类 我有兴趣创建一个名为 非盈利 的游戏版本 千 h
  • iOS 项目的单元测试 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我对于 iOS 开发还是比较陌生的 对于任何类型的测试 除了编译 运行和检查你想到的任何东西 之外的测
  • 当表单操作属性为“#”(数字/井号/符号/字符)时,这意味着什么?

    当表格出现时 这意味着什么action属性是 数字 井号 符号 字符 当表单输入时会发生什么formaction属性设置为 这是否会阻止输入被提交到服务器
  • 用按位运算替换最低有效位

    用提供的位替换字节的最低有效位的最佳方法是什么 我知道如何检查和比较最后一位 例如使用 posix ffs 函数 但我想知道是否有性能更好的解决方案 而不检查替换位是 0 还是 1 该示例是用 python 伪代码编写的 但我将用 C 实现
  • web3.js如何搜索所有曾经创建的合约并查看地址

    我是 web3 js 和 Solidity 的新手 我的问题与我们在区块链上搜索的方式有关 如果我们知道合约地址 就很容易搜索特定合约 然而 我们如何使用最初用于创建合约的地址来查找和识别特定类型的合约 例如 我有一个合同 Contract
  • OSX Game Center:无法与帮助应用程序通信

    I m setting up Game Center for my OSX game but it can t authenticate player with the following error OSX 10 10 Yosemite
  • 计算页面大小和段大小

    在分页分段系统中 我们有32位的虚拟地址和12位的偏移量 11位的段和9位的页号 我们如何计算页面大小 最大段大小和最大段数 保留 12 位用于偏移量 因此页面大小为 2 12 4KB 9 位保留用于页号 因此每个段可以包含 2 9 512
  • 绘制具有颜色渐变的矩阵“光谱图”

    使用 STFT 短时傅立叶变换 后 输出是一个表示 3d 图的矩阵 就像 A X Y M A是输出矩阵 X是时间 Y是频率 第三维M是由像素颜色强度表示的幅度 如下图所示 频谱图2 https i stack imgur com mtWqb
  • 使用 Caret 在 R 中创建 k 折 CV 的折叠

    我正在尝试使用以下位置提供的数据为几种分类方法 hiperparameters 制作 k 折 CVhttp archive ics uci edu ml machine learning databases undocumented con
  • 如何知道ios中UIKeyboard上按下了哪个键? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我正在实现一个 iPad 应用程序
  • R中PRROC包的精确召回曲线计算

    我的问题与this https stackoverflow com questions 25020788 in r calculate area under precision recall curve aupr问题 我对计算精确召回曲线
  • 将 JAR 添加到 IntelliJ 中的 WEB-INF/lib 目录中的正确步骤是什么

    假设我有一个 Java Web 项目 我需要将几个 JAR 放入 WEB INF lib 目录中 在 Eclipse 中 如果您只是将这些 JAR 放在那里 Eclipse 就会像在类路径上一样拾取它们 然而 IntelliJ 似乎没有 将
  • 从 Python 类获取所有 @properties [重复]

    这个问题在这里已经有答案了 在Python中 我怎样才能得到所有特性一个类的所有成员 即由该类创建的所有成员 property装饰师 There are at least two questions 1 2 on stackoverflow
  • 计算与谓词匹配的元素数量的惯用方法是什么?

    除了这个之外 是否有更好的方法来计算谓词函数为 true 的元素数量 PredCount lst pred Length Select lst pred 我问这个问题是因为构建一个子集似乎效率低下lst with Select 并且因为Co
  • 将作曲家 1 和 2 保留在同一台机器上

    我们如何在同一台机器上使用 Composer 1 和 Composer 2 作为一名开发人员 我们在同一台机器上处理多个项目 并且项目 1 需要 Composer 1 项目 2 需要 compower 版本 2 这就是我曾经在同一台机器上安
  • 为什么我不能在 MySQL 中使用特定的排序规则?

    我有一个包含字符集的表latin1 通过检查show variables like character set database 和默认排序规则latin1 swedish ci 通过检查SHOW TABLE STATUS 我想使用排序规则
  • 如何部署线程安全的异步 Rails 应用程序?

    我在网上阅读了大量有关不同版本的 Ruby 和 Rails 中的线程安全和性能的材料 我想我现在已经很好地理解了这些内容 奇怪的是 讨论中似乎缺少的是如何实际部署异步 Rails 应用程序 当谈论应用程序中的线程和同步性时 人们想要优化两件