【Rails+Redis+Docker】在Rails应用中引入Redis并实现排名功能
引入Redis
这次我们将使用Redis来显示常见的博客网站排名。
首先,我必须进行Rails和Redis的连接,但是在这方面我遇到了大约两天的困难。我在许多网站上不断尝试,但始终无法成功连接,这真是一段地狱般的经历。
解决方案
通常情况下,Redis连接到localhost:6379是很常见的,但在开发阶段,由于Rails本身连接到了localhost,所以搞混了导致无法正确连接。
所以,只需将Redis的配置从localhost更改为redis,就能顺利进行。
我认为一旦开始做就觉得很简单,但对于初学者来说确实是相当困难的地方。如果只是写代码出错还好,但连接不上且出错会对精神造成相当大的影响。
以下为变更内容和参考网站。
【https://stackoverflow.com/questions/34729752/sidekiq-error-connecting-to-redis-on-127-0-0-16379-errnoeconnrefused-on-doc】的链接显示了一个关于Sidekiq连接到Redis时出现的错误消息。
顺便提一下,这是docker-compose.yml的配置样式。
version: '3'
services:
db:
image: mysql:8.0.17
command: mysqld --default-authentication-plugin=mysql_native_password
volumes:
- ./db/mysql_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: root
ports:
- "4306:3306"
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/app_name
ports:
- "3000:3000"
depends_on:
- db
- redis
tty: true
stdin_open: true
links:
- db
environment:
REDIS_HOST: redis
REDIS_PORT: 6379
redis:
image: redis:5.0.5
ports:
- 6379:6379
volumes:
- ./redis:/data
command: redis-server --appendonly yes
用Redis实现排名功能。
尽管Redis的引入没有问题,但并不意味着一旦引入就万事大吉。
为了显示排名,我们还需要重新审查Redis基础、控制器和视图。
我在搜索”Rails redis 排名”时也找到了很多参考网站,但因为对其运作机制理解不足,所以需要重新审视基础知识。
以下是Redis的特点:
-
- インメモリアルデータベース(すごく早い!)…ランキングなどに向いてる
-
- 永続化(定期的にディスクに書き出す)
- データ構造サーバー
要在Rails中使用这样的Redis,需要通过Gem将Redis引入并使用REDIS方法。
当Gem被成功引入后,在config/initialize目录下创建redis.rb文件并填入以下内容。
require 'redis'
uri = URI.parse(ENV["REDIS"])
REDIS = Redis.new(host: uri.host, port: uri.port)
def index
@posts = Post.all
ids = REDIS.zrevrangebyscore "posts/daily/#{Date.today.to_s}", "+inf", 0,limit:[0,3]
@ranking_posts = ids.map{ |id| Post.find(id) }
end
# GET /posts/1
# GET /posts/1.json
def show
REDIS.zincrby "posts/daily/#{Date.today.to_s}", 1, @post.id
end
在本次实现中,我们使用了Redis的排序集合来实现PV数排行榜。
要显示PV数,只需直接将以下内容写入视图即可显示。
<ul>
<% @ranking_posts.each do |ranking_post| %>
<li>
<%= link_to(ranking_post.title,"/posts/#{ranking_post.id}") %>
(<%= REDIS.zscore("posts/daily/#{Date.today.to_s}", ranking_post.id).to_i %>PV)
</li>
<% end %>
</ul>
我想過如何在行動中安裝,但是只找到了這一個方法。雖然看起來有點不美觀,但至少可以顯示PV數量。
总结
我对Redis的理解还很欠缺,但是我玩它的时候觉得非常有趣,所以我想再次使用它。