2

我对采用哪种方法以及最佳实践感到很困惑。假设我有一个 C# 应用程序,它执行以下操作:

从队列中发送电子邮件。要发送的电子邮件和所有内容都存储在数据库中。

现在,我知道如何使我的 C# 应用程序几乎可扩展,但我需要更进一步。

我想要某种形式的责任,即能够跨 X 服务器分配任务。因此,不仅仅是一台服务器完成所有处理,而是在服务器之间共享它。如果一台服务器出现故障,则负载将在其他服务器之间分担。我知道 NLB 会这样做,但我不是在这里寻找 NLB。

当然,您可以在 DB 表中添加某种列来指示应该分配哪个服务器来处理该记录,并且服务器上的每个应用程序都将具有某种与 DB 中的值匹配的 ID,并且它们只会拉他们自己的记录——但我认为这是廉价的、不好的做法和不切实际的。

由于潜在的死锁和其他可能的问题,我不会做数据库表行锁。

我也没有表示在这里使用“极端”线程,但是是的,每个项目都会有线程来处理或按线程对 x 数量的线程进行批处理。

在制作可扩展且具有高可用性的 C# 应用程序时,我应该如何处理以及您有什么建议?目标是拥有 X 个服务器,每个服务器都具有相同的应用程序,并且每个服务器都能够获取记录并处理它们,但具有在服务器之间共享的处理/项目级别,因此如果一个服务器或服务发生故障,另一个服务器或服务失败可以承担该负载,直到放回另一台服务器。

对不起,我缺乏理解或知识,但一直在思考这个问题,并且睡眠不足,试图想出一个好的强大的解决方案。

4

1 回答 1

1

我会考虑批量处理工作,所以每个应用程序一次只拉回 x 条记录,将这些检索到的记录标记为表中的 bool 字段。我将修改 SELECT 语句以仅提取未标记为已完成/已完成的记录。在这种情况下,表锁可以在很短的时间内使用,以确保处理相同记录的应用程序没有重叠。

编辑:它不是很优雅,但您可以为每个条目设置一个日期戳和一个状态(而不是上面的 bool 字段)。然后,您可以运行定期代理作业,该作业运行 sproc 以重置任何状态为 In Progress 但已超过时间阈值但未设置为完成的记录的状态。稍后它们将准备好由另一个应用程序重新处理。

这可能不足以满足您的口味,但我敢打赌,企业中有很多应用程序同样简单且运行良好。最好的事情以最少的复杂性工作。

于 2012-04-23T20:26:07.357 回答