# get the latest source git clone https://github.com/openzipkin/zipkin cd zipkin # Build the server and also make its dependencies ./mvnw -DskipTests --also-make -pl zipkin-server clean install # Run the server java -jar ./zipkin-server/target/zipkin-server-*exec.jar 无论您以何种方式启动zikpin,请访问 http://your_host:9411以查询跟踪。
按照官方文档说明。 using ZipkinTracer.DependencyInjection; using ZipkinTracer.Owin; public class Startup { public void Configuration(IApplicationBuilder app) { app.UseZipkinTracer(); } public void ConfigureServices(IServiceCollection services) { var config = new ZipkinConfig(new Uri("http://XXX:9411"), request => new Uri("https://yourservice.com")) { Bypass = request => request.GetUri().AbsolutePath.StartsWith("/allowed"), SpanProcessorBatchSize = 10, SampleRate = 0.5 } services.AddZipkinTracer(config); } } //GetUri()方法报错。 改成如下方法: public void Configuration(IApplicationBuilder app) { app.UseZipkinTracer(); } public void ConfigureServices(IServiceCollection services) { var config = new ZipkinConfig(new Uri("http://weixinhe.cn:9411")); services.AddZipkinTracer(config); services.AddZipkinTracer(config); } 客户端调用using ZipkinTracer.Http; public class HomeController : Controller { private readonly IZipkinTracer _tracer; public HomeController(IZipkinTracer tracer) { _tracer = tracer; } public async Task Index() { using (var httpClient = new HttpClient(new ZipkinMessageHandler(_tracer)))) { var response = await httpClient.GetAsync("http://www.google.com"); if (response.IsSuccessStatusCode) { var content = await response.Content.ReadAsStringAsync(); } } return View(); } } 运行程序,报错! 让我们去官网看看问题,issue 里面有人提出了这个问题,Registering zipkin tracer throws an error #10下面有人回复:意思是需要重写中间件。I have the same issue. According to the documentation, the dependencies in the middlewares should be moved into the Invoke method. In this case, the ZipkinMiddleware has to be changed in my opinion.年久失修,作者未回复。但是源码都放在那里了,难道任由其报错而无能为力么?这我不能忍受。所以,下载源码,引用源码项目。开启调试之路。
解决问题
右键查看属性,竟然看不到目标框架。应该是版本太低了。 查看依赖版本是framework4.6和.netstandard 1.3那好办,我们新建一个.netcore2.1版本的项目,然后将tracer的代码都复制过去。 一些复制好并引用后,还是刚才那个错。调试也没有看到哪里报错,只是最终页面报错了。所以我们继续搜索。Cannot consume scoped service 'XXXX' from singleton 'XXX'.
依赖注入的知识普及
.net核心依赖注入生命周期解释无法从Singleton消耗Scoped服务 - ASP.net核心DI范围的一课ASP.net核心中的第三方依赖注入此网站已收集在.NetCore外国一些高质量博客分享,长期保持更新。上面三篇文章普及了一些依赖注入的知识。sorry,这块我研究的很浅。。。这次顺带了解了不少,以后要抽空专门研究一下。Single:单例是一个将持续应用程序整个生命周期的实例。在Web术语中,这意味着在服务的初始请求之后,每个后续请求将使用相同的实例。这也意味着它跨越Web请求(因此,如果两个不同的用户访问您的网站,代码仍然使用相同的实例)。考虑单例的最简单方法是,如果类中有静态变量,则它是跨多个实例的单个值。Scoped:范围内的生命周期对象通常会简化为“每个Web请求一个实例”,但实际上它比实际上更加微妙。无可否认,在大多数情况下,您可以将每个Web请求视为范围对象。您可能会看到的常见问题是每个Web请求创建一次DBContext,或者创建一次NHibernate上下文,以便您可以将整个请求包含在事务中。作用域生存期对象的另一个非常常见的用途是当您要创建每个请求缓存时。 Scoped生命周期实际上意味着在创建的“范围”对象中将是同一个实例。它恰好发生在.net核心中,它在“范围”内包装请求,但您实际上可以手动创建范围Transient:每次请求服务时,都会创建一个新实例。关于上述的类似错误无法从单件服务 #2569中使用作用域服务'AutoMapper.IMapper',有用户评论:这是一个基本的设计约束。你不能让单身人士(Single)依赖于瞬态(Scoped)或范围内(Transient)的物品。这不是容器的错,这些生命周期是不相容的。如果您需要兼容的生命周期,请选择不同的生命周期。Singleton < - Singleton 良好Singleton < - Scoped 糟糕Singleton < - Transient 糟糕Scoped < - Singleton 良好Scoped < - Scoped 良好Scoped < - Transient 良好TRANSIENT < - Singleton 良好Transient < - Scoped 良好在范围内,糟糕在范围外 TRANSIENT< - TRANSIENT 良好所以真的只有两种情况“总是糟糕”,一种情况“有时候很糟糕”。 ASP.NET Core DI使这个非常明确,甚至将工厂方法传递给上下文对象,例如过滤器。过滤器是Singleton,因此您不能拥有构造函数依赖项。相反,您使用传递给过滤器方法的各种XyzContext对象来解析依赖项。上述是十分有价值的评价,先收藏,以后细细品味。有了这些基础知识和良好建议,我们再来回顾下代码。看到前面都是AddSingleton,后面是AddScoped,在上面的建议中是属于糟糕的。虽然不清楚作者的意图,但我们可以先把程序跑起来,以后用熟悉了再来仔细修复。 public static class ServiceCollectionExtensions { public static void AddZipkinTracer(this IServiceCollection services, ZipkinConfig config) { if (config == null) throw new ArgumentNullException(nameof(config)); var maxSize = config.MaxQueueSize <= 0 ? 100 : config.MaxQueueSize; services.AddSingleton(config); services.AddSingleton(new BlockingCollection(maxSize)); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddScoped(); services.AddScoped(); services.AddScoped(); } } 好吧,临时将三个AddScoped 改为 AddSingleton(); 运行项目。又开始报错了。。。。说IZipkinTracer需要一个无参的构造函数。InvalidOperationException: Could not create an instance of type 'ZipkinTracer.IZipkinTracer'. Model bound complex types must not be abstract or value types and must have a parameterless constructor. Alternatively, give the 'tracer' parameter a non-null default value. 继续搜索新的这个错误。