前言
最近我们公司的部分。净核心的项目接入了耶格,也算是稍微完善了一下。网团队的技术栈。
至于为什么选择贼鸥而不是天行道,这个问题我只能回答,大佬们说了算。
前段时间也在CSharpCorner写过一篇类似的介绍使用ASP。网核心和耶格探索分布式跟踪。
下面回到正题,我们先看一下贼鸥的简介
贼鸥的简单介绍
贼鸥是超级的开源的一个分布式追踪的工具,主要为基于微服务的分布式系统提供监测和故障诊断。包含了下面的内容
分布式上下文传播分布式事务监控根本原因分析服务相关性分析性能/延迟优化下面就通过一个简单的例子来体验一下。
示例
在这个示例的话,我们只用了jaegertracing/一体机这个码头工人的镜像来搭建,因为是本地的开发测试环境,不需要搭建额外的存储,这个感觉还是比较贴心的。
我们会用到两个主要的框架包
贼鸥这个是官方的客户端OpenTracing .贡献于网络核心网。非官方这个是对。网核心探针的处理,从开放跟踪-contrib/cs harp-net核心这个项目移植过来的(这个项目并不活跃,只能自己做扩展)然后我们会建两个应用程序接口的项目,一个是服务,一个是服务。
其中服务会提供一个接口,从缓存中读数据,如果读不到就通过英孚核心去从数据库中读,然后写入缓存,最后再返回结果。
服务会通过客户端去调用服务的接口,从而会形成调用链。
开始之前,我们先把docker-compose.yml配置一下
版本: ' 3.4 '服务s : a服务:映像: $ { DOCKER _ REGISTRY-} a服务构建:上下文:DOCKER文件: a服务/DOCKER文件端口:-' 9898:80 ' dependency _ :-Jager服务-b服务网络:后端: b服务:映像: $ { DOCKER _ REGISTRY-} b服务构建:上下文:Dockerfile : b服务/Dockerfile端口:-' 9899:80 ' depends _ :-Jager服务网络:后端: Jager服务:映像3: jaegertracing/一体机:最新环境:-COLLECTOR _ ZIPKIN _ HTTP _ PORT=9411 PORT :-' 5775:577然后就在两个项目的启动加入下面的一些配置,主要是和贼鸥相关的。
public void ConfigureServices(IServiceCollection services){//others.//添加opentracing服务addpentracing();//添加耶格追踪器。服务AddSingletonITracer(ServiCe Provider={ string ServiCe name=ServiCe Provider .GetRequiredServiceIHostingEnvironment().ApplicationNamevar记录器工厂=服务提供商.GetRequiredServiceILoggerFactory();var采样器=新的const采样器(样本:为真);var reporter=new RemoteReporter .Builder().带记录器工厂(记录器工厂)。WithSender(新UdpSender('jagerservice ',6831,0)).build();var tracer=新tracer .生成器(服务名)。带记录器工厂(记录器工厂)。带有取样器(取样器)。记者build();GlobalTracer .注册(跟踪器);返回跟踪器;});}这里需要注意的是我们要根据情况来选择采样器,演示这里用了最简单的常量采样器。
回到服务这个项目,我们添加数据库和轻松缓存的相关支持。
public void ConfigureServices(IServiceCollection services){//添加一个InMemory-Sqlite DB来显示EFCore跟踪。服务。AddEntityFrameworkSqlite()。AddDbContextBDbContext(选项={ var connectionStringBuilder=new SqliteConnectionStringBuilder { data source=' : memory : ',Mode=SqliteOpenMode。内存,缓存=SqliteCacheMode。共享};var connection=new SqliteConnection(connectionStringBuilder。ConnectionString);连接。open();连接。EnableExtensions(真);选项。UseSqlite(连接);});//在内存提供程序中添加EasyCaching。服务。addeasychapping(options={ options。UseInMemory(' m1 ');});}然后控制器更简单。
//GET API/values[HttpGet]public async tasiactionresult GetAsync(){ var provider=_ provider factory。getcachingProvider(' m1 ');var obj=等待提供程序。GetAsync('mykey ',async ()=await _dbContext。DemoObjs . ToListAsync(),TimeSpan。从秒(30));返回Ok(obj);}AService只是通过HttpClient调用上面的接口。
//GET API/values[HttpGet]public async Taskstring GetAsync(){ var RES=wait getdemasync();返回res} private async TaskString GetDemoasync(){ var client=_ client factory。create client();var request=new Httprequestmessage { Method=HttpMETHoD。Get,RequestURi=new Uri($ ' http://b service/API/values ')};var响应=等待客户端。SendAsync(请求);回应。EnsureSuccessStatusCode();var body=等待响应。content . ReadAsStringAsync();返回体;}如果你到了这里,代码就可以了。我们来看看效果。
通过http://localhost :9898/API/values/多次访问a服务
我大概能得到这样的结果
然后转到Jaeger的界面,我们可以看到这两个服务已经注册了。
选择A和B中的一个进行搜索,可以看到如下结果
这是最外层,您可以看到这些请求的一些宏信息。
让我们选择界面上的最后一个,也就是第一个请求,进去看看细节
从上图大概可以看出做了哪些操作,当请求来到AService时,它向BService发起一个HTTP请求,而BService首先通过easy cache获取缓存,显然缓存中没有数据,所以读取数据库。
与其他请求相比,可以发现缺少搜索数据库的步骤。这就是为什么顶部有10个跨度,而底部只有8个跨度。
让我们看一下这两个请求的比较图。
上图中的红色和绿色块是两个请求之间的区别。
回过头来看看其他细节,你会发现类似下面这样的东西
日志相关的东西很多,在这里可能没有太大的实际作用。我们可以调整日志级别,防止被写入Jaeger。
或者通过以下方法进行过滤
服务。附加赛车(新系统。collections . generic . dictionary string,LogLevel{ {'AService ',LogLevel。信息} });最后是依赖图。
写在最后
虽然耶格使用简单,但也是美中不足。不过Jaeger应该不会背这个锅,主要是因为很多常用的库不直接支持Diagnostic,所以还是有几个东西可以监控的。
然而,ClrProfiler。在github中发现了Trace项目,可以用来解决上述问题。
最后,本文的示例代码
耶格演示
摘要
以上就是本文的全部内容。希望本文的内容对大家的学习或工作有一定的参考价值。谢谢你的支持。