通常,系统的健壮性来自全面有效的错误管理。由于错误可能发生在我们的硬件和软件系统环境的任何部分,因此我们需要区别对待它们。例如:数据中心-整个数据中心(DC)可能因电源故障、网络连接故障、环境灾难等而变得不可用硬件设备-服务器、存储组件可能会出现硬盘故障、磁盘已满、可分配资源耗尽和其他硬件错误。软件应用程序——无论应用程序的技术堆栈如何,都可能发生应用程序错误、异常软件行为和程序级缺陷。为了从各个方面应对上述故障,我们往往需要通过以下手段来提供系统的自愈能力:通过监控,提供电源、网络、冷却系统等方面的冗余来实现数据中心的高可用性。部署在云端,减少错误实例,使用更成熟的技术栈,基于微服务的分布式架构。监控服务器各项参数,采用多种高可用部署方式,采用容器化方式,具有强大的DevOps功能。通过应用各种替代架构和设计模式来最大限度地减少错误。例如,异步处理用户请求有助于避免服务器过载并为用户提供一致的体验。可以看出,无论是系统架构师还是应用程序设计者,他们的主要目标都是根据实际业务需求和成本影响,仔细考虑和设计各个组件的高可用性,并能够优雅地处理应用程序错误.模式简述目前业界有多种架构模式和方法,可以满足不同的应用架构范式、功能需求、NFR(Non-FailureRequest)、应用故障恢复能力。例如:如果应用是基于微服务的,那么我们的重点应该放在微服务集成依赖的容错上。如果应用程序是基于事件的架构,除了正常的错误处理之外,我们还应该注意处理幂等性和出现问题时可能丢失的数据。虽然基于API的同步应用很容易将错误返回给调用者,但如果问题持续时间较长,我们就需要更实用的监控和事件管理机制。在基于批处理的组件中,我们可能应该专注于以幂等方式重新启动或恢复原始批处理功能。错误代码如果没有关于错误代码的通用约定和指南,每个应用程序或系统将根据用例和设计遵循自己的自定义默认错误代码。这有可能导致不同的方法相互冲突。可见,在应用程序的错误处理过程中,我们应该提前定义错误代码。通过标准化和直观的错误处理方法,可以提高解决问题的效率,以及错误的数量、负载峰值以及特定类型故障的影响等细节。错误处理下图显示了如何在基于事件的应用程序中处理各种错误。当然,所涉及的具体步骤可能因架构模型而异。首先,我们应该区分应用程序的可重试错误和不可重试错误。例如,当传入消息本身存在问题时,除非有人为干预,否则重试此类错误通常没有意义。那些数据库连接问题值得重试。当应用出现重试类型错误时,我们可以选择统一的“错误重试配置”方式进行微调。如下表所示,在基于事件的服务中,一旦基础设施组件的可用性缺失,我们需要通过预定义的重复重试机制来确认运营商是否及时修复了。这往往比直接怀疑并处理并发请求导致问题的可能性更符合常识。触发事件我们需要一种方法来触发事件并在所有重试失败时升级错误。在简单的情况下,我们可以直接将问题的相关信息以通知的形式反馈给用户,建议用户重新提交所需的请求。但有些问题源于内部技术问题,导致用户体验突然下降。例如,在基于事件的架构中,异步集成模式经常使用DLQ(译者注:死信队列,DeadLetterQueue)作为错误处理模式。尽管如此,DLQ只是该过程中的一个临时步骤。我们仍然需要通过触发事件或发送警报来可靠地升级错误。那么,我们如何设计一个集事件和告警于一体的管理系统呢?下面,我们将讨论两种主要的方法:第一种方法:当应用程序完成所有重试后,我们需要利用其可用的logs功能来构建可靠的错误报告路径,以减少丢失错误消息的可能性。虽然业界有成熟的日志记录标准。但是,我们仍然需要将各个错误日志分开,以便事件管理系统不会被不相关的错误消息淹没。我们通常将此类日志称为“错误警报”。它们通常由专用代码库和组件以预设格式生成,及时生成大量错误消息。这是一个代码示例:Java{"logType":"ErrorAlert","errorCode":"subA.compA.DB.DatabaseA.Access_Error","businessObjectId":"234323","businessObjectName":"ACCOUNT","InputDetails":"
