通过Zipkin上报 .NET应用数据 示例
基本介绍
Zipkin 是 Twitter 的一个开源项目,基于 Google Dapper 实现。可以使用它来收集各个服务器上请求链路的跟踪数据,并通过它提供的 REST API 接口来辅助我们查询跟踪数据以实现对分布式系统的监控程序,从而及时地发现系统中出现的延迟升高问题并找出系统性能瓶颈的根源。除了面向开发的API接口之外,它也提供了方便的 UI 组件帮助我们直观的搜索跟踪信息和分析请求链路明细,比如:可以查询某段时间内各用户请求的处理时间等。
基本术语
- Span:基本工作单元,例如,在一个新建的span中发送一个RPC等同于发送一个回应请求给RPC,span通过一个64位ID唯一标识,trace以另一个64位ID表示,span还有其他数据信息,比如摘要、时间戳事件、关键值注释(tags)、span的ID、以及进度ID(通常是IP地址) span在不断的启动和停止,同时记录了时间信息,当你创建了一个span,你必须在未来的某个时刻停止它。
- Trace:一系列spans组成的一个树状结构,例如,如果你正在跑一个分布式大数据工程,需要创建一个trace。
- Annotation:用来及时记录一个事件的存在,一些核心 annotations 用来定义一个请求的开始和结束。
zipkin架构
ZipKin可以分为两部分,一部分是zipkin server,用来作为数据的采集存储、数据分析与展示;zipkin client是zipkin基于不同的语言及框架封装的一些列客户端工具,这些工具完成了追踪数据的生成与上报功能。
zipkin 服务流程
部署
version: '3.8' services: elasticsearch: image: elasticsearch:7.9.1 container_name: elasticsearch restart: always ports: - 9200:9200 healthcheck: # test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"] interval: 30s timeout: 10s retries: 3 start_period: 40s environment: - discovery.type=single-node - bootstrap.memory_lock=true - "ES_JAVA_OPTS=-Xms512m -Xmx512m" - TZ=Asia/Shanghai ulimits: memlock: soft: -1 hard: -1 zipkin: image: openzipkin/zipkin:latest container_name: zipkin depends_on: - elasticsearch links: - elasticsearch restart: always ports: - 9411:9411 environment: - TZ=Asia/Shanghai - STORAGE_TYPE=elasticsearch - ES_HOSTS=elasticsearch:9200
1. 创建控制台应用程序 zipkintest
2. 通过 NUGET 引入相关组件
- Microsoft.AspNet.WebApi.OwinSelfHost 最新稳定版 ()
- zipkin4net 1.1.1 ()
3. 添加Startup类 作为zipkin设置和宿主服务设置的主方法(这里 “test” 为给本次痕迹的服务名,可做成配置项)
using Newtonsoft.Json.Serialization; using Owin; using System.Web.Http; using zipkin4net; using zipkin4net.Tracers.Zipkin; using zipkin4net.Transport.Http; namespace zikpintest { internal class Startup { public void Configuration(IAppBuilder appBuilder) { //注册成webapi HttpConfiguration config = new HttpConfiguration(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{action}", defaults: new { id = RouteParameter.Optional } ); appBuilder.UseWebApi(config); var json = config.Formatters.JsonFormatter; json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); var logger = new ConsoleLogger(); // 实现ILogger TraceManager.SamplingRate = 1.0f; // 完全跟踪 var httpSender = new HttpZipkinSender("http://192.168.15.65:9411", "application/json"); // 设置zipkin服务端地址 var tracer = new ZipkinTracer(httpSender, new JSONSpanSerializer()); TraceManager.RegisterTracer(tracer); TraceManager.Start(logger); // 关闭 // TraceManager.Stop(); var trace = Trace.Create(); trace.Record(Annotations.ServerRecv()); trace.Record(Annotations.ServiceName("test")); trace.Record(Annotations.Rpc("GET")); trace.Record(Annotations.ServerSend()); trace.Record(Annotations.Tag("http.url", "<url>")); // adds binary annotation // Trace.Current = trace; } } }
4. 在控制台的Program文件的main方法里面添加启动
using Microsoft.Owin.Hosting; using System; namespace zikpintest { internal class Program { static void Main(string[] args) { string baseAddress = "http://localhost:7400/"; // Start OWIN host using (WebApp.Start<Startup>(url: baseAddress)) { Console.WriteLine("Start server on {0}", baseAddress); Console.ReadLine(); } } } }
5. 添加一个记录过程 ConsoleLogger 类
using System; using zipkin4net; namespace zikpintest { internal class ConsoleLogger : ILogger { public void LogError(string message) { Console.Error.WriteLine(message); } public void LogInformation(string message) { Console.WriteLine(message); } public void LogWarning(string message) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine(message); Console.ResetColor(); } } }
6. 此时 webapi+zipkin 已经注册完成,现添加一个api接口来测试,新建 HomeController 类
using Newtonsoft.Json; using System; using System.Net.Http; using System.Text; using System.Web.Http; namespace zikpintest { public class HomeController : ApiController { [HttpGet] public HttpResponseMessage GetText(int id) { Random random = new Random(); var product = new { id = id, name = "test", ran = random.Next(10000, 99999) }; HttpResponseMessage result = new HttpResponseMessage(); result.Content = new StringContent(JsonConvert.SerializeObject(product), Encoding.GetEncoding("UTF-8"), "application/json"); return result; } } }
7. 启动项目,调用接口
8. 查看zipkin服务端发现,调用痕迹已记录成功