在事件驱动的分布式系统中处理网络异常

问题描述

我已经实现了RESTful API,并且在某些端点上进行了一些更新,我需要连接到某些RabbitMQ服务器或Redis服务器。这些消息将帮助事件进一步发展。我的问题是,在这种情况下如何处理网络异常?

例如,如果任务A已更新,我首先更新数据库中任务的状态(例如mongodb),然后在某些RabbitMQ服务器上提交一条消息,以通知另一个微服务上的另一个使用者。或者我可能需要在Redis服务器上更新一些计数器。

* API REQUEST - update Task A
*serving request:
* update Task A on DB
* send message to RabbitMQ about the change (ERROR ? socket timeout. do I retry indef ?)
* update a counter on Redis (ERROR ? socket timeout - do I retry indef?)

如果尝试连接RabbitMQ或Redis时出现“套接字超时异常”,该如何处理?我应该尝试还原数据库上的更改并仅返回HTTP 500吗? 还是我应该尝试将有关此失败的内容写到某个文件或数据库,以便稍后可以再次尝试?

系统是事件驱动的。没有守护程序一直在检查来自数据库的任务,因此必须在收到API请求的那一刻将该消息发送给RabbitMQ。还是应该在收到API请求时对Redis服务器进行更新

解决方法

这在很大程度上取决于您要做什么以及要处理什么。

网络可靠吗?服务可靠吗?如果重播/重试是个大问题吗?如果某个任务尚待解决,这是一个大问题吗?您如何处理不一致的状态?

您提到在发布到RabbitMQ时发生超时(我假设带有确认),但是如果RabbitMQ确认消息丢失了怎么办?或确认它,然后还有其他错误?

最后,架构将由您的风险模型决定,要考虑哪些风险可以接受,哪些不可接受。

通常的方法是尝试创建幂等流,并在失败时重试(因此,多个更新无关紧要),但是不必如此。

如果您绝对需要系统在每个时间点都保持一致,则可能需要实现一个涉及所有部分的分布式交易算法。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...