我需要在我的Rails应用程序中设置与外部服务的连接。我在初始化器中执行此操作。问题是服务库使用线程传递(我需要,因为我不能让它停止请求),但是Unicorn生命周期会导致线程被杀死而工作者永远不会看到它。一种解决方案是在每个请求上调用新连接,但这不必要地浪费。
最佳解决方案是在unicorn配置中的after_fork块中设置连接。问题是不会在独角兽之外调用,这意味着我们无法在开发/测试环境中对其进行测试。
所以问题是,确定Rails应用程序是否在Unicorn(主服务器或工作进程)下运行的最佳方法是什么?
答案 0 :(得分:3)
在Rails中可以访问一个环境变量(我知道它存在于3.0和3.1中),检查env['SERVER_SOFTWARE']
的值。您可以将正则表达式或字符串与该值进行比较,以确定您正在运行的服务器。
我的管理员中有一个模板,它通过env变量并吐出内容。
Unicorn 4.0.1
env['SERVER_SOFTWARE'] => "Unicorn 4.0.1"
rails服务器(webrick)
env['SERVER_SOFTWARE'] => "WEBrick/1.3.1 (Ruby/1.9.3/2011-10-30)"
答案 1 :(得分:3)
您可以检查defined?(Unicorn)
并在Gemfile集中gem :unicorn, require: false
实际上你不需要在你的rails应用程序中加载Unicorn库。
服务器由shell
unicorn
命令启动
答案 2 :(得分:1)
检查Unicorn
常量似乎是一个很好的解决方案,但它在很大程度上取决于require: false
中是否提供了Gemfile
。如果不是(这很可能),检查可能会产生误报。
我以非常直接的方式解决了这个问题:
# `config/unicorn.rb` (or alike):
ENV["UNICORN"] = 1
...
# `config/environments/development.rb` (or alike):
...
# Log to stdout if Web server is Unicorn.
if ENV["UNICORN"].to_i > 0
config.logger = Logger.new(STDOUT)
end
干杯!
答案 3 :(得分:0)
您可以检查Unicorn模块是否已使用Object.constants.include?('Unicorn')
定义。
当然,这对于Unicorn非常具体。更通用的方法是建立一个设置连接的方法,并记住已经完成的连接。如果它被多次调用,它只会在后续调用中返回任何内容。然后在after_fork和应用程序控制器的before_filter中调用该方法。如果它在after_fork中运行,它在before_filter中什么都不做,如果它还没有运行,它会在第一个请求上执行它的操作而在后续请求中没有任何操作。
答案 4 :(得分:0)
内部config/unicorn.rb
将ENV变量定义为
ENV['RAILS_STDOUT_LOG']='1'
worker_processes 3
timeout 90
然后可以在Rails应用工作线程中的任何位置访问此变量ENV['RAILS_STDOUT_LOG']
。
我的问题: 我想在Unicorn工作者上输出所有日志(SQL查询)而不是Heroku上的任何其他工作者,所以我做的是在unicorn配置文件中添加env变量