9

[Stardust]星尘分布式全链路监控

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzAwNTMxMzg1MA%3D%3D&%3Bmid=2654082115&%3Bidx=1&%3Bsn=bc4023314b8e54c2e9a1d4a6fb7f06a2
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

随着业务的发展,微服务系统会变得越来越大,各个服务之间的调用关系也会日趋复杂。一个WebApi请求,后方可能经历多个微服务以及数据库和MQ操作,在这个调用过程中,可能因为某一个服务节点出现延迟或者失败,而导致整个请求失败,此时极为需要全链路的调用监控。星尘Stardust提供了分布式全链路监控的解决方案。

星尘监控功能

星尘分布式全链路监控,主要功能点如下:

  • 功能强大 。能够埋点统计调用次数、错误数、耗时等,适用于Web接口、RPC接口、数据库访问、Redis访问、消息队列访问等场景;

  • 简单易用 。只有一个服务端和Web控制台,支持多种数据库(MySql/SQLite/Postgresql/SqlServer),免安装,解压后配置数据库连接即可跑起来;

  • 超低投入 。计算能力下沉,无需ES等重型数据库,避免了大量的IT基础设施投入,1台2C4G的服务器和1台2C4G的MySql足够支持80多个应用每天4亿多的埋点数据;

  • 多维度分析 。丰富的实时计算经验,按照应用、类别、埋点等多个维度进行实时分析,支持月度、每天、小时、5分钟等多种时间刻度,永久保存分析统计数据,主要接口趋势图等同于业务趋势;

  • 监控告警 。支持按照应用配置告警阈值和告警机器人(企业微信、钉钉);

  • 业界标准 。基于业界标准OpenTracing来设计,跨应用跟踪基于W3C的TraceContext来设计,支持任意语言开发的应用接入,支持不同语言应用系统的链路集成;

(应用监控趋势图)

uINrUvZ.png!mobile

(跨应用全链路监控,Android客户端、WebApi、数据库、Redis、消息队列、用户自定义埋点)

yEFRJjf.png!mobile

部署星尘服务端

源码:https://github.com/NewLifeX/Stardust

国内:https://gitee.com/NewLifeX/Stardust

可以下载源码,编译StarServer/StarWeb并得到两个输出,标准.NET5.0应用。

StarServer是星尘服务端 ,默认端口6600,可以通过aspnetcore的urls参数调整端口。服务端以webapi形式接收处理StarAgent星尘代理或者其它星尘客户端的数据请求,其中一部分接口属于监控子系统,接收埋点应用上报的链路监控数据。为提升系统可用性,建议服务端采用双节点部署,业务应用集成星尘客户端时,支持配置逗号分隔的多节点地址,来实现故障转移,例如:“ http://star.newlifex.com:6600,http://106.14.11.143:6600

73em2i6.png!mobile

StarWeb是星尘Web管理平台 ,默认端口5000,可以通过aspnetcore的urls参数调整端口。管理平台是一个基于魔方开发的web后台系统,用于管理查看节点和应用埋点数据。Web管理平台仅用于查看数据和修改配置,无需多节点部署。

NJFRzmF.png!mobile

星尘支持多种数据库(MySql、SQLite、SqlServer、Oracle、Postgresql),默认SQLite。主要连接名如下:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "Stardust": {
      "connectionString": "Data Source=..\\Data\\Stardust.db",
      "providerName": "SQLite"
    },
    "Node": {
      "connectionString": "Data Source=..\\Data\\Node.db",
      "providerName": "SQLite"
    },
    "NodeLog": {
      "connectionString": "Data Source=..\\Data\\NodeLog.db",
      "providerName": "SQLite"
    },
    "Monitor": {
      "connectionString": "Data Source=..\\Data\\Monitor.db",
      "providerName": "SQLite"
    },
    "MonitorLog": {
      "connectionString": "Data Source=..\\Data\\MonitorLog.db",
      "providerName": "SQLite"
    }
  }
}

实际生产环境中,星尘使用2C4G的MySql数据库,2C4G的服务器,支撑了80多个应用系统的埋点数据,每天共4亿多次调用跟踪。

使用监控系统

星尘系统演示:http://star.newlifex.com

星尘服务端试用版:http://star.newlifex.com:6600/

应用跟踪器

应用监控,应用跟踪器,管理着所有连接到星尘的监控埋点应用,默认自动添加新应用。

FJB3637.png!mobile

  • 启用,如果禁用,星尘将不再接受该应用提交的埋点数据;

  • 采样周期,默认每60秒上传一次采样数据;

  • 最大正常采样数,每个采样周期中,每个埋点选择的采样数据明细,用于建立调用链路;

  • 最大异常采样数,每个采样周期中,每个埋点选择的异常采样数据明细,用于分析系统错误;

应用统计

每个应用每天的总调用数、错误数、平均耗时、最大最小耗时,分类调用数(如接口数、Http请求、数据库、消息队列、Redis缓存、用户自定义埋点)

u222aiB.png!mobile

点击应用名,进入应用每日视图,可以看到该应用在这一天中,每一个操作名/埋点(接口)的调用情况,包括次数、错误数、耗时等。点击这里的种类,可以过滤只查看该类埋点操作的数据,不同种类埋点操作,采用不同颜色显示。

63qq6bz.png!mobile

再次点击应用名,可以看到该应用每天的整体调用情况

uINrUvZ.png!mobile

埋点跟踪统计

点击操作名(埋点/接口),可以查看该埋点操作近90天的每日统计数据,主要有调用次数、错误数、耗时等。上方的“7天”,可以查看该埋点仅7天的每小时统计数据。上方的“24小时”,可以查看该埋点近24小时的每5分钟统计数据,5分钟数据比较多,默认只会保留3天,可以在服务端配置文件中调整。

fm6ju2V.png!mobile

全链路追踪

每个埋点数据行,都带有“跟踪”链接,可以查看该埋点的某一次调用链路。

yEFRJjf.png!mobile

如上图,同一个调用链上的多次埋点,具有相同traceId,跟踪视图显示该traceId的前后调用关系,甚至跨多个应用系统,穿越http接口和消息队列。鼠标移到埋点操作名上面,可以看到该埋点的数据标签,或者异常信息。例如,数据库埋点的数据标签就是sql语句,消息队列埋点的数据标签就是消息内容。

链路追踪明细数据默认保存3天,可以在星尘服务端配置文件调整。

异常分析

对于有错误次数的埋点,可以从总次数点击进去,找到错误采样,然后进行跟踪查看。如果有多次错误采样,不方便查找,可以从埋点跟踪统计进入五分钟视图后再找。

ZnemQbJ.png!mobile

应用接入监控系统

微服务系统中的调用采样数据及其庞大,星尘监控通过计算能力下沉来解决这个问题。在业务系统埋点模块内部对埋点数据进行初步聚合,再挑选若干采样数据,在每个采样周期(默认60秒)结束后批量上传到星尘服务端的收集器。收集器落库保存数据后,再次进行聚合,并进行级联统计分析。

任何项目想要接入星尘监控,都需要从nuget中引用 NewLife.Stardust 组件库,实例化StarTracer跟踪器。

星尘监控支持WebApi、HttpClient、Redis、XCode、AntJob等场合的自动埋点追踪,也支持用户自定义埋点。

WebApi应用接入监控

netcore项目在Startup的ConfigureServices中配置引入

public void ConfigureServices(IServiceCollection services)
{
    var set = Stardust.Setting.Current;
    if (!set.Server.IsNullOrEmpty())
    {
        // APM跟踪器
        var tracer = new StarTracer(set.Server) { Log = XTrace.Log };
        DefaultTracer.Instance = tracer;
        ApiHelper.Tracer = tracer;
        DAL.GlobalTracer = tracer;
        TracerMiddleware.Tracer = tracer;
        services.AddSingleton<ITracer>(tracer);
    }
    services.AddControllersWithViews();
    // 引入魔方
    services.AddCube();
}

从配置文件Config/Star.config中读取Server字段,初始化星尘跟踪器。也可以代码写死或者从配置中心读取地址,支持配置逗号分隔的多节点地址,来实现故障转移,例如:“ http://star.newlifex.com:6600,http://106.14.11.143:6600 ”。

services.AddSingleton<ITracer>(tracer) 直接注入跟踪器实例,便于后面集成使用,推荐使用。

DefaultTracer.Instance 是静态属性,用于没有DI的较老代码的接入,不推荐使用。

ApiHelper.Tracer 开放所有HttpClient扩展的埋点追踪。

DAL.GlobalTracer 开放XCode所有数据库访问的埋点追踪。

TracerMiddleware.Tracer 对所有Web请求进行埋点追踪。

Web应用跟踪视图如下

JVJNraa.png!mobile

消息队列应用接入监控

.NET最爱的Redis消息队列, NewLife.Redis 集成了链路追踪,仅需要在实例化FullRedis对象时,指定Tracer属性。

var redis = new FullRedis { Tracer = tracer, Timeout = 15000, Retry = 5, Log = XTrace.Log };

此外, NewLife.RocketMQNewLife.MQTT 都集成了链路追踪支持。

消息队列跟踪视图如下

zeqUBnr.png!mobile

数据调度应用接入监控

蚂蚁调度 AntJob 集成了链路追踪,仅需要在实例化调度器时指定Tracer属性。

var set = AntSetting.Current;
var server = _getConfig("antServer");
if (!server.IsNullOrEmpty())
{
    set.Server = server;
    set.Save();
}
// 实例化调度器
var sc = new Scheduler
{
    Tracer = DefaultTracer.Instance,
    // 使用分布式调度引擎替换默认的本地文件调度
    Provider = new NetworkJobProvider
    {
        Server = set.Server,
        AppID = set.AppID,
        Secret = set.Secret,
        Debug = false
    }
};

数据调度应用跟踪视图如下

Rz6z6vj.png!mobile

用户自定义埋点

在关键业务方法内部,我们需要做一些自定义埋点。通过DI注入或者DefaultTracer.Instance拿到ITracer对象,借助NewSpan方法,即可得到一个埋点实例ISpan,参数就是埋点操作名,span开始到释放就是这一次埋点的耗时。

using var span = _tracer?.NewSpan("CreateOrder", orderModel);
try
{
    //todo CreateOrder
}
catch (Exception ex)
{
    span?.SetError(ex, null);
    throw;
}

如上,使用using语法,让span离开作用域时自动Dispose销毁,计算耗时。NewSpan第二个参数是数据标签Tag,如果这一次埋点span有幸成为采样对象送给星尘服务端,那么Tag将会在链路追踪视图里面得以显示(鼠标移到操作名上)。

如果业务代码抛出异常,需要调用SetError方法指定这一次埋点为异常采样,并设置ex异常信息,该信息会送给星尘服务端,用于查看异常详情。

SetError 不是必须的,如果异常时不调用SetError,还是会记入监控统计,只是认为这次调用成功,并且拿不到异常信息。此时有最简化的自定义埋点代码:

using var span = _tracer?.NewSpan("CreateOrder", orderModel);

NewSpan会在进程中建立埋点的父子关系,无需用户处理。而跨应用集成调用链,则需要一些额外操作。

常见注入和提取扩展

iEBVz2R.png!mobile

调用另一个系统的WebApi时,按照W3C标准,需要在Http请求头中加上 traceparent ,内容是 span.ToString(),格式: 00-traceId-spanId-00

spanId是埋点唯一标识,一般是16字符hex编码;

traceId是链路唯一标识,一般是32字符hex编码,具有相同traceId的埋点采样,构成一个完整调用链;

调用方通过span.Attach把span注入到http请求头,接收方从http请求头中解码得到traceId,魔方的 TracerMiddleware.cs 中有实现该功能。该方案使得不同应用的埋点操作具有相同的链路标识traceId,从而构成一个完整调用链。

NewLife.Redis消息队列的跨系统集成,本质上是在发布消息时,向json集合中注入一个traceparent的字段,消费时读取,从而共用traceId,构成完成调用链。

从图片库选择


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK