我正在构建一个数据库,其中某些表将填充在"使用它或丢失它"场景自动化应用程序流我的意思是数据将通过Webhook(PayPal IPN)进入,如果我的RDBMS拒绝INSERT,则数据将丢失,即没有操作员检查/更正数据并重试。
一个简单的解决方案是通过排除NOT NULL
使数据库字段尽可能简单,甚至可能使字段基于文本。
仍然存在一致性问题。我怎样才能确保这一点?我是否应该包含可能包含在数据库中的检查,并在出现问题时记录警告。
实际上,只有WebHook服务发生变化才会破坏,但我想为这种情况做好准备。
更新:
我想另一种方法可能是在NoSQL商店中逐字缓存所有传入的webhook消息。无论上述问题如何,这都可能是一个好主意。
答案 0 :(得分:0)
这一切都取决于您不会丢失此事件/数据的重要性。
由于网络问题或其他问题,总是有可能永远不会调用webhook,但是如果我们假设PayPal负责确保最终调用服务器上的webhook(即他们在他们身边重试)如果事情失败了,您可以通过以下一项或多项措施,几乎100%保证您不会丢失数据:
在接收webhook的servlet /应用程序中,请确保尽可能少地使用它,除非可能验证数据以确保它以一致的形式存储在您身边。可能有人认为,如果您想在以后重新播放这些事件或事件,您还应该使用意外数据来保留无效事件或事件。
如果您有消息代理/队列系统或其他高可用性分布式数据存储(例如RabbitMQ,Kafka,Cassandra,Redis或类似产品),您应该在那里发送事件。您可以选择始终执行此操作,或者仅在直接对数据库进行故障时才执行此操作,但为简单起见,最好始终将事件放在队列中并使用单独的进程从队列中读取并写入数据到SQL数据库。
如果您没有队列系统,或者在队列系统中存储事件失败,您可以在处理webhook的节点上的本地磁盘¹上保留事件。这种后备可以帮助您在写入数据库和/或队列系统失败的情况下恢复“丢失”事件。
在单独的进程中,从队列或其他分布式存储中获取事件,并将其插入数据库。如果写入数据库成功,此过程应仅对队列中的消息进行确认,否则,消息不应被确认,因此可以重新处理消息。
您实施的这些技术越多,越接近100%保证永不丢失事件。最后,一切都会失败,如果你想要一些非常强大的东西,你应该设计它以期望任何事情都会在某些时候失败。
但是,即使yuo具有分布式消息队列,如果写入队列失败并且同时写入本地磁盘也会失败,则可能会丢失数据。在这种情况下恢复数据的唯一方法是让PayPal重新播放事件并使用相同的数据再次调用您的webhook,或者从PalPal手动检索相同的数据(如果可能)。
BTW:是使用队列还是仅使用“哑”分布式数据存储来存储事件取决于您是否关心处理顺序,多次处理同一事件等等。
¹如果在webhook节点上处理数据时记录数据,则“免费”获得本地磁盘持久性,但这取决于您是否能够实际记录事件中的所有数据,这可能不是如果事件包含敏感数据,则可能如果您在plcace中有某种日志传送或分布式日志记录服务器,这也可能(部分)保护您免受webhook节点上的磁盘故障或节点本身故障(即虚拟/云服务器重新启动并丢失其磁盘) 的