我正在考虑将monolith应用程序转变为面向微服务的应用程序,这样做将需要一个健壮的消息传递系统来进行进程间通信。其思想是让microserviceprocesss在ha的服务器集群上运行,将要处理的请求添加到所有应用程序都可以访问的消息队列中。我正在考虑将redis用作 transient 数据的kv存储,以及使用.net的servicestack框架的消息代理,但我担心redis应用的最终一致性概念会使请求的处理变得不可靠。这就是我如何理解redis在mq中的作用:
客户端1将请求发布到节点1上的队列
节点1将使用pub/sub通知该队列上的所有侦听器请求的存在,并且还将异步地将请求推送到节点2。
节点1上的侦听器将从节点中提取请求,其中只有1个侦听器将按原样获取请求。删除请求的更新以异步方式发送到节点2,但需要一些时间才能到达。
初始请求由节点2接收(假设在rtt中有一点延迟),它将继续并使用pub/sub通知连接到它的侦听器。在接收到来自节点1的关于从队列中删除请求的更新之前,节点2上的侦听器也可以拉取请求。结果是两个侦听器最终处理同一个请求,这将对我们的系统造成严重破坏。
redis或servicestack redis mq的实现中是否有任何东西可以阻止所描述的场景发生?或者关于redis中的复制还有什么我误解的地方吗?或者我应该放弃redis/ss的mq方法,而使用rabbitmq之类的东西,而不是我所理解的acid兼容的东西?
1条答案
按热度按时间4sup72z81#
同一条消息不可能在redis mq中处理两次,因为消息工作者将消息从redis list backed mq中弹出,并且所有redis操作都是原子的,因此其他消息工作者将无法访问已从列表中删除的消息。
servicestack.redis(redis mq使用的)只支持redis sentinel for ha,尽管redis支持多个副本,但它们只包含主数据集的只读视图,因此所有写操作(如列表添加/删除操作)只能在单个主示例上发生。
使用redis mq而不是rabbit mq等特定用途mq的一个显著区别是redis不支持ack,因此如果从mq中弹出消息的消息工作进程崩溃,那么它的消息就会丢失,与rabbitmq相反,如果未确认消息的有状态连接终止,则rabbitmq服务器将消息恢复回mq。