小窍门
Azure 平台的云原生 .NET 应用电子书封面缩略图。
正如已经开发模式来帮助在应用程序中的代码布局一样,有一些模式可用于以可靠的方式运行应用程序。 维护应用程序时出现了三种有用的模式: 日志记录、 监视和 警报。
何时使用日志功能
无论我们有多小心,应用程序在生产中几乎总是以意外的方式行事。 当用户报告应用程序问题时,能够查看出现问题时应用发生的情况非常有用。 在应用程序运行时捕获有关其活动的最可靠和经过验证的方法之一是让应用程序记录正在进行的操作。 此过程称为日志记录。 每当生产中发生故障或问题时,目标应该是在非生产环境中重现发生故障的条件。 设置良好的日志记录为开发人员提供了一条路线图,以便他们能够在一个可以进行测试和试验的环境中复现问题。
使用云原生应用程序进行日志记录时面临的挑战
在传统应用程序中,日志文件通常存储在本地计算机上。 事实上,在类似 Unix 的作系统上,存在一个文件夹结构,用于保存任何日志,通常位于 /var/log
其中。
图 7-1。 在整体式应用中将日志记录到文件。
在云环境中,将日志记录到单台计算机上的平面文件的有用性大大减少。 生成日志的应用程序可能无法访问本地磁盘或本地磁盘可能是高度短暂的,因为容器是围绕物理计算机随机选择的。 即使是简单扩展整体式应用程序到多个节点,也会使定位合适的文件日志变得困难。
图 7-2。 在缩放的整体式应用中将日志记录到文件。
使用微服务体系结构开发的云原生应用程序也对基于文件的记录器带来了一些挑战。 用户请求现在可能跨越在不同计算机上运行的多个服务,并且可能包括无服务器函数,根本不可访问本地文件系统。 将来自用户或会话的日志关联到这些许多服务和计算机是非常具有挑战性的。
图 7-3. 在微服务应用中将日志记录到本地文件。
最后,某些云原生应用程序中的用户数很高。 假设每个用户在登录到应用程序时会生成一百行日志消息。 单独情况下,这可以管理,但当这种情况扩展到超过 100,000 用户时,日志量就会大到需要使用专用工具来有效管理。
在云原生应用程序中登录
每个编程语言都有允许写入日志的工具,通常写入这些日志的开销较低。 许多日志记录库提供记录不同种类的严重性的功能,可在运行时对其进行调整。 例如, Serilog 库 是适用于 .NET 的常用结构化日志记录库,提供以下日志记录级别:
- 详细
- 调试
- 信息
- 警告
- 错误
- 严重
这些不同的日志级别增加了日志记录的粒度。 当应用程序在生产环境中正常运行时,可能会将其配置为仅记录重要消息。 当应用程序行为不当时,可以增加日志级别,以便收集更详细的日志。 这可以平衡性能与调试的便利性。
日志记录工具的高性能和详细程度可调整性应鼓励开发人员频繁记录。 许多人倾向于记录每个方法的入口和退出模式。 这种方法听起来可能有点过分,但开发人员很少希望减少日志记录。 实际上,仅出于围绕有问题的方法添加日志记录这一目的而执行部署并不少见。 在日志记录过多方面犯错,而不是在日志记录过少方面犯错。 某些工具可用于自动提供此类日志记录。
由于与在云原生应用中使用基于文件的日志相关的挑战,因此首选集中式日志。 日志由应用程序收集,并传送到中央日志记录应用程序,该应用程序为日志编制索引并存储日志。 此类系统每天可以引入数十 GB 的日志。
生成跨越许多服务的日志记录时,遵循一些标准做法也很有帮助。 例如,在较长的交互开始时生成 相关 ID ,然后在与该交互相关的每条消息中记录该 ID,以便更轻松地搜索所有相关消息。 只需查找单个消息并提取相关 ID 即可查找所有相关消息。 另一个示例是确保日志格式对于每个服务都是相同的,无论它使用何种语言或日志记录库。 这种标准化使读取日志更加容易。 图 7-4 演示了微服务体系结构如何利用集中式日志记录作为工作流的一部分。
图 7-4. 来自各种源的日志将引入到集中式日志存储中。
检测和响应潜在应用健康状况问题的挑战
某些应用程序不是任务关键型应用程序。 也许它们仅在内部使用,并且出现问题时,用户可以联系负责的团队,并且可以重启应用程序。 但是,客户通常对使用的应用程序寄予厚望。 你应在用户发现问题或用户通知你问题出现之前知晓应用程序的问题。 否则,你可能会在问题初露端倪时才意识到,具体表现为社交媒体上出现大量愤怒的帖子,嘲讽你的应用程序,甚至是你的组织。
可能需要考虑的一些方案包括:
- 应用程序中的一个服务不断失败和重启,从而导致间歇性缓慢的响应。
- 在一天中的某个时间,应用程序的响应时间很慢。
- 在最近的部署之后,数据库上的负载已翻了三倍。
正确实施后,监视可以让你了解会导致问题的条件,从而在条件导致任何重大用户影响之前解决基础条件。
监视云原生应用
某些集中式日志记录系统承担了在纯日志之外收集遥测的附加角色。 它们可以收集指标,例如运行数据库查询的时间、Web 服务器的平均响应时间,甚至作系统报告的 CPU 负载平均值和内存压力。 与日志结合使用,这些系统可以提供整个系统中节点和应用程序运行状况的整体视图。
还可以从应用程序中手动提供监视工具的指标收集功能。 特别感兴趣的业务流(如新用户注册或下单)可以进行检测,以便在中央监视系统中增加计数器。 这一方面可解锁监视工具,不仅监视应用程序的运行状况,还能监视企业的运行状况。
可以在日志聚合工具中构造查询,以查找某些统计信息或模式,然后可以在自定义仪表板上以图形形式显示这些统计信息或模式。 通常情况下,团队将使用大型壁挂式显示屏,轮流显示与应用程序相关的统计信息。 这样一来,就很容易在问题发生时发现问题。
云原生监控工具提供实时遥测和洞察,不论应用程序是单进程整体架构还是分布式微服务架构。 它们包括允许从应用收集数据的工具,以及用于查询和显示有关应用运行状况的信息的工具。
对云原生应用中的关键问题做出反应的挑战
如果需要对应用程序问题做出反应,则需要通过某种方式提醒正确的人员。 这是第三种云原生应用程序可观测性模式,取决于日志记录和监视。 应用程序需要进行日志记录,以便诊断问题,并在某些情况下用于监控工具。 它需要通过监控来在一个地方汇聚应用程序指标和健康数据。 建立此策略后,可以创建规则,当某些指标超出可接受的级别时,将触发警报。
通常,警报分层在监视之上,以便某些条件触发适当的警报,以通知团队成员出现紧急问题。 可能需要警报的一些方案包括:
- 应用程序服务之一在停机 1 分钟后未响应。
- 应用程序正在将不成功的 HTTP 响应返回到超过 1% 的请求。
- 您的应用程序的关键终结点的平均响应时间超过 2000 毫秒。
云原生应用中的警报
可以针对监视工具创建查询,以查找已知的故障条件。 例如,查询可以在收到的日志中搜索 HTTP 状态代码 500 的迹象,这表示 Web 服务器上的问题。 一旦检测到其中一个,就可以将电子邮件或短信发送给发起服务的所有者,他们可以开始调查。
不过,通常,单个 500 错误不足以确定问题已发生。 这可能意味着用户键入了密码错误或输入了一些格式不正确的数据。 只有在检测到超过 500 错误平均数目时,才能创建警报查询以触发警报。
警报中最具破坏性的模式之一是触发过多警报,供人类调查。 服务所有者会迅速对他们之前调查过并认为是无害的错误失去敏感性。 当发生真正的错误时,这些错误将在数百个误报的干扰中被忽略。 狼来了的故事常常用来告诫孩子们要警惕这样的危险。 请务必确保触发的警报指示真实问题。