您现在的位置是:网站首页> 编程资料编程资料
.NET6接入Skywalking链路追踪详细过程_实用技巧_
2023-05-24
315人已围观
简介 .NET6接入Skywalking链路追踪详细过程_实用技巧_
.NET6接入Skywalking链路追踪完整流程
一、Skywalking介绍
Skywalking是一款分布式链路追踪组件,什么是链路追踪?
随着微服务架构的流行,服务按照不同的维度进行拆分,一次请求往往需要涉及到多个服务。互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发、可能使用不同的编程语言来实现、有可能布在了几千台服务器,横跨多个不同的数据中心。
然后微服务面临了这些问题:
- 某个核心服务挂了,导致大量报错,如何快速确定哪里出了问题?
- 用户请求响应延迟高,怎么确定是哪些服务导致的?
- 应用程序有性能瓶颈,怎样确定瓶颈在哪里?
- 如何准实时的了解应用部署环境(CPU、内存、进程、线程、网络、带宽)情况,以便快速扩容/缩容、流量控制、业务迁移
- 如何统计各个调用的性能指标,比如:吞吐量(TPS)、响应时间及错误记录等
分布式链路跟踪系统就是为了解决这些问题应运而生。
分布式链路追踪组件
- 阿里巴巴鹰眼(EagleEye)
- 美团CAT
- 京东Hydra
- Twitter Zipkin (Java经常用到) 【.NET Java】
- Apache SkyWalking (APM) 【go,python,.NET, Java】
- Pinpoint(APM)
.NET用的最多的两款是SkyWalking、Zipkin。这里介绍Skywalking使用。
Skywalking有哪些功能?
- 多种监控手段。可以通过语言探针和 service mesh 获得监控是数据。
- 多个语言自动探针。包括 Java,.NET Core 和 Node.JS。
- 轻量高效。无需大数据平台,和大量的服务器资源。
- 模块化。UI、存储、集群管理都有多种机制可选。
- 支持告警。
- 优秀的可视化解决方案。
**Skywalking整体架构 **

整个架构,分成上、下、左、右四部分:
- 探针基于不同的来源可能是不一样的, 但作用都是收集数据, 将数据格式化为 SkyWalking 适用的格式.
- 平台后端是一个支持集群模式运行的后台, 用于数据聚合, 数据分析以及驱动数据流从探针到用户界面的流程. 平台后端还提供了各种可插拔的能力, 如不同来源数据(如来自 Zipkin)格式化, 不同存储系统以及集群管理. 你甚至还可以使用观测分析语言来进行自定义聚合分析.
- 存储是开放式的. 你可以选择一个既有的存储系统, 如 ElasticSearch, H2 或 MySQL 集群(Sharding-Sphere 管理), 也可以选择自己实现一个存储系统. 当然, 我们非常欢迎你贡献新的存储系统实现.
- 用户界面对于 SkyWalking 的最终用户来说非常炫酷且强大. 同样它也是可定制以匹配你已存在的后端的
Tracing、Logging和Metrics
在微服务领域,很早以来就形成了Tracing、Logging和Metrics相辅相成,合力支撑多维度、多形态的监控体系,三类监控各有侧重:
Tracing:它在单次请求的范围内,处理信息。 任何的数据、元数据信息都被绑定到系统中的单个事务上。例如:一次调用远程服务的RPC执行过程;一次实际的SQL查询语句;一次HTTP请求的业务性ID;
Logging:日志,不知道大家有没有想过它的定义或者边界。Logging即是记录处理的离散事件,比如我们应用的调试信息或者错误信息等发送到ES;审计跟踪时间信息通过Kafka处理送到BigTable等数据仓储等等,大多数情况下记录的数据很分散,并且相互独立,也许是错误信息,也许仅仅只是记录当前的事件状态,或者是警告信息等等。
Metrics:当我们想知道我们服务的请求QPS是多少,或者当天的用户登录次数等等,这时我们可能需要将一部分事件进行聚合或计数,也就是我们说的Metrics。可聚合性即是Metrics的特征,它们是一段时间内某个度量(计数器或者直方图)的原子或者是元数据。例如接收的HTTP数量可以被建模为计数器,每次的HTTP请求即是我们的度量元数据,可以进行简单的加法聚合,当持续了一段时间我们又可以建模为直方图。

二、Skywalking搭建
这里用Docker搭建
数据存储用ES,搭建ES
docker run -d -p 9200:9200 -p 9300:9300 --name es -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms128m -Xmx256m" elasticsearch:7.16.3
搭建skywalking-oap服务,这里用的是8.9.1版本,oap服务需要关联ES
docker run --name skywalking-oap \ --restart always \ -p 11800:11800 -p 12800:12800 -d \ -e TZ=Asia/Shanghai \ -e SW_ES_USER= \ -e SW_ES_PASSWORD= \ -e SW_STORAGE=elasticsearch \ -e SW_STORAGE_ES_CLUSTER_NODES=192.168.101.10:9200 \ -v /etc/localtime:/etc/localtime:ro \ apache/skywalking-oap-server:8.9.1
搭建skywalking-ui界面,需要关联oap服务
docker run -d \ --name skywalking-ui \ --restart always \ -p 8080:8080 \ --link skywalking-oap:skywalking-oap \ -e TZ=Asia/Shanghai \ -e SW_OAP_ADDRESS=http://skywalking-oap:12800 \ -v /etc/localtime:/etc/localtime:ro \ apache/skywalking-ui:8.9.1
搭建完成,打开ip:8080查看skywalking界面

三、.NET6接入Skywalking
1、单个服务接入
新建一个.NET6站点,安装Nuget包
SkyAPM.Agent.AspNetCore
Properties下launchSettings.json增加
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "SkyAPM.Agent.AspNetCore", //必须配置
"SKYWALKING__SERVICENAME": "Service1" // 必须配置,在skywalking做标识,服务名称
{ "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { "applicationUrl": "http://localhost:6413", "sslPort": 44308 } }, "profiles": { "NET6AndSkyWalking": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, "applicationUrl": "http://localhost:5025", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "SkyAPM.Agent.AspNetCore", //必须配置 "SKYWALKING__SERVICENAME": "Service1" // 必须配置,在skywalking做标识,服务名称 } }, "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } }如果不在launchSettings.json加,也可以在Program.cs加
Environment.SetEnvironmentVariable("ASPNETCORE_HOSTINGSTARTUPASSEMBLIES", "SkyAPM.Agent.AspNetCore"); Environment.SetEnvironmentVariable("SKYWALKING__SERVICENAME", "Service1");生成skywalking.json文件
1、安装CLI(SkyAPM.DotNet.CLI),cmd命令:
dotnet tool install -g SkyAPM.DotNet.CLI
2、自动生成skyapm.json文件,cmd命令:
1.dotnet skyapm config [service name] [server]:11800 2.eg: dotnet skyapm config service1 192.168.101.10:11800
执行了命令会生成skywalking.json文件,把skywalking.json放到项目根目录,设置较新复制到输出目录,然后修改ServiceName设置为项目名,和上面的SKYWALKING__SERVICENAME一致。
skyapm.json文件
{ "SkyWalking": { "ServiceName": "service1", "Namespace": "", "HeaderVersions": [ "sw8" ], "Sampling": { "SamplePer3Secs": -1, "Percentage": -1.0 }, "Logging": { "Level": "Information", "FilePath": "logs\\skyapm-{Date}.log" }, "Transport": { "Interval": 3000, "ProtocolVersion": "v8", "QueueSize": 30000, "BatchSize": 3000, "gRPC": { "Servers": "192.168.101.10:11800", "Timeout": 10000, "ConnectTimeout": 10000, "ReportTimeout": 600000, "Authentication": "" } } } }SamplePer3Secs:每三秒采样的Trace数量 ,默认为负数,代表在保证不超过内存Buffer区的前提下,采集所有的Trace
Percentage:采样率,默认负数,采集全部,其它数值格式:0.5,0.8...
这时候运行项目已经有基本的链路追踪功能了!
试一下运行,项目,然后看链路追踪界面(注意一下时间搜索的时间范围向后选一些),这个可能会延迟几秒钟才显示出来。
仪表盘

追踪

自定义链路日志
自定义链路日志可以在重要的地方加上,这样就能知道程序跑到这个地方时的关键信息了。
public class HomeController : Controller { private readonly IEntrySegmentContextAccessor _segContext; public HomeController(IEntrySegmentContextAccessor segContext) { _segContext = segContext; } public IActionResult Index() { return View(); } /// /// 自定链路日志 /// /// public string SkywalkingLog() { //获取全局traceId var traceId = _segContext.Context.TraceId; _segContext.Context.Span.AddLog(LogEvent.Message("自定义日志1")); Thread.Sleep(1000); _segContext.Context.Span.AddLog(LogEvent.Message("自定义日志2")); return traceId; } }调用/Home/SkywalkingLog后Skywalking界面效果,看到了程序添加的日志

2、多服务追踪
链路追踪在多服务的时候才能体现它的精髓,一个链路能跟踪到请求涉及的所有服务。
这里新增一个.NET6的web项目,前面的步骤和上面的Service1一样,只是把服务名改为Service2。
然后在Service2增加一个接口 /UserInfo/GetUserInfo
public class UserInfoController : Controller { private readonly IEntrySegmentContextAccessor _segContext; public UserInfoController(IEntrySegmentContextAccessor segContext) { _segContext = segContext; } [HttpGet] public string GetUserInfo(string userId) { string result = $"userId:{userId},userName:张三"; _segContext.Context.Span.AddLog(LogEvent.Message(result)); return result; } }然后在Service1增加一个接口/Home/GetUser调用Service2
后在Service2增加一个接口 /UserInfo/GetUserInfo
public class UserInfoController : Controller { private readonly IEntrySegmentContextAccessor _segContext; public UserInfoController(IEntrySegmentContextAccessor segContext) { _segContext = segContext; } [HttpGet] public string GetUserInfo(string userId) { string result = $"userId:{userId},userName:张三"; _segContext.Context.Span.AddLog(LogEvent.Message(result)); return result; } }然后在Service1增加一个接口/Home/GetUser调用Service2
public async TaskGetUser() { var client = new HttpClient(); //调用Service2 var response=await client.GetAsync("http://localhost:5199/UserInfo/GetUserInfo"); var result = await response.Content.ReadAsStringAsync(); return result; }
然后调用Service1的接口/Home/GetUser

然后看链路追踪,会显示出对应的Service对应的耗时,点进去还能看到当前服务的详情和打的日志。

多服务的时候还能看到服务之间对应的调用关系

四、微服务网关接入Skywalking
新建一个.NET6的Web项目,引用Nuget包
相关内容
- 使用CefSharp在.Net程序中嵌入Chrome浏览器_实用技巧_
- .Net中的弱引用字典WeakDictionary和ConditionalWeakTable介绍_实用技巧_
- 详解.NET中负载均衡的使用_实用技巧_
- .Net使用Xunit工具进行单元测试_实用技巧_
- .Net使用日志框架NLog_实用技巧_
- 在.NET Core中使用CSRedis的详细过程_实用技巧_
- 在Code First模式中自动创建Entity模型_实用技巧_
- Entity Framework代码优先Code First入门_实用技巧_
- .Net中的不可变集合(Immutable Collection)程序集简介_基础应用_
- 一文掌握.Net core中的缓存_实用技巧_
点击排行
本栏推荐
