如何在Rails中使用Redis?

10
我希望能够使用快速缓存,因此我正在使用 Redis。我认为我的做法不正确,因此遇到了问题。
以下是我每次使用 Redis 时所做的事情。在我的控制器文件 user.rb 中:
def online?
  !Redis.new.get("#{self.auth_token}").nil?
end

那么为了检查用户是否在线,我正在使用以下代码:

@users_ol = User.where(:id => @id).select(&:online?)

这会给我提供当前在线用户列表。在本地主机上运行良好,但在服务器上运行时会出现问题。
我的问题是:
  • 如何调试并知道此问题是否由Redis引起?
  • 在Rails中正确使用Redis的方法是什么?
  • Redis在生产环境中是否需要额外配置才能在服务器(nginx)上正常工作?
您可以通过评论带有回答这些问题的链接(对我来说没问题) 提前感谢。

1
你尝试过按照Rails官方网站的指南操作吗?https://guides.rubyonrails.org/caching_with_rails.html#activesupport-cache-rediscachestore - Ray
2个回答

22

你正在为每个控制器请求建立redis连接。在大规模情况下,这将是一场灾难。理想情况下,您应该为一个rails实例打开一个连接。要做到这一点,请创建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)

请查看应用程序机密部分,我在那里指定要使用的配置,并将生产和其他环境中的hostport暴露出来。这使我能够根据环境动态控制redis主机和端口,并在本地回退为localhost:6379(默认值)。

def online?
  !Redis.new.get("#{self.auth_token}").nil?
end

应该变成

def online?
  REDIS.get("#{self.auth_token}").present?
end

如何调试并确定问题是由Redis引起的?

查看Rails服务器异常日志以查看出错原因。使用像exception_notification这样的gem,在不同的环境中触发异常时发送邮件通知你。

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

参见本答案的开头部分。建立一条连接,使用Rails secrets 或环境变量来公开主机和端口。完全取决于您在何处以及如何设置Redis实例。

在生产环境中,Redis是否需要额外的配置才能与服务器(nginx)正常工作?

对于nginx,不需要任何特殊配置。你只需在应用程序中进行配置,并确保你可以连接到Redis服务器。


2
是的。请使用redis-rb或ioredis gem。你也需要确保在你的系统或远程主机上安装了redis,并且端口(默认为6379)是可访问的。 - kiddorails

5
在生产中,我使用Kubernetes,其中Redis的URL为redis://redis:6379/0
在我的Rails开发环境中,在Docker中,Redis URL也与上述相同,但是在我的Rails本地主机上,不在Docker中,Redis URL为redis://localhost:6379
接受答案提供了一个好建议,即在初始化程序中设置Redis.new来建立单个连接。
接受答案中的解决方案在您在开发环境中同时使用本地和Docker时无法正常工作。 对于我来说,在config/initializers/redis.rb文件中使用以下代码是解决方案:
redis_url = ENV.fetch("REDIS_URL")

REDIS = Redis.new(url: redis_url)

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

REDIS.incr "page hits"
@page_hits = REDIS.get "page hits"

我使用.env_file在Docker中设置REDIS_URL,使用父目录下的.rbenv-vars文件设置REDIS_URL以在本地主机上运行Rails应用程序。
对于Kubernetes,我在我的rails_deploy.yaml文件的环境部分设置REDIS_URL。

1
不错的配置方法。您可以进一步采取以下步骤,创建一个类似于database.ymlconfig/redis.yml文件,并根据环境提取不同的细节,使用Rails.application.config_for - alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接