14、Micronaut 框架中微服务的分布式日志、跟踪和监控

Micronaut 框架中微服务的分布式日志、跟踪和监控

在微服务架构中,一个应用通常由多个运行在不同主机上的微服务组成。对于上游消费者来说,API 网关提供了一个一站式的接口来访问所有应用端点。任何对 API 网关的请求都会分散到一个或多个微服务中。这种分布式的请求处理方式给基于微服务的应用维护带来了挑战。如果出现异常或错误,很难确定是哪个微服务或分布式组件出了问题。因此,有效的微服务实现必须主动应对这些维护挑战。

1. 技术要求

在开发环境中,需要安装和设置以下工具:
- Java SDK:版本 13 或更高(建议使用 Java 14)
- Maven:可选,仅在使用 Maven 作为构建系统时需要。建议在开发机器上进行设置。下载和安装说明: Maven 官网
- 开发 IDE:可根据个人喜好选择基于 Java 的 IDE,这里以 IntelliJ 为例
- Git:下载和安装说明: Git 官网
- PostgreSQL:下载和安装说明: PostgreSQL 官网
- MongoDB:MongoDB Atlas 提供免费的在线数据库服务,存储容量可达 512 MB。如果需要本地数据库,下载和安装说明: MongoDB 官网
- REST 客户端:可使用任何 HTTP REST 客户端,这里以 Advanced REST Client Chrome 插件为例
- Docker:下载和安装说明: Docker 官网

2. 分布式日志

在基于微服务的应用中,用户请求会在运行于不同主机环境的多个微服务上执行,因此日志消息会分散在多个主机上。这给开发者或管理员维护应用带来了挑战,因为出现故障时,需要登录多个主机环境,筛选日志并整合才能找到问题所在。

2.1 日志聚合组件

日志聚合是将应用中各个微服务和组件产生的日志组合在一起,通常涉及以下组件:
- 日志生产者:在执行控制流时产生日志的任何微服务或分布式组件
- 日志分发器:负责收集日志生产者产生的日志,并将其分发到集中存储
- 日志存储:持久化并索引应用所有组件和微服务产生的日志
- 日志可视化器:提供用户界面,用于访问、搜索和过滤存储在日志存储中的日志

2.2 实现 ELK 堆栈进行分布式日志记录

在宠物诊所应用中,可使用 ELK(Elasticsearch、Logstash、Kibana)堆栈实现分布式日志记录。

设置 ELK 到 Docker
1. 从 GitHub 仓库 检出 docker-elk。
2. 打开任何 Bash 终端(如 Git Bash)。
3. 切换到检出 docker-elk 的目录。
4. 运行 docker compose up –d 命令。
5. 等待 Docker 下载镜像并实例化 ELK 容器。

默认情况下,Elasticsearch 在端口 9200 运行,Logstash 在 5000 运行,Kibana 在 5601 运行。

集成 Logstash 与 Micronaut 微服务
为了将 Logstash 集成到宠物诊所微服务中,可借助 Logback。在 Logback 中引入一个新的 appender,将日志发送到之前创建的 Logstash 实例。

Logstash 配置如下:

input {
    tcp {
        port => 5000
        type => syslog
        codec => json_lines
    }
}
filter {
    grok {
        match => [ "message", "%{GREEDYDATA}" ]
    }
    mutate {
        add_field => { "instance_name" => "%{app_name}- %{host}:%{app_port}" }
    }
}
output {
    stdout { 
        codec => rubydebug
    }
    elasticsearch {
        hosts => [
            "${XPACK_MONITORING_ELASTICSEARCH_HOSTS}" ]
        user => 
            "${XPACK_MONITORING_ELASTICSEARCH_USERNAME}"
        password => 
            "${XPACK_MONITORING_ELASTICSEARCH_PASSWORD}"
        index => "logstash-%{+YYYY.MM.dd}"
    }
}

该配置包含三个部分:
| 配置部分 | 说明 |
| ---- | ---- |
| input | 配置 Logstash 的一个或多个输入源,这里启用了端口 5000 的 TCP 输入 |
| filter | 将传入的日志转换为定义的日志事件,并添加额外信息(如 app_name 和 app_port) |
| output | 配置接收源,将日志事件推送到标准输出和 Elasticsearch |

配置微服务进行分布式日志记录
为了让宠物诊所微服务将日志聚合并发送到 Logstash,需要在所有微服务的 pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>6.3</version>
</dependency>

修改所有微服务的 logback.xml 文件,添加 Logstash appender:

<appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    <param name="Encoding" value="UTF-8"/>
    <remoteHost>host.docker.internal</remoteHost>
    <port>5000</port>
    <encoder class=»net.logstash.logback.encoder.LogstashEncoder»/>
</appender>
…
<root level="debug">
    <appender-ref ref="logstash"/>
    <appender-ref ref="stdout"/>
</root>

同时,需要定义 app_name app_port 属性:

<property scope="context" name="app_name" value="pet-owner "/>
<property scope="context" name="app_port" value="32581"/>

验证宠物诊所应用中的分布式日志记录
为了验证 Logstash 是否从宠物诊所应用的所有微服务接收日志,需要重新构建 Docker 镜像并重新部署应用:
1. 在 pet-owner 微服务根目录的终端中:
- 运行 mvn compile jib:dockerBuild 命令构建 Docker 镜像。
- 等待 jib 构建并上传 Docker 镜像到本地 Docker 镜像仓库。
2. 在 pet-clinic 微服务根目录的终端中,重复上述步骤。
3. 在 pet-clinic-reviews 微服务根目录的终端中,重复上述步骤。
4. 在 pet-clinic-concierge 微服务根目录的终端中,重复上述步骤。
5. 打开任何 Bash 终端,切换到检出的宠物诊所 docker-compose.yml 文件所在目录:
- 运行 docker compose up –d 命令。
- 等待 Docker 启动宠物诊所堆栈。

应用启动后,需要配置 Kibana 来索引和显示日志:
1. 访问 Kibana ,使用 docker-elk 目录中 .env 文件中的 Elasticsearch 凭据登录。
2. 打开主页,点击“Connect to your Elasticsearch index”超链接,Kibana 将提供连接索引的设置页面。
3. 在设置页面加载后,在“Index Patterns”文本框中输入 logstash
4. 点击“Next step”按钮,在配置设置中选择 @timestamp
5. 点击“Create index pattern”。

成功连接索引后,可在“Discover”页面查看应用日志。由于在日志事件中添加了 app_name app_port ,可以根据这两个参数查看特定微服务的日志。

3. 分布式跟踪

分布式跟踪是系统通过收集请求从一个服务组件传递到另一个服务组件的数据,来跟踪和观察分布式系统中请求执行流程的能力。跟踪数据会收集每个服务的执行时间和端到端执行流程等指标,有助于找出执行流程中的性能瓶颈。

跟踪是一种类似甘特图的数据结构,以跨度(span)的形式存储跟踪信息。每个跨度记录特定服务组件中的执行流程,并且可以引用父跨度和子跨度。

3.1 实现基于 Zipkin 的分布式跟踪

在宠物诊所应用中,可使用 Zipkin 进行分布式跟踪。

运行 Zipkin 实例
1. 打开任何 Bash 终端。
2. 运行 docker run -d -p 9411:9411 openzipkin/zipkin 命令。
3. 等待 Docker 下载并在端口 9411 上实例化 Zipkin。实例化成功后,可通过 Zipkin 界面 进行验证。

配置宠物诊所 - 礼宾服务
在 pet-clinic-concierge 服务的 POM 文件中添加以下依赖:

<!-- Distributed tracing -->
<dependency>
    <groupId>io.micronaut</groupId>
    <artifactId>micronaut-tracing</artifactId>
    <version>${micronaut.version}</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>io.zipkin.brave</groupId>
    <artifactId>brave-instrumentation-http</artifactId>
    <version>5.12.3</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.zipkin.reporter2</groupId>
    <artifactId>zipkin-reporter</artifactId>
    <version>2.15.0</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.opentracing.brave</groupId>
    <artifactId>brave-opentracing</artifactId>
    <version>0.37.2</version>
    <scope>compile</scope>
</dependency>

application.properties 文件中添加以下与 Zipkin 相关的属性:

tracing:
  zipkin:
    http:
      url: http://host.docker.internal:9411
    enabled: true
    sampler:
      probability: 1

在 Micronaut 中,有两个用于管理跨度的标签:
- @NewSpan :从标记的方法开始创建一个新的跨度。
- @ContinueSpan :延续前一个跨度。

OwnerResourceClientController 中进行如下修改:

@Controller("/api")
public class OwnerResourceClientController {
    @Inject
    OwnerResourceClient;
    @NewSpan
    @Post("/owners")
    public HttpResponse<OwnerDTO> createOwner(@SpanTag("owner.dto") OwnerDTO ownerDTO) {
        return ownerResourceClient.createOwner(ownerDTO);
    }
    @NewSpan
    @Put("/owners")
    HttpResponse<OwnerDTO> updateOwner (@SpanTag("owner.dto") @Body OwnerDTO ownerDTO) {
        return ownerResourceClient.updateOwner(ownerDTO);
    }
    ...
}

其他微服务(pet-owner、pet-clinic、pet-clinic-reviews)的客户端控制器方法也需要进行类似的修改。

修改宠物诊所微服务进行分布式跟踪
在 pet-owner、pet-clinic 和 pet-clinic-reviews 微服务的项目 POM application.properties 文件中进行相同的修改。同时,在这些微服务的控制器方法上添加 @ContinueSpan 标签:

@Post("/owners")
@ExecuteOn(TaskExecutors.IO)
@ContinueSpan
public HttpResponse<OwnerDTO> createOwner(@Body OwnerDTO ownerDTO) throws URISyntaxException {
    ...
}
3.2 验证宠物诊所应用中的分布式跟踪

要验证宠物诊所应用中的分布式跟踪,需要确保应用正在运行。通过 API 网关获取所有者列表:
1. 在任何浏览器标签或 REST 客户端中访问 http://localhost:32584/api/owners
2. 访问 Zipkin 验证上述 HTTP GET 调用的跟踪信息。
3. 点击“Run Query”按钮。
4. 在返回的结果中找到 get /api/owners 请求并点击“Show”。

通过 Zipkin 的用户界面,可以看到请求首先到达 pet-clinic-concierge,然后传递到 pet-owner 微服务。整个请求大约花费了 948 毫秒,大部分时间花在了 pet-owner 微服务上。

通过实现分布式日志和分布式跟踪,可以提高系统的可观测性,更方便地维护和优化基于微服务的应用。在后续内容中,将进一步探讨分布式监控以及如何在 Micronaut 框架中实现。

4. 分布式监控

分布式监控是持续监控所有服务组件的关键性能指标,以全面了解系统健康状况的过程。通过收集分布式日志、跟踪和监控这三种不同类型的数据,可以增强系统的可观测性,随时获取请求在系统中执行的完整上下文。

4.1 监控指标和工具

在微服务架构中,常见的监控指标包括:
- 响应时间 :服务处理请求所需的时间。
- 吞吐量 :单位时间内处理的请求数量。
- 错误率 :请求失败的比例。
- 资源利用率 :如 CPU、内存、磁盘 I/O 等资源的使用情况。

可以使用多种工具来实现分布式监控,例如 Prometheus 和 Grafana。Prometheus 是一个开源的监控系统,用于收集和存储时间序列数据;Grafana 是一个可视化工具,用于展示 Prometheus 收集的数据。

4.2 在宠物诊所应用中实现分布式监控

以下是在宠物诊所应用中使用 Prometheus 和 Grafana 实现分布式监控的步骤:

安装和配置 Prometheus
1. 下载 Prometheus:从 Prometheus 官网 下载适合你操作系统的版本。
2. 配置 Prometheus:创建一个 prometheus.yml 配置文件,指定要监控的目标。示例配置如下:

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'pet-clinic'
    static_configs:
      - targets: ['localhost:32581', 'localhost:32582', 'localhost:32583', 'localhost:32584']

在上述配置中, scrape_interval 指定了数据收集的间隔时间, targets 列出了要监控的微服务的地址和端口。

  1. 启动 Prometheus:在终端中运行以下命令启动 Prometheus:
./prometheus --config.file=prometheus.yml

安装和配置 Grafana
1. 下载 Grafana:从 Grafana 官网 下载适合你操作系统的版本。
2. 启动 Grafana:在终端中运行以下命令启动 Grafana:

./bin/grafana-server
  1. 配置数据源:打开浏览器,访问 http://localhost:3000 ,使用默认的用户名和密码(admin/admin)登录 Grafana。在 Grafana 中,添加 Prometheus 作为数据源,配置如下:
    • Name :自定义数据源名称。
    • Type :选择 Prometheus。
    • URL :输入 Prometheus 的访问地址,例如 http://localhost:9090

创建监控仪表盘
1. 在 Grafana 中,点击“Create” -> “Dashboard” 创建一个新的仪表盘。
2. 添加面板:点击“Add panel”,选择要展示的指标,例如响应时间、吞吐量等。可以使用 PromQL(Prometheus 查询语言)来查询和过滤数据。
3. 配置面板:设置面板的标题、图表类型、数据源等信息。
4. 保存仪表盘:完成配置后,点击“Save dashboard” 保存仪表盘。

以下是一个简单的 PromQL 查询示例,用于查询某个微服务的平均响应时间:

avg_over_time(http_request_duration_seconds_sum{job="pet-clinic", instance="localhost:32581"}[5m]) / avg_over_time(http_request_duration_seconds_count{job="pet-clinic", instance="localhost:32581"}[5m])
4.3 监控流程总结

下面是在宠物诊所应用中实现分布式监控的流程总结:

graph LR
    A[安装和配置 Prometheus] --> B[启动 Prometheus]
    C[安装和配置 Grafana] --> D[启动 Grafana]
    D --> E[配置数据源(Prometheus)]
    E --> F[创建监控仪表盘]
    B --> F

总结

通过实现分布式日志、分布式跟踪和分布式监控,可以显著提高基于微服务的应用的可观测性。在 Micronaut 框架中,我们可以利用 ELK 堆栈实现分布式日志记录,使用 Zipkin 进行分布式跟踪,使用 Prometheus 和 Grafana 进行分布式监控。

  • 分布式日志 :使用 ELK 堆栈将分散在多个主机上的日志集中管理,方便故障排查和日志分析。
  • 分布式跟踪 :通过 Zipkin 跟踪请求在不同服务组件之间的执行流程,找出性能瓶颈。
  • 分布式监控 :使用 Prometheus 和 Grafana 监控关键性能指标,全面了解系统的健康状况。

在实际应用中,随着微服务数量的增加和系统复杂度的提高,分布式日志、跟踪和监控的重要性将更加凸显。通过合理配置和使用这些技术,可以更好地维护和优化微服务架构,确保系统的稳定性和性能。

希望本文介绍的方法和步骤能够帮助你在 Micronaut 框架中实现高效的分布式日志、跟踪和监控,提升微服务应用的可维护性和性能。

【电能质量扰动】基于MLDWT的电能质量扰动分类方法研究(Matlab实现)内容概要:本文研究了一种基于机器学习(ML)离散小波变换(DWT)的电能质量扰动分类方法,并提供了Matlab实现方案。首先利用DWT对电能质量信号进行多尺度分解,提取信号的时频域特征,有效捕捉电压暂降、暂升、中断、谐波、闪变等常见扰动的关键信息;随后结合机器学习分类器(如SVM、BP神经网络等)对提取的特征进行训练与分类,实现对不同类型扰动的自动识别与准确区分。该方法充分发挥DWT在信号去噪与特征提取方面的优势,结合ML强大的模式识别能力,提升了分类精度与鲁棒性,具有较强的实用价值。; 适合人群:电气工程、自动化、电力系统及其自动化等相关专业的研究生、科研人员及从事电能质量监测与分析的工程技术人员;具备一定的信号处理基础Matlab编程能力者更佳。; 使用场景及目标:①应用于智能电网中的电能质量在线监测系统,实现扰动类型的自动识别;②作为高校或科研机构在信号处理、模式识别、电力系统分析等课程的教学案例或科研实验平台;③目标是提高电能质量扰动分类的准确性与效率,为后续的电能治理与设备保护提供决策依据。; 阅读建议:建议读者结合Matlab代码深入理解DWT的实现过程与特征提取步骤,重点关注小波基选择、分解层数设定及特征向量构造对分类性能的影响,并尝试对比不同机器学习模型的分类效果,以全面掌握该方法的核心技术要点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值