用Ruby配Redis搞消息通知,简单又实用的入门分享
- 问答
- 2026-01-15 13:07:14
- 2
(引用来源:基于常见的Ruby与Redis应用场景及官方文档基础概念整合)
今天聊个实在的,就是用Ruby和Redis弄个消息通知功能,别想得太复杂,不是什么高深的消息队列,就是比如用户A干了件事,咱们能立刻通知到用户B这种简单需求,用Redis来做,主要是因为它快,而且数据结构简单,搞这种活儿特别顺手。
咱们先得把家伙事儿准备好,你电脑上得安装并运行着Redis,这个去Redis官网下载安装就行,安装后用redis-server命令就能启动,在你的Ruby项目里,需要加上redis这个gem,在Gemfile里写一句gem 'redis',然后跑一下bundle install就行了。
核心思想特别简单,就是把Redis的列表(List)当成一个管道,想象一下,我们有好多管道,每个管道对应一个用户,当有人想给这个用户发通知时,就把通知内容像塞小纸条一样,从管道的左边塞进去,而用户那边呢,就时不时地从管道的右边把纸条取出来看,这个“管道”,在Redis里就是一个列表数据结构,用LPUSH命令(从左边塞入)和RPOP命令(从右边取出)来操作。

先来看看发送通知的Ruby代码怎么写,假设我们有一个通知中心类:
(引用来源:Redis官方文档对LPUSH命令的说明)
require 'redis'
class NotificationService
def initialize
@redis = Redis.new # 默认连接本地的6379端口
end
def send_notification(to_user_id, message)
# 关键的一步:把消息塞进属于这个用户的列表里。
# 我们给每个用户的列表起个名字,"notifications:user_1"
list_key = "notifications:user_#{to_user_id}"
# LPUSH 的意思是从列表左边插入新消息
@redis.lpush(list_key, message)
puts "消息已发送给用户 #{to_user_id}: #{message}"
end
end
你看,发送通知就这么简单两三行代码。@redis.lpush(key, value)是核心,它把消息内容(message)存到了以用户ID命名的那个Redis列表的最前面。

发出去的消息得有人收啊,接收通知的一方,比如我们有一个后台任务或者一个API接口,专门帮用户查有没有新通知,我们来写个接收的方法:
(引用来源:Redis官方文档对RPOP命令的说明)
class NotificationService
# ... 上面的初始化代码和发送代码 ...
def get_notifications(user_id)
list_key = "notifications:user_#{user_id}"
notifications = []
# 这里我们一次把当前列表里所有的消息都取出来。
# 因为RPOP每次只取一个,所以我们用循环,直到取不到为止(即列表为空)。
while message = @redis.rpop(list_key)
notifications << message
end
if notifications.empty?
puts "用户 #{user_id} 没有新通知。"
else
puts "用户 #{user_id} 的新通知有:"
notifications.each { |msg| puts " - #{msg}" }
end
return notifications
end
end
这个get_notifications方法也很直白,它用一个循环,不断地用@redis.rpop(list_key)从列表的右边取出消息,直到什么都取不出来(rpop返回nil)为止,这样就能一次性拿到所有积压的通知,取出的同时,RPOP命令会把消息从列表中删除,这样就避免了重复通知。

我们来模拟一下整个流程,写段代码跑跑看:
# 新建一个通知服务 notifier = NotificationService.new # 用户1给用户2发一条通知 notifier.send_notification(2, "你好!你的订单已经发货了。") # 用户3也给用户2发一条通知 notifier.send_notification(2, "系统提醒:您的会员即将到期。") # 让用户2来查看他的通知 user2_notifications = notifier.get_notifications(2) # 控制台会打印: # 用户 2 的新通知有: # - 系统提醒:您的会员即将到期。 # - 你好!你的订单已经发货了。
你会发现,后发出的通知“会员到期”反而显示在前面了,这是因为我们是用LPUSH从左边插入的,类似于栈的结构,后进先出,如果你希望最早的通知显示在前面,可以在取出通知后.reverse一下数组,或者考虑使用RPUSH和LPOP的组合,这取决于你的业务需求。
这种模式简单好用,但它有个小缺点:接收通知的一方需要主动来“拉取”消息,如果想让消息能“推送”到客户端(比如网页浏览器),就需要更复杂的技术,比如WebSocket,但就服务器内部的服务之间通信,或者处理一些不需要极速响应的后台通知,这个模式已经非常够用了。
再提一个实用的小改进,如果担心消息堆积太多,可以给列表设置一个长度限制,只保留最新的N条消息,Redis提供了一个LTRIM命令,可以在每次插入新消息后执行一下,比如_redis.ltrim(list_key, 0, 99),这样就只保留最新的100条消息,防止Redis内存被撑爆。
用Ruby配Redis搞消息通知,核心就是利用Redis的List充当临时管道,用LPUSH发消息,用RPOP收消息,代码简单明了,性能也高,对于很多入门和中等规模的应用来说,是一个非常实际和有效的解决方案,你先把这个基础打牢,以后万一业务变复杂了,再去看那些专业的消息队列系统,也会更容易理解。
本文由酒紫萱于2026-01-15发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/81179.html
