我一直在寻找使用Redis Pub / Sub替代RabbitMQ。
据我了解,Redis的pub / sub拥有与每个订阅者的持久连接,如果该连接终止,则所有将来的消息都将丢失并掉在地板上。
一种可能的解决方案是使用列表(和阻止等待)将所有消息和pub / sub存储为通知机制。我认为这可以帮助我解决大部分问题,但是我仍然对失败案例感到担忧。
当订户(消费者)死亡时,您的列表将继续增长,直到客户返回。生产商可以在达到特定限制后(从任一侧)修剪列表,但这是您需要在应用程序级别处理的。如果在每个消息中都包含时间戳记,那么您的使用者就可以根据消息的使用期限进行操作,假设您具有要在消息使用期限上执行的应用程序逻辑。
我不确定格式错误的消息将如何进入系统,因为与Redis的连接通常是具有完整性保证的TCP。但是,如果发生这种情况,可能是由于生产者层消息编码中的错误所致,您可以通过保留接收消费者异常消息的每个生产者队列来提供一种处理错误的通用机制。
重试策略将在很大程度上取决于您的应用程序需求。如果您需要100%确保已收到并处理了一条消息,则应考虑使用Redis事务(MULTI / EXEC)来包装使用方完成的工作,因此可以确保客户端不会删除一条消息,除非它已经完成了工作。如果需要显式确认,则可以在专用于生产者进程的队列上使用显式ACK消息。
在不了解您的应用程序需求的情况下,很难知道如何明智地选择。通常,如果您的邮件需要完全的ACID保护,那么您可能还需要使用Redis事务。如果您的消息仅在及时的情况下才有意义,则可能不需要进行交易。听起来好像您不能容忍丢弃的消息,所以使用列表的方法很好。如果需要为邮件实现优先级队列,则可以使用排序集(Z命令)将邮件(以其优先级作为得分值)和轮询使用者一起存储。