我希望得到一些关于我们团队几乎每个项目似乎都会重现的问题的提示。
在这些项目中,主要目标通常是对大量的项目进行某种处理。 '处理'基本上是一系列动作,每个动作都可能由于各种原因而失败。
也许我可以通过描述一个示例应用程序来解释它。
想象一下以下作为我们的一个应用程序的简化版本:(实际上可能是1000 LoC)
foreach (var pdfFile in unprocessedPdfFiles)
{
var mailWasSent = SendMail(pdfFile);
if(!mailWasSent)
{
PrintFile(pdfFile);
}
MarkAsProcessed(pdfFile);
}
虽然这些是有问题的要求:
我认为这是我们最大的困难:
(注意:处理性能通常没有问题。)
以下是我们过去尝试解决这些问题的方法:
我确信有很多专家在这方面有很多长期经验。 (无论它叫什么) 但是我无法通过搜索网络找到很多实用的建议,所以我希望在stackoverflow上我可以得到一些建议。
我在网上找到了有趣的框架,但到目前为止还犹豫不决:
希望帖子不会太混乱,但我很乐意在需要的地方详细说明。
答案 0 :(得分:1)
首先,这是一个需要立即解决的大问题。
这是一个企业级问题,最好在更高级别的抽象上解决。在SOA术语中,您必须将系统分解为仅执行其需要执行操作的较小应用程序。想想SOLID [1]。思考单一责任。
将应用程序分解为更小的应用程序后,您可以使用像Mule [2]或Apache Camel [3]这样的集成中心来集成消息交换。
微服务架构[4]通过创建彼此隔离服务的边界来很好地解决问题。按业务领域或职能分组服务。
以下是一些可以让您的生活更轻松的提示:
使用AWS等托管云服务来减少应用程序的责任。例如,对于文件管理,请使用AWS S3 [5]。要发送电子邮件,请使用AWS SNS主题[6],它允许您可靠地发送电子邮件。或者,使用作为托管SMTP服务器的AWS SES。使用托管服务的优点是您不需要处理诸如记录或管理故障之类的低级工作。让PAAS为您处理。
消息队列的职责是为共享信息提供持久,可靠的通道。它用于以松散耦合的方式可靠地接收和发送消息给多个消费者和生产者。它也不会帮助您写入数据库。
如果您想在处理数据库时也写入数据库,请考虑将数据写入Apache Kafka [7]或AWS Kinesis Stream [8]等流。您可以创建多个收件人来收听流,并对数据进行操作。例如,一个客户端可以处理数据并将结果保存到数据库。另一个客户端监听器可以负责记录数据。
对所有API调用使用重试策略。延迟和超时等瞬态故障在分布式处理中非常常见。它们可以在一段时间后消失,并且可以使用重试来处理。有一个很好的重试策略框架用C#编写,称为Polly [9]。
如果在最大重试限制后无法解决的故障,请向死信队列发送消息[10]。 AWS Lamdba支持执行将失败的执行作为消息发送到死信队列的代码。 AWS Lambda将自动重试,因此您可以专注于编写代码以执行其所需的操作。任何执行失败都将转到DLQ。另一个Lambda函数可用于处理DLQ中的消息。
我希望您开始了解如何解决问题,并使用一些良好的原则,您将能够构建一个更强大,可扩展且更具弹性的系统。
[1] https://www.codeproject.com/Articles/703634/SOLID-architecture-principles-using-simple-Csharp
[2] https://developer.mulesoft.com/
[4] http://microservices.io/patterns/microservices.html
[5] https://aws.amazon.com/s3/
[6] https://aws.amazon.com/sns/
[8] https://aws.amazon.com/kinesis/streams/