如何在Rails中使用Redis?

Vai*_*ari 3 ruby-on-rails redis ruby-on-rails-5

我想要真正快速的缓存,因此我正在使用Redis。我认为我做错了,因此遇到了问题。

这是我每次使用redis时所做的事情。在我的控制器文件中,user.rb

def online?
  !Redis.new.get("#{self.auth_token}").nil?
end
Run Code Online (Sandbox Code Playgroud)

然后为了检查用户是否在线,我正在使用它,

@users_ol = User.where(:id => @id).select(&:online?)
Run Code Online (Sandbox Code Playgroud)

这将获取我当前在线的所有用户的列表。这在localhost中运行良好,但是在服务器上运行时会中断。

我的问题是

  • 如何调试并知道此问题是否是由Redis引起的?
  • 在Rails中使用Redis的正确方法是什么?
  • Redis是否需要额外配置以使服务器(nginx)在生产中正常工作?

您可以通过回答这些问题的链接发表评论(对我满意)预先感谢

kid*_*ils 7

您正在为每个控制器请求建立Redis连接。这将是一场大规模的灾难。理想情况下,您应该为一个滑轨实例打开一个连接。为此,请创建config/initializers/redis.rb

redis_host = Rails.application.secrets.redis && Rails.application.secrets.redis['host'] || 'localhost'
redis_port = Rails.application.secrets.redis && Rails.application.secrets.redis['port'] || 6379

# The constant below will represent ONE connection, present globally in models, controllers, views etc for the instance. No need to do Redis.new everytime
REDIS = Redis.new(host: redis_host, port: redis_port.to_i)
Run Code Online (Sandbox Code Playgroud)

查看应用程序的秘密部分,有我指定要使用的配置,并露出hostport进行生产和其他环境中自己的秘密。这使我能够根据环境动态控制Redis主机和端口,并在本地回退到localhost:6379(默认)。

def online?
  !Redis.new.get("#{self.auth_token}").nil?
end
Run Code Online (Sandbox Code Playgroud)

应该成为

def online?
  REDIS.get("#{self.auth_token}").present?
end
Run Code Online (Sandbox Code Playgroud)

如何调试并知道此问题是否是由Redis引起的?

查看Rails服务器异常的日志,以了解中断和原因。exception_notification在不同的环境中触发异常时,可以使用gem 来向您发送邮件。

在Rails中使用Redis的正确方法是什么?

请参阅此答案的初始部分。建立一个连接,使用Rails机密或环境变量公开主机,端口。完全取决于设置Redis实例的方式和位置。

Redis是否需要额外配置以使服务器(nginx)在生产中正常工作?

nginx不需要任何特殊的东西。您只需要在应用程序中对其进行配置,并确保能够连接。

  • 是的。使用 redis-rb 或 ioredis gem。您还需要确保您的系统或远程主机中安装了redis,并且端口(默认6379)可访问 (2认同)

mar*_*cks 5

在生产中,我使用 Kubernetes,其中 Redis URL 为redis://redis:6379/0

在我的 Rails 开发环境中,在 Docker 中,Redis URL 也如上,但在我的 Rails on localhost、Docker 外部,Redis URL 是redis://localhost:6379

他接受的答案很好地说明了Redis.new在初始化程序中设置以建立单个连接的观点。

如果您在本地使用 Rails 并在开发环境中的 Docker 中使用,则已接受答案中的解决方案将不起作用。我的解决方案是在我的 config/initializers/redis.rb 文件中使用以下代码:

redis_url = ENV.fetch("REDIS_URL")

REDIS = Redis.new(url: redis_url)
Run Code Online (Sandbox Code Playgroud)

然后在我的控制器中我使用以下代码:

REDIS.incr "page hits"
@page_hits = REDIS.get "page hits"
Run Code Online (Sandbox Code Playgroud)

我使用 .env_fileREDIS_URL在 Docker 和.rbenv-varsRails 应用程序的父目录中设置 REDIS_URL 以在本地主机上运行 Rails。

对于 Kubernetes,我REDIS_URL在文件的环境部分中进行设置rails_deploy.yaml