27、微服务的日志记录与监控

微服务的日志记录与监控

1. 日志记录

1.1 日志处理优化

日志数据在被 Logstash 处理之前可以在代理中进行缓冲。代理起到缓冲作用,当有大量日志消息无法立即处理时,它会存储这些消息。Redis 常被用作代理,它是一种快速的内存数据库。

1.2 日志分析工具

1.2.1 Graylog

Graylog 是一个开源的日志分析解决方案,它利用 Elasticsearch 存储日志数据,使用 MongoDB 存储元数据。Graylog 定义了自己的日志消息格式——GELF(Graylog 扩展日志格式),该格式对通过网络传输的数据进行了标准化。许多日志库和编程语言都有针对 GELF 的扩展,也可以使用 UNIX 工具 syslog 从日志数据中提取或查看相关信息。Logstash 支持 GELF 作为输入和输出格式,因此可以与 Graylog 结合使用。Graylog 还提供了一个 Web 界面,方便分析日志信息。

1.2.2 Splunk

Splunk 是一款商业解决方案,已在市场上存在很长时间。它不仅可以分析日志文件,还能分析机器数据和大数据。处理日志时,Splunk 通过转发器收集数据,通过索引器对数据进行预处理以便搜索,搜索头负责处理搜索请求。其安全概念强调了作为企业解决方案的定位。它支持定制分析和在出现特定问题时发出警报,还可以通过众多插件进行扩展,并且有针对特定基础设施(如 Microsoft Windows Server)的现成解决方案应用程序。该软件既可以安装在自己的计算中心,也可以作为云解决方案使用。

1.3 日志利益相关者

日志记录有不同的利益相关者,但日志服务器的分析选项非常灵活,分析方法也相似,通常一个工具就足够了。利益相关者可以创建自己的仪表盘,展示与他们相关的信息。对于特定需求,日志数据可以传递给其他系统进行评估。

1.4 关联 ID

在多个微服务协同处理一个请求时,为了便于分析请求在微服务中的路径,需要使用关联 ID。关联 ID 可以唯一标识整个系统中的一个请求,并在微服务之间的所有通信中传递。这样,在中央日志系统中就可以轻松找到与单个请求相关的所有系统的日志条目,从而跨所有微服务跟踪请求的处理过程。

关联 ID 的实现方式如下:
- 可以通过在消息头或有效负载中传递请求 ID 来实现。
- 许多项目在自己的代码中实现这种传递,而不使用框架。
- 对于 Java,可以使用 tracee 库来实现 ID 的传递。
- 一些日志框架支持上下文,在接收消息时将关联 ID 放入上下文中,这样就无需在方法之间传递关联 ID。但当请求处理涉及多个线程时,如果关联 ID 绑定到线程,可能会出现问题。确保在上下文中设置关联 ID 可以保证所有日志消息都包含该关联 ID,并且所有微服务记录关联 ID 的方式必须统一,以便在日志中搜索请求。

1.5 Zipkin:分布式跟踪

在性能评估方面,需要跨微服务进行评估。当请求的完整路径可追溯时,就可以确定哪个微服务是瓶颈,以及哪个微服务处理请求需要特别长的时间。Zipkin 可以实现这种调查,它支持不同的网络协议,能够自动通过这些协议传递请求 ID。与关联 ID 不同,Zipkin 的目的不是关联日志条目,而是分析微服务的时间行为,并提供了合适的分析工具。

1.6 尝试与实验

  • 定义一个能够实现基于微服务架构的日志记录的技术栈:
  • 确定日志消息的格式。
  • 必要时定义一个日志框架。
  • 确定用于收集和评估日志的技术。
  • 思考当前项目如何处理日志,是否可以在项目中实施上述部分方法和技术。

2. 监控

2.1 监控概述

监控用于监视微服务的指标,使用除日志记录之外的信息源。监控主要使用数值来提供应用程序当前状态的信息,并指示该状态随时间的变化。这些值可以表示在特定时间内处理的调用次数、处理调用所需的时间,或者系统值(如 CPU 或内存利用率)。当某些阈值被超过或未达到时,这表明存在问题,并可以触发警报,以便有人解决问题,甚至可以自动解决问题,例如通过启动额外的实例来解决过载问题。

监控提供的生产反馈不仅对运维人员重要,对开发人员和系统用户也很重要。基于监控信息,他们可以更好地理解系统,从而做出关于系统进一步开发的明智决策。

2.2 基本监控信息

所有微服务都应提供基本的监控信息,这有助于全面了解系统状态。所有微服务应以相同的格式提供所需信息,微服务系统的组件也可以使用这些值。例如,负载均衡可以使用健康检查来避免访问无法处理调用的微服务。

所有微服务应提供的基本值包括:
- 指示微服务可用性的值,表明微服务是否能够处理调用(“存活”)。
- 关于微服务可用性的详细信息,例如微服务使用的所有其他微服务是否可访问,以及所有其他资源是否可用(“健康”)。这些信息不仅能表明微服务是否正常运行,还能提示微服务的哪个部分当前不可用以及原因。
- 微服务的版本信息以及其他元信息,如联系人、使用的库及其版本等。这些信息可以作为文档的一部分,也可以用于检查当前生产环境中实际使用的微服务版本,便于查找错误,还可以实现微服务和其他软件的自动连续清单管理。

2.3 额外指标

监控还可以记录额外的指标,如响应时间、特定错误的频率或调用次数等。这些值通常针对特定的微服务,不一定所有微服务都需要提供。当达到某些阈值时,可以触发警报,不同微服务的阈值不同。为了让所有微服务使用相同的监控工具,使用统一的接口访问这些值是明智的,这可以大大减少这方面的开销。

2.4 监控利益相关者

监控信息有不同的利益相关者:
- 运维人员希望及时了解问题,以确保微服务的顺利运行。在出现紧急问题或故障时,他们希望通过寻呼机或短信等方式随时收到警报。只有在需要更深入分析错误时,才需要详细信息,通常会与开发人员一起进行分析。运维人员不仅关注微服务本身的值,还关注操作系统、硬件或网络的监控值。
- 开发人员主要关注应用程序的信息,他们希望了解应用程序在生产环境中的运行方式以及用户的使用情况。根据这些信息,他们可以进行优化,特别是在技术层面。因此,他们需要非常具体的信息,例如,如果应用程序对某类调用的响应过慢,就需要针对这类调用对系统进行优化,为此需要获取尽可能多的关于这类调用的信息。开发人员会详细评估这些信息,甚至可能对分析特定用户或一组用户的调用感兴趣。
- 业务利益相关者关注业务成功和相关业务数据。应用程序可以专门为他们提供这些信息,他们根据这些信息生成统计数据,从而做出业务决策。通常,他们对技术细节不感兴趣。

不同的利益相关者不仅关注不同的值,而且分析方式也不同。标准化数据格式有助于支持不同的工具,使所有利益相关者都能访问所有数据。

2.5 事件关联

将数据与事件(如新版本发布)进行关联是有意义的。这需要将事件信息传递给监控系统。当新版本发布带来显著的收入增长或导致明显的响应时间延长时,这是一个值得关注的发现。

2.6 监控与测试的关系

在某种程度上,监控是另一种形式的测试。测试关注新版本在测试环境中的正确功能,而监控检查应用程序在生产环境中的行为。集成测试的结果也应反映在监控中。当问题导致集成测试失败时,监控中可以有相关的警报。此外,测试环境也应启用监控,以便在测试阶段就发现问题。当通过适当的措施降低部署风险时,监控甚至可以接管部分测试工作。

2.7 动态环境挑战

基于微服务架构的工作面临的另一个挑战是微服务的动态性。在部署新版本时,实例可能会停止并以新的软件版本重新启动。当服务器出现故障时,实例会关闭并启动新的实例。因此,监控必须与微服务分开进行,否则微服务的停止会影响监控基础设施,甚至导致其失败。此外,微服务是分布式系统,单个实例的值本身并不具有代表性,只有收集多个实例的值,监控信息才具有相关性。

2.8 具体监控技术

可以使用不同的技术来监控微服务:
| 技术名称 | 描述 |
| ---- | ---- |
| Graphite | 可以存储数值数据,针对处理时间序列数据进行了优化。数据可以在 Web 应用程序中进行分析,存储在自己的数据库中,一段时间后会自动删除。通过套接字接口以非常简单的格式接受监控值。 |
| Grafana | 扩展了 Graphite,提供了替代的仪表盘和其他图形元素。 |
| Seyren | 为 Graphite 增加了触发警报的功能。 |
| Nagios | 是一个全面的监控解决方案,可以作为 Graphite 的替代方案。 |
| Icinga | 最初是 Nagios 的一个分支,使用场景非常相似。 |
| Riemann | 专注于处理事件流,使用函数式编程语言定义对特定事件的反应逻辑,可以配置合适的仪表盘,并通过短信或电子邮件发送消息。 |
| Packetbeat | 使用代理记录被监控计算机上的网络流量,能够轻松确定哪些请求需要多长时间以及哪些节点之间进行通信。它使用 Elasticsearch 进行数据存储,使用 Kibana 进行分析,与日志分析使用相同的工具栈,降低了环境的复杂性。 |
| 商业工具 | 如 HP 的 Operations Manager、IBM Tivoli、CA Opscenter 和 BMC Remedy 等。这些工具非常全面,在市场上存在很长时间,支持许多不同的软件和硬件产品。通常在企业范围内使用,但引入这些工具通常是一个非常复杂的项目。一些解决方案还可以分析和监控日志文件。 |
| 云监控 | 可以将监控迁移到云端,无需安装额外的基础设施,便于引入工具和监控应用程序,例如 NewRelic。 |

2.9 微服务中启用监控

微服务需要提供数据,以便在监控解决方案中显示。可以通过简单的接口(如 HTTP)以 JSON 等数据格式提供数据,然后监控工具可以读取并导入这些数据。开发人员可以编写适配器脚本,通过相同的接口为不同的工具提供数据。

2.10 监控相关框架和工具

  • Metrics :在 Java 世界中,可以使用 Metrics 框架记录自定义值并将其发送到监控工具,从而在应用程序中记录指标并将其传递给监控工具。
  • StatsD :可以从不同来源收集值,进行计算,并将结果传递给监控工具。这有助于在将数据传递给监控工具之前进行数据压缩,减少监控工具的负载。有许多 StatsD 客户端库便于向 StatsD 发送数据。
  • collectd :可以收集系统统计信息,如 CPU 利用率。数据可以通过前端进行分析,也可以存储在监控工具中。collectd 可以从 HTTP JSON 数据源收集数据并发送到监控工具,还可以通过不同的插件从操作系统和基本进程收集数据。

2.11 监控技术栈

监控技术栈包括以下不同组件:
- 在微服务内部记录数据并提供给监控。可以使用直接与监控工具通信的库,也可以通过统一接口提供数据。

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;

    A(微服务):::process -->|数据记录| B(监控工具):::process
    A -->|通过统一接口| C(数据传输):::process
    C --> B
    B --> D(分析展示):::process

以上就是关于微服务日志记录和监控的详细介绍,通过合理运用这些技术和方法,可以更好地管理和优化微服务系统。

2.12 监控技术栈组件详细分析

2.12.1 数据记录组件

在微服务内部进行数据记录是监控的基础。可以采用以下两种主要方式:
- 使用直接与监控工具通信的库 :以 Java 中的 Metrics 框架为例,它提供了丰富的 API 来记录各种指标。以下是一个简单的使用示例:

import com.codahale.metrics.ConsoleReporter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Timer;

import java.util.concurrent.TimeUnit;

public class MetricsExample {
    static final MetricRegistry metrics = new MetricRegistry();

    public static void main(String[] args) {
        ConsoleReporter reporter = ConsoleReporter.forRegistry(metrics)
               .convertRatesTo(TimeUnit.SECONDS)
               .convertDurationsTo(TimeUnit.MILLISECONDS)
               .build();
        reporter.start(1, TimeUnit.MINUTES);

        Timer timer = metrics.timer(MetricRegistry.name(MetricsExample.class, "test-timer"));
        Timer.Context context = timer.time();
        try {
            // 模拟处理逻辑
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            context.stop();
        }
    }
}

在这个示例中,我们创建了一个 Timer 来记录一段代码的执行时间,并通过 ConsoleReporter 将指标输出到控制台。

  • 通过统一接口提供数据 :可以使用 HTTP 接口以 JSON 格式提供数据。以下是一个使用 Spring Boot 实现的简单示例:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@SpringBootApplication
@RestController
public class MonitoringDataProvider {

    public static void main(String[] args) {
        SpringApplication.run(MonitoringDataProvider.class, args);
    }

    @GetMapping("/metrics")
    public Map<String, Object> getMetrics() {
        Map<String, Object> metrics = new HashMap<>();
        metrics.put("cpuUsage", 0.5);
        metrics.put("memoryUsage", 0.6);
        return metrics;
    }
}

这个示例中,我们创建了一个 Spring Boot 应用,通过 /metrics 接口以 JSON 格式返回 CPU 和内存的使用情况。

2.12.2 数据传输组件

数据传输是将微服务内部记录的数据传递到监控工具的过程。常见的传输方式有:
- 通过 HTTP 协议 :如上述 Spring Boot 示例,监控工具可以通过发送 HTTP 请求到微服务的统一接口来获取数据。
- 使用消息队列 :可以使用 Kafka、RabbitMQ 等消息队列将数据异步发送到监控工具。例如,使用 Kafka 发送监控数据的示例代码如下:

import org.apache.kafka.clients.producer.*;
import java.util.Properties;

public class KafkaProducerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

        Producer<String, String> producer = new KafkaProducer<>(props);
        ProducerRecord<String, String> record = new ProducerRecord<>("monitoring-topic", "cpuUsage", "0.5");
        producer.send(record, new Callback() {
            @Override
            public void onCompletion(RecordMetadata metadata, Exception exception) {
                if (exception != null) {
                    System.err.println("Failed to send message: " + exception.getMessage());
                } else {
                    System.out.println("Message sent successfully: " + metadata.toString());
                }
            }
        });
        producer.close();
    }
}

在这个示例中,我们创建了一个 Kafka 生产者,将 CPU 使用情况发送到 monitoring-topic 主题。

2.12.3 分析展示组件

监控工具接收到数据后,需要对数据进行分析和展示。不同的监控工具提供了不同的分析和展示功能:
- Graphite 和 Grafana :Graphite 存储时间序列数据,Grafana 则提供了强大的可视化功能。可以通过 Grafana 创建各种仪表盘来展示监控数据,如折线图、柱状图等。以下是一个简单的 Grafana 仪表盘配置示例:
| 面板名称 | 数据来源 | 展示类型 |
| ---- | ---- | ---- |
| CPU 使用率 | Graphite 中的 cpuUsage 指标 | 折线图 |
| 内存使用率 | Graphite 中的 memoryUsage 指标 | 柱状图 |

2.13 监控技术选型建议

在选择监控技术时,需要考虑以下几个因素:
- 功能需求 :根据微服务系统的具体需求,确定需要监控的指标和功能。如果需要监控网络流量,可以选择 Packetbeat;如果需要处理事件流,可以选择 Riemann。
- 可扩展性 :随着微服务系统的发展,监控需求可能会不断增加。选择具有良好可扩展性的监控技术,如支持插件扩展的工具,可以方便地添加新的监控功能。
- 易用性 :监控工具的易用性直接影响运维人员和开发人员的使用体验。选择具有直观界面和简单配置的工具,如 Grafana,可以降低使用门槛。
- 成本 :商业监控工具通常功能强大,但成本较高;开源工具则成本较低,但可能需要更多的技术支持。需要根据企业的实际情况进行选择。

2.14 微服务监控最佳实践

2.14.1 建立监控指标体系

根据微服务的业务需求和技术架构,建立全面的监控指标体系。包括基本指标(如可用性、健康状态、版本信息)和额外指标(如响应时间、错误频率)。

2.14.2 定期评估和优化监控策略

随着微服务系统的不断变化,监控策略也需要不断调整和优化。定期评估监控指标的有效性,删除不必要的指标,添加新的指标。

2.14.3 自动化处理和告警

设置合理的阈值,当指标超过阈值时自动触发告警。同时,可以通过自动化脚本实现问题的自动处理,如自动启动额外的实例来解决过载问题。

2.14.4 多维度分析

不仅要关注微服务本身的指标,还要结合操作系统、硬件和网络的监控数据进行多维度分析。例如,当微服务响应时间过长时,检查是否是由于网络延迟或 CPU 过载导致的。

2.15 总结

微服务的日志记录和监控是确保微服务系统稳定运行和性能优化的关键。通过合理选择日志分析工具和监控技术,建立完善的监控指标体系,以及遵循最佳实践,可以更好地管理和优化微服务系统。在实际应用中,需要根据具体情况进行灵活调整,不断完善日志记录和监控方案。

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;

    A(确定监控需求):::process --> B(选择监控技术):::process
    B --> C(建立监控指标体系):::process
    C --> D(实施监控):::process
    D --> E(分析数据):::process
    E --> F(优化策略):::process
    F --> D

以上就是关于微服务日志记录和监控的全面介绍,希望能为微服务系统的管理和优化提供有益的参考。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值