`
wx1569578408
  • 浏览: 71531 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

使用Elastic APM监控你的.NET Core应用

 
阅读更多

前言

在应用实际的运维过程中,我们需要更多的日志和监控来让我们对自己的应用程序的运行状况有一个全方位的了解。然而对于大部分开发者而言,平时大家所关注的更多的是如何更优雅的实现业务,或者是如何让应用的响应速度更快等等与编码相关的技术,对于应用程序的监控,可能还停留在日志文件的层面,而且大多数是出了事故被人为发现后,才通过日志尝试去定位问题。

本文所准备介绍的Elastic APM是一套用于监控应用各项指标,比如系统响应时间、异常、EF执行的SQL记录等等,并且可以将这些记录组织成一个可追溯的链路,方便查询问题。此外,Elastic APM还可以通过Kibana来做非常漂亮的可视化展示,方便我们定位和发现问题。

废话不再多说,我们开始实战~Elastic APM介绍

Elastic APM的由下面四个组件所组成,如下图:

640?wx_fmt=png

APM Agent

APM Agent是安装到你的.NET Core程序中的一个Nuget包,他用于性能、错误等各类数据的收集,并将收集到的数据缓存起来分批发送到APM Server。当然,除了.NET Core使用的Nuget包,他还可以支持很多其他的语言,比如Java,Node.Js,Python等

支持的语言列表请参考这里:https://www.elastic.co/guide/en/apm/agent/index.html

APM Server

APM Server是部署在服务器端的一个用于接收Agent发来的数据包的应用程序,并根据这些数据包自动创建文档,将数据转存到Elastic Server中。

Elastic Search

这个相信大家都很熟悉了,他就是一个基于Lucene实现的高性能、分布式的全文搜索引擎,用于快速、实时的存储、搜索和分析大量数据。在这里来说,他提供的是数据存储和搜索能力!

Kibana

如果你熟悉Elastic Search,那么你一定多少会了解Kibana,Kibana是开源的分析和可视化平台,他能与Elastic Search进行很好的协同,帮助你快速的可视化存储在Elastic Search中的数据,并做成各种各样漂亮的报表、图形等。

环境准备

在本次的实战过程中,我们需要以下的东西:

  • Elastic Search

  • Kibana

  • APM Server

  • 一个基于.NET Standard 2.0 + 的项目

Elastic Search的安装:https://www.cnblogs.com/baiyunchen/p/11227144.html

Kibana的安装:

我的环境是Centos 7,所以照着https://www.elastic.co/guide/en/kibana/7.3/rpm.html 这个官网教程安装的,整个过程很简单:

  • 下载Kibana RPM包(采用这种方式是因为用yum install网速太慢,所以我用迅雷下载完成rpm文件后上传到Linux机器中)

  • 执行命令rpm --install  “下载的文件名” 进行安装

  • 安装完成后,到/etc/kibana/kibana.yml文件中在文件末尾增加以下配置:

1

2

3

4

5

server.host: 0.0.0.0

server.name: 主机IP

server.port: 一个你喜欢的端口号

elasticsearch.hosts: ["已安装好的ES地址,多个之间用逗号隔开"]

logging.dest: /var/log/kibana.log

  • 将Kibana安装为系统服务并启动

1

2

3

4

sudo /bin/systemctl daemon-reload

sudo /bin/systemctl enable kibana.service

sudo systemctl start kibana.service

这里大家一定要注意Elastic Search的版本和Kibana一定要匹配,不然会报错的。(我的ES是前段时间装的,所以会有这问题,如果大家一口气安装所有的,应该没啥问题)

如果不幸遇到了问题,可以通过配置文件中logging.dest中配置的路径查看日志。

APM Server的安装

APM Server的安装跟Kibana的安装类似,过程如下:

  • 下载RPM包,包在这个页面找你需要的版本,也需要跟ES、Kibana的版本一致,不然你懂得~ https://www.elastic.co/cn/downloads/past-releases#apm-server

  • 执行rpm --install “下载的文件名”进行安装

  • 在文件夹/etc/amp-server中修改配置文件apm-server.yml,将配置文件最开始的host: “localhost:8200”修改成“0.0.0.0:8200”,以便让他能允许通过ip:端口号的方式访问, 并在配置的最后面添加如下配置:

1

2

output.elasticsearch:

    hosts: ["已安装好的ES地址,多个之间用逗号隔开"]

  • 将apm-server安装为系统服务并启动

1

2

3

4

sudo /bin/systemctl daemon-reload

sudo /bin/systemctl enable apm-server.service

sudo systemctl start apm-server.service

执行上述操作完成后,在浏览器中尝试打开服务器Ip:8200,最终如果APM Server安装的没有问题,则浏览器中会打印出类似于如下的内容:

1

2

3

4

5

{

  "build_date": "2019-06-20T14:39:23Z",

  "build_sha": "9a099b63c53eac8c55707df96193143ec66337e9",

  "version": "7.2.0"

}

此时我们在浏览器中打开Kibana,然后点击Add APM

640?wx_fmt=png

然后将新打开的页面往下滚动,点击Check APM Server Status按钮,如果出现You have correctly setup APM Server则说明安装完成~

640?wx_fmt=png

到这里为止,我们的安装工作就全部完成了,接下来,我们尝试将.NET Core与Elastic APM集成起来,一起继续吧~

.NET Core 应用集成

我们创建一个Demo项目,来用于测试APM的各项功能。

项目的地址请参考GitHub:

引用依赖包

我们需要从Nuget引用相关的SDK来与我们的应用做集成,其实就是引用我们最开始说的APM Agent的部分,在Nuget中,我们引用Elastic.Apm.NetCoreAll这个包。

依赖这个包其实相当于自动依赖了如下三个包,你也可以根据需要只依赖其中的一部分。

  • Elastic.Apm

  • Elastic.Apm.AspNetCore

  • Elastic.Apm.EntityFrameworkCore

这里我们为了简单起见,直接印用Elastic.Apm.NetCoreAll这个包

将Agent添加到.NET Core

找到.NET Core的StartUp文件,在里面的Configure方法中添加如下代码:

1

2

3

4

public void Configure(IApplicationBuilder app, IHostingEnvironment env)

{

    app.UseAllElasticApm(Configuration);

}

然后在application.json中添加如下内容:

1

2

3

4

5

6

{

  "ElasticApm": {

    "LogLevel": "Error",

    "ServiceName" : "MyApp",

  }

}

此时我们将项目启动起来,随便的刷新几下,然后回到Kibana中,在刚才的页面中往下滚动,选择.NET,然后点击Check Agent Status按钮,如果顺利,就会显示“Data successfully received from one or more agents”,如果不幸没能显示这句话,可以通过VS的Diagnostic Tools中的Event跟踪一下,看看是不是哪里没有配置对

640?wx_fmt=png

 640?wx_fmt=png

监控数据查看

在Kibana的Add APM页面的最下方,找到Load Kibana Objects,来创建索引,然后点击APM dashboard按钮,就可以进入APM数据的查看页面。

640?wx_fmt=png 

点击APM Dashboard按钮后,展示的页面如下:

640?wx_fmt=png

该页面中的功能分为Services、Traces两个大的功能模块,先来简单了解一下这两个Tab页中对应的功能。

Services

下面的列表中显示的XianDotnetCommunity其实就是你在配置文件中配置的ServiceName,点击这个名字进入,又可以看到如下的报表,里面有Transactions,Errors,Metrics三个Tab页。

640?wx_fmt=png

 640?wx_fmt=png

 640?wx_fmt=png

其中

Transactions:展示的当前应用请求情况的概览,包括请求响应时长、请求调用次数等等

Errors:程序中的异常列表

Metrics:应用程序所在机器的CPU/内存使用情况

PS:其实我觉得非常需要一个当前应用程序所消耗的内存和CPU的值,但是貌似.NET Core版本的代理没有实现这些功能,期待未来的更新吧

Traces

里面是用于做链路追踪的视图,首页包含所有事务的名称列表以及响应时间等

640?wx_fmt=png

点击具体的事务进去,可以看到这个事务经过的链路列表以及更详细的一些响应信息,从而帮你分析出整个链路中的瓶颈,更多内容我们在下面细讲。

640?wx_fmt=png

探索更多

Elastic APM还有很多其他的功能,比如链路追踪、数据库调用执行,让我们来一起探索吧~API调用链路追踪

如果你了解过微服务架构,那你一定了解链路追踪这个概念。那什么是链路追踪呢?举个栗子:

有个服务A,他会依赖服务B,C,而服务B又会依赖服务D,E,服务C又依赖F,G(省略无数依赖关系),然后有一天,服务A变得非常慢,那到底该怎么定位是哪个服务慢呢?此时链路最终就派上用场了~

我们来简单模拟一下这种嵌套的调用:

在一个WebAPI项目Demo1中有一个ConsumerController,他里面有一个API A,里面调用了另外一个WEB API项目Demo2中的接口B/C/D/E。代码大致如下:

项目甲:


[Route("api/consumer")]

[ApiController]

public class ConsumerController : ControllerBase

{

    private readonly IHttpClientFactory _httpClientFactory;

    public ConsumerController(IHttpClientFactory httpClientFactory)

    {

        _httpClientFactory = httpClientFactory;

    }

    private const string baseUri = "http://localhost:54597";

    [HttpGet("a")]

    public async Task<string> A()

    {

        var client = _httpClientFactory.CreateClient();

        Thread.Sleep(new Random().Next(1, 1500));

        var b = await client.GetStringAsync($"{baseUri}/api/data-source/b");

        var c = await client.GetStringAsync($"{baseUri}/api/data-source/c");

        var d = await client.GetStringAsync($"{baseUri}/api/data-source/d");

        var e = await client.GetStringAsync($"{baseUri}/api/data-source/e");

        return $"b={b} & c={c} & d={d} & e={e}";

    }

}

项目乙:


[Route("api/data-source")]

[ApiController]

public class DataSourceController : ControllerBase

{

    [HttpGet("b")]

    public async Task<string> B()

    {

        Thread.Sleep(new Random().Next(1, 1500));

        return "B";

    }

    [HttpGet("c")]

    public async Task<string> C()

    {

        Thread.Sleep(new Random().Next(1, 1500));

        return "C";

    }

    [HttpGet("d")]

    public async Task<string> D()

    {

        Thread.Sleep(new Random().Next(1, 1500));

        return "D";

    }

    [HttpGet("e")]

    public async Task<string> E()

    {

        Thread.Sleep(new Random().Next(1, 1500));

        return "E";

    }

}

此时我们请求Demo1中的API A (xxx/api/consumer/a),然后在Kibana中打开APM中的Traces,找到”GET Consumer/A” 这条记录(看起来默认是根据Controller的名字+Action的名字命名的),然后点击查看详情。

640?wx_fmt=png

在详情中的最下方,我们找到TimeLine,可以看到如下图所示的图形:

640?wx_fmt=png

我们可以看到我们在请求API A时的时间分别花费在调用4个API中的时间,也可以看出调用第三个API花费的时间更长,点击蓝色的条可以看到请求的详细信息。

这里不太好的一点是默认显示的名字是GET localhost这样的,其实我们更期望的是显示成调用的api uri对吧?这个我提了一个pr给他们,大家可以关注下:https://github.com/elastic/apm-agent-dotnet/pull/463监控EF执行记录

这个不需要过多的解释,就是在EF执行DB操作时,进行监控,以便发现性能等问题,我的代码大致如下:


[HttpGet("person")]

public void TestEfCore()

{

    using (var db = new ApmDbContext())

    {

        var jax = new Person

        {

            Name = "西安.NET社区",

            Age = 26,

            Remark = "做最好的技术社区~"

        };

        db.Persons.Add(jax);

        db.SaveChanges();

        db.Persons.FirstOrDefault(x => x.Id == jax.Id );

        db.Persons.FirstOrDefault(x => x.Name == "西安.NET社区");

        jax.Name = ".NET西安社区";

        db.SaveChanges();

        db.Persons.Remove(jax);

        db.SaveChanges();

    }

}

当我们使用Kibana查看这次请求时,TimeLine显示如下:

640?wx_fmt=png

我们可以比较清晰直观的看到在这次请求中,执行了哪些SQL语句,各耗时多少,对我们的请求分析来说,还是蛮有用处的。点击具体的蓝条,还可以看到更详细的数据,但比较遗憾的是,数据中并没有记录SQL Params ,这对于我们想完全重现这次请求来说,还是不够友好~

640?wx_fmt=png

自行埋点记录

相对来说,Elastic APM目前生态圈还不够好,比sky walking还是稍微差一些组件的支持,如果要使用Elastic APM,免不了自己去做一些性能数据的埋点记录,或者在为第三方组件、类库做支持时,也需要做一些数据的埋点。接下来我们就在我们的请求中,埋一些我们想额外记录的信息,示例代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

[HttpGet]

public void RecordMyApmData()

{

    var transaction = Agent.Tracer.CurrentTransaction;

    var span1 = transaction.StartSpan("Stage 1", "Customize");

    Thread.Sleep(300);

    span1.End();

    Thread.Sleep(200);

    var span2 = transaction.StartSpan("Stage 2", "Customize");

    Thread.Sleep(100);

    span2.End();           

    Thread.Sleep(100);

    var span3 = transaction.StartSpan("Stage 3", "Customize");

    Thread.Sleep(500);

    span3.End();           

}

最终记录的效果如下:

640?wx_fmt=png

这个Demo虽然写的很简单,但是我相信你已经能大概脑补如何使用Elastic Apm Agent这个类去自定义自己需要捕捉的一些监控数据了~

异常监控

当我们的程序发生了异常时,Elastic APM能帮助你记录,这个功能和日志差不多,但可能比日志稍微好用那么一点点。我们一起来看看吧~

示例代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

[HttpGet]

public void TestException()

{

    try

    {

        throw new Exception("捕获的异常");

    }

    catch (Exception)

    {

    }

    throw new Exception("未捕获的异常");

}

执行代码后,我们可以通过点击Service Name,然后在Errors这个Tab页中查看到这次的异常

640?wx_fmt=png

点击详情,我们能看到详细的堆栈调用信息:

640?wx_fmt=png

此外,我们可以在Trasactions Tab中,找到发生异常的这个请求,然后点击查看详情,在详情中我们也能看到这次异常的发生:

640?wx_fmt=png

总结

本文介绍了如何使用Elastic APM在.NET Core应用中收集性能和异常数据,并使用Kibana进行可视化分析,整体来说,Elastic APM还是挺强大的,对于性能监控、链路追踪、异常监控基本是够用了。

目前来说,Elastic APM 支持的组件还是比较有限,比如对数据库查询还只是支持EF Core,并不支持更多的组件,链路追踪也仅支持HTTP请求的追踪,也没用支持其他的方式。另外,个人认为Elastic APM把监控报警(Watcher) 给放到X-Pack收费包中也是挺让人伤心的,异常监控报警其实还是蛮关键的。

欢迎大家尝试Elastic APM,有问题的地方共同探讨~

分享到:
评论

相关推荐

    基于.netcore搜索封装ElasticSearch.zip

    通过这两个库,开发者可以更加便捷地在.NET Core应用中使用Elasticsearch的功能。 在.NET Core应用中集成Elasticsearch,首先需要安装对应的NuGet包。"TCT.Net.Base.ElasticSearch"可能已经集成了这些依赖,或者你...

    miniblog-elasticsearch:将Elasticsearch与ASP.NET Core结合使用

    将Elasticsearch与ASP.NET Core和Docker结合使用 结合的博客文章的示例代码。 使用MiniBlog模板创建一个新的ASP.NET Core项目,并在其中添加Elasticsearch功能。 是开源项目。 是的产品。

    Elasticsearch.Net Demo

    Elasticsearch.Net是一个非常底层且灵活的客户端,它不在意你如何的构建自己的请求和响应。... Elasticsearch.Net有非常大的弹性,如果你想更好的提升你的搜索服务,你完全可以使用它来做为你的客户端。

    Laravel开发-elastic-apm-laravel

    Elastic APM是一个强大的工具,它可以帮助开发者实时监控应用的性能指标,包括数据库查询、HTTP请求、内存使用等,从而及时发现并解决性能瓶颈。 **Elasticsearch与APM** Elasticsearch是一个分布式、开源的搜索和...

    elasticsearch组件APM

    总之,Elasticsearch APM是现代应用程序监控的强大工具,它提供了深入的性能洞察,有助于持续优化和提升应用性能。通过集成APM,开发者和运维团队可以更快地定位和解决问题,确保服务的高可用性和用户体验。

    asp.net分布式应用程序

    9. **分布式日志和监控**:为了跟踪和调试分布式系统中的问题,使用像ELK Stack(Elasticsearch, Logstash, Kibana)或Prometheus这样的工具收集和分析来自不同节点的日志和性能数据至关重要。 总之,ASP.NET提供了...

    【ASP.NET编程知识】Elasticsearch.Net使用入门教程(1).docx

    在本教程中,我们将使用 C# 语言编写一个控制台应用程序,用于演示 Elasticsearch.Net 的使用。首先,读者需要创建一个新的控制台应用程序项目,然后添加 Elasticsearch.Net NuGet 包。 Program.cs 代码如下所示:...

    【ASP.NET编程知识】.Net Core项目中NLog整合Exceptionless实例.docx

    它支持JavaScript, Node, .NET Core, .NET相关应用程序的异常信息采集。 二、NLog简介 NLog是一款日志框架,完美支持.NET和.NET Core,可以将日志输入到多种target形式,如txt文件、Sql Server、MySQL、Redis、Mq...

    elasticsearch-net, Elasticsearch.Net &嵌套.zip

    elasticsearch-net, Elasticsearch.Net &嵌套 这两个存储库分别为和收费 Elasticsearch.Net,这两个正式的elasticsearch. NET 客户机。兼容矩阵Elasticsearch客户端支持 Windows CI Linux CI Nuget CI

    Python库 | elastic_apm-5.5.2-cp36-cp36m-manylinux1_i686.whl

    `elastic_apm`就是这样一个Python库,它为应用程序性能监控(APM)提供了强大的解决方案。 **1. elastic_apm库介绍** `elastic_apm`是Elastic公司提供的一个Python库,专门用于集成到Python应用中,以便监控和追踪...

    PyPI 官网下载 | Elastic_APM_ASGI-0.0.8-py3-none-any.whl

    要将`Elastic_APM_ASGI`集成到你的ASGI应用中,首先需要在你的项目环境中安装这个库,可以使用pip进行安装: ```bash pip install Elastic_APM_ASGI-0.0.8-py3-none-any.whl ``` 然后,在你的应用配置中设置...

    ASP.NET_Core-Elastic_APM-Docker:该项目在Docker上为单页ASP.NET核心应用程序(Model-View-Controller)设置了Elastic APM

    Docker中的ASP.NET Core Web应用程序+弹性APM Docker是一组平台即服务(PaaS)产品,它们使用操作系统级虚拟化来以称为容器的程序包交付软件。 容器彼此隔离,并将它们自己的软件,库和配置文件捆绑在一起; 他们...

    .net core来构建一个内容管理系统.zip

    首先,`.NET Core`是微软推出的一个跨平台、开源的开发框架,它允许开发者在Windows、Linux、macOS等多个操作系统上构建Web应用、桌面应用以及云服务。.NET Core提供了高性能、模块化和可移植的优势,使得开发者可以...

    Go-APM服务器从ElasticAPM代理接收数据并将数据存储到Elasticsearch中

    Elastic APM是Elastic公司提供的一种强大的APM解决方案,能够实时监控和分析应用程序的性能。在这个场景中,我们将讨论如何使用Go语言构建一个APM服务器,该服务器能从Elastic APM代理接收数据,并将这些数据存储到...

    Python库 | elastic_apm-5.7.0-cp37-cp37m-manylinux2010_i686.whl

    Elastic APM是一个强大的监控解决方案,用于追踪应用程序性能,帮助开发者诊断和优化代码,确保应用程序的高效运行。 **版本与兼容性** `elastic_apm-5.7.0-cp37-cp37m-manylinux2010_i686.whl` 这个文件是`...

    aspnetcore-graphql-elasticsearch:示例应用程序,使用Asp.Net Core 2.2和Elastic Search演示GraphQL Web API

    在本项目中,"aspnetcore-graphql-elasticsearch" 是一个使用 Asp.Net Core 2.2 和 Elasticsearch 构建的示例应用程序,它演示了如何通过 GraphQL Web API 来与 Elasticsearch 进行交互。这个项目的核心目的是展示...

    ElasticSearchLite:一个用于ElasticSearch.Net的简单.NET Core包装器

    ElasticSearchLite是一个专为Elasticsearch.Net设计的.NET Core轻量级封装库,它旨在简化Elasticsearch在.NET Core应用程序中的使用。Elasticsearch是一个流行的开源全文搜索引擎,提供了分布式、实时、可扩展的数据...

    Elasticsearch.Net使用入门教程(1)

    通过这个入门教程,你可以了解如何设置环境、安装插件、以及如何在.NET应用中使用Elasticsearch.Net进行基本的数据操作。随着对Elasticsearch.Net的深入学习,你将能够掌握更高级的功能,如聚合查询、实时分析和复杂...

    otel-with-java:具有Elastic APM的Java中的OpenTelemetry

    与收藏家一起奔跑使用此模型,Java应用程序将跟踪和度量标准发送到收集器,该收集器将其转发到Elastic APM。 docker-compose -f run-with-collector.yaml up -d在没有收集器的情况下运行使用此模型,Java应用程序将...

    asp.net安全应用程序开发

    ASP.NET是微软公司推出的用于构建Web应用程序的框架,它提供了丰富的功能和强大的工具,使得开发者可以高效地构建动态网站、Web服务以及企业级应用。然而,随着互联网技术的发展,网络安全问题变得越来越重要,尤其...

Global site tag (gtag.js) - Google Analytics