require 'celluloid' 需要很长时间才能加载

require 'celluloid' takes a long time to load

我在 Google 计算引擎上部署了一个 JRuby 应用程序。我注意到加载 celluloid gem 需要一段时间。在查看更多细节后,我发现加载 celluloid/internals/stack 需要更多时间。

通常需要 2 分钟以上。有一次加载它甚至需要大约 41 分钟。服务器配置良好,15Gb RAM 和 4 核。

JAVA版本

java version "1.8.0_74"
Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)

JRUBY 版本

jruby 9.0.5.0 (2.2.3) 2016-01-26 7bee00d Java HotSpot(TM) 64-Bit Server VM 25.74-b02 on 1.8.0_74-b02 +jit [linux-amd64]


当我尝试使用 ruby 时,它会快速加载 celluloid

安装 haveged 以在虚拟机上更快地补充熵。

您可能没有足够的熵来生成从 SecureRandom 中提取的 UUID,在 jRuby 下很容易用完随机性。特别是在虚拟机上。所以你的虚拟机实际上是在等待更多的随机性成为可能。 haveged 通过收集新的熵来帮助补充快速闪电般的随机性。

正在安装...

下载:http://www.issihosts.com/haveged/downloads.html

在类似 Debian 的 Linux 风格下,如 Mint 和 Ubuntu,这就完成了:

sudo apt-get install haveged

这是 SecureRandomjRuby 下的一个已知问题 ...

我以前也遇到过这个问题,不得不用strace定位问题。请注意这个文件,它是您在问题中提到的行之前加载的文件... internals/uuid.rb:

require "securerandom"

module Celluloid
  module Internals
    # Clearly Ruby doesn't have enough UUID libraries
    # This one aims to be fast and simple with good support for multiple threads
    # If there's a better UUID library I can use with similar multithreaded
    # performance, I certainly wouldn't mind using a gem for this!
    module UUID
      values = SecureRandom.hex(9).match(/(.{8})(.{4})(.{3})(.{3})/)
      PREFIX = "#{values[1]}-#{values[2]}-4#{values[3]}-8#{values[4]}".freeze

      #de ...
    end
  end
end

那是有问题的代码,因为它生成一个 9 十六进制数字字符串,它可以用作 UUID 代码的前缀...使用 SecureRandom

然后,通过 Celluloid::Internals::UUID.generate 方法使用它。但是在加载时,Celluloid::Internals::UUID 模块执行需要 SecureRandom 的操作...... jRuby 遇到了麻烦: