ruby,openssl,unicorn,systemd(Gcloud)非常奇怪的行为

时间:2018-02-28 18:01:35

标签: ruby openssl unicorn systemd init.d

我们开始在日志中看到一些奇怪的错误,这些错误通常在使用OpenSSL未正确编译ruby时出现。但它不一致 ......

我们遇到的错误如下:

  • char[] replacements = new char[Character.MAX_VALUE]; boolean[] removals = new boolean[Character.MAX_VALUE]; // fill these arrays // like replacements['ł'] = 'l'; public String replaceSpecialBulgarianCharacters(String str) { char[] s = str.toCharArray(); StringBuilder sb = new StringBuilder(s.length); for (int index = 0; index < s.length; index++) { char c = s[index]; if (!removals[c]) { sb.append(replacements[c]); } } return sb.toString(); } (还有其他摘要,如RuntimeError: Unsupported digest algorithm (SHA256).)。 example error trace
  • sha1 example error trace

我们设法在使用Faraday::SSLError (SSL_CTX_new: (null))service unicorn start启动独角兽时重现它。但只有一些请求...不是全部。一些使用OpenSSL的请求确实有效。其他人没有。

然而,当我们使用systemctl start unicorn启动独角兽时,一切都顺利进行。(澄清一下,systemd启动相同的/etc/init.d/unicorn start脚本)

我们尝试调试/etc/init.d vars,用户权限,文件/目录所有权,重新编译ruby,从头开始引导新服务器......似乎没什么用。

如果这有帮助:

我们缺少什么?我们还能想到什么呢?

更新1

更新2

我们正在为VM使用脚本化/可重复的构建过程(使用结构),这个问题在我们在 GCloud 上引导的多个VM上是一致的。然后我们使用相同的引导脚本在 DigitalOcean 上尝试了一个虚拟机,问题似乎没有出现在那里。

在这两种情况下,我们选择了Ubuntu 16.04 64位基本映像,但显然内核版本,基本安装包等存在一些差异......

更新3

问题根本就消失了。请参阅下面的答案。

3 个答案:

答案 0 :(得分:2)

@gingerlime我在GCP上使用我们的Jenkins时遇到了类似的情况,我们使用的是ChefDK 3.1.0(红宝石嵌入了2.5.1p57)-也对运行在SELECT `id`, JSON_PRETTY(`goods`) FROM `packet_code` WHERE JSON_SEARCH( `goods`, 'all', 'S87719300077661', NULL, '$[*].code') IS NOT NULL; 上的Jenkins进行了其他尝试( Ubuntu 16.04)和systemd(Ubuntu 14.04)–我们尝试了这两个版本,目前在upstart内核版本中运行超过16.04,并使用4.15.0-1023-gcp运行了一些作业,并且总是会出现此问题在某些情况下。

我深入研究,发现只有在调用kitchen-docker类(for me here)时才会发生这种情况,这不会返回任何错误,它会返回正确的信息,正确的类类型(Etc.getlogin),但是一旦接到电话,就会String被提出。

如果我由Unsupported digest algorithmroot用户手动启动该过程,则不会发生此问题。我尝试以几种不同的方式实现jenkins,例如使用Etc.getlogin,固定的String或ENV['USER']中的其他类(例如Etc)来模拟返回类和值来自getpwuid,并且不会引发错误。

我不确定这是否与GCP实例使用的ruby版本和自定义内核有关,但它发生在与您类似的情况下,对我来说,Etc.getlogin是问题所在。现在,我通过使用自定义配置进行了修复,该配置无法从该函数获取调用,并且可以正常工作。

答案 1 :(得分:1)

一个选项是,这根本不是sysVinit vs systemd的问题,但您尚未使用sysVinit脚本触发此问题。

当您通过svsVinit命令运行systemctl脚本时,它将通过兼容层,并且可能存在问题。如果您直接使用systemd服务文件重现问题并共享该文件,那么您和我们的问题将会简化。

您提到调试ENV,但没有提到您在ENV中检查的确切内容。这绝对是systemd可以发挥作用的地方。如man systemd.exec中所示,systemd将环境中的$ PATH设置为固定值:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

如果这与直接作为sysVinit脚本直接运行时不完全相同,那可能是个问题。

我还会检查系统上所有的SSL副本。你有不止一个吗?哪里?您是否拥有加载ruby openssl模块的副本?

 locate -r lib/.*libssl.*so

另请参阅常见问题解答的答案:Why do things behave differently under systemd?

答案 2 :(得分:0)

(也发布于this github issue

看起来这个问题就消失了。我们正在Google云上的几个计算引擎实例上一致地测试和再现它。在某些条件下(unicorn / puma由systemd等启动),它可以完全重现我们自己的rails应用程序,以及我们为测试目的设置的普通vanilla rails应用程序。它也可以在几个ruby版本中重现(我们测试了2.3.4,2.3.6和2.5.0)。

突然间,一直失败的所有实例开始工作而没有出现这些问题。喜欢从未存在过。我们甚至没有重新启动其中的一些实例,我们没有看到任何无人值守升级的证据...我们还有一个系统的快照,它有这个问题,我们可以可靠地重现。从这个快照创建一个实例,几个小时前就停止了从该特定时间点开始展示它。

我们完全混淆了可能导致它的原因,以及可能导致它消失的原因......但是,现在不能重现它,我想这个问题没有任何意义,所以关闭它。把它归结为 Deus ex machina 我想。 (也许谷歌支持众神,但他们还没有向我们报告任何事情)