前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在微服务中启用分布式跟踪 | 微服务系列第十篇

在微服务中启用分布式跟踪 | 微服务系列第十篇

作者头像
魏新宇
发布2018-09-30 11:48:14
1.3K0
发布2018-09-30 11:48:14
举报

文章导读

  • 本文仅代表作者的个人观点;
  • 本文的内容仅限于技术探讨,不能作为指导生产环境的素材;
  • 本文素材是红帽公司产品技术和手册;
  • 本文分为系列文章,将会有多篇,初步预计将会有26篇。

一、用OpenTracing解决分布式跟踪问题

跟踪是一种用于监视软件的执行路径、以便进行调试或故障排除的专门的方法。您可能熟悉TRACE日志级别,其中包含有关每个方法调用的信息。跟踪微服务的目标类似于此级别的日志记录。在最高级别,从一个微服务到另一个微服务的跟踪,讲述了事务或请求在通过基于微服务的系统传播时的路径。

分布式跟踪特指跨越微服务边界跟踪请求流。这比单个应用程序中的传统跟踪更具挑战性,因为请求来自完全不同的微服务。但是,在请求可以流经多个服务的微服务环境中,跟踪尤为重要。这是因为跟踪为您提供了有价值的性能数据,您可以使用这些数据有效地识别应用程序瓶颈,错误或其他问题,从而将延迟引入基于微服务的应用程序中。

OpenTracing是一个新的,开放式的应用程序和开源软件包跟踪标准。

OpenTracing项目的既定目标是提供“高质量的分布式跟踪,应用程序员几乎不需要任何仪器工作。”通过为流行的平台提供一致的、富有表现力的、与供应商无关的API,使用OpenTracing可以使开发人员通过简单的配置更改轻松添加或切换跟踪实现。

以下列表包含一些支持OpenTracing规范的更流行的实现

  • Jaeger
  • Appdash
  • Lightstep
  • Hawkular
  • Apache SkyWalking

在OpenTracing中,跟踪是跨度的有向无环图(DAG)。 DAG是边缘显示方向的节点图,没有循环。 Spans是命名的,定时操作,表示该跟踪中的连续工作单元。这个连续的工作单元可以代表对数据库服务的单个调用,也可以代表需要多个下游服务的复杂操作。

参与分布式跟踪的每个微服务都可以创建自己的跨度或跨度。跨度是分层的,这意味着跨子之间可以存在父子关系。这有助于将跟踪数据组织到更大的高级任务中,例如在电子商务Web应用程序中将采购的物品添加到购物车。诸如此类的任务通常表示使用父跨度的多个操作,并且使用子跨度来表示低级粒度操作,例如单个数据库查找或外部服务调用。父跨度可以显式地以串行或并行方式启动其他跨度。在OpenTracing中,甚至可以使用多个父项来建模子跨度。

例如,在MicroProfile会议应用程序中,下图中显示的示例跟踪从Web应用程序客户端通过API网关到调用CouchDB服务的微服务投票端点,然后通过Web应用程序客户端的API网关:

默认情况下,上图中显示的跟踪包含三个单独的跨距。 为每个Web服务调用创建一个跨度。 第一个后续每个后续跨度继承前一个跨度作为其父级。 这意味着Web应用程序调用API网关的范围包括API网关调用微服务投票应用程序所花费的所有时间。 它还包括微服务投票应用程序调用CouchDB服务并将结果返回API网关所需的时间,然后API网关将最终结果返回给Web应用程序。

二、描述MicroProfile OpenTracing API版本1.0

分布式跟踪日志记录的常见协同工具是可以存储分布式跟踪记录的服务。分布式跟踪记录的存储服务通常提供可视化与特定请求流相关联的跨服务跟踪记录的功能。通过使用标准方法跟踪仪器,按照MicroProfile规范编写的微服务能够与作为更大微服务环境一部分的分布式跟踪系统很好地集成。

MicroProfile OpenTracing规范定义了API和实现行为,允许微服务轻松参与启用分布式跟踪的环境。 OpenTracing规范的既定目标解决了在运行时使用分布式跟踪功能轻松修改服务的问题,给定环境中现有的分布式跟踪系统。

为了使分布式跟踪系统有效和可用,您环境中的每个微服务都需要两件事:

  • 必须就跨微服务传输相关ID的机制达成一致。跟踪实现在内部使用关联ID来跟踪来自上游系统的传入请求中已存在的各个跨距。
  • 必须以标准格式生成跟踪记录,这些格式可由公共存储服务用于分布式跟踪记录。

MicroProfile OpenTracing规范没有解决定义,实现或配置底层分布式跟踪系统的问题。 OpenTracing主要关注三个方面:它为开发人员提供了一种简单,标准化,独立于供应商的机制,可以将跟踪引入基于MicroProfile的微服务中,它提供了标准化跟踪数据如何从一个微服务传输到另一个微服务的解决方案,并生成了跟踪数据。标准格式。

MicroProfile OpenTracing实现允许JAX-RS应用程序参与分布式跟踪,而无需开发人员将任何分布式跟踪代码添加到其应用程序中,也无需开发人员了解有关他们部署JAX-RS应用程序的分布式跟踪环境的任何信息。

为了满足这些要求,MicroProfile OpenTracing规范规定所有MicroProfile实现必须自动:

  • 检测并配置类路径上可用的io.opentracing.Tracer实现,以供JAX-RS应用程序使用。
  • 从任何传入的JAX-RS请求中提取SpanContext信息。
  • 为任何传入的JAX-RS请求启动Span,并在请求完成时完成Span。
  • 将SpanContext信息注入任何传出的JAX-RS请求。
  • 为任何传出的JAX-RS请求启动Span,并在请求完成时完成Span。

三、使用OpenTracing将分布式跟踪添加到基于MicroProfile的微服务

默认情况下,在应用程序的依赖项中包含MicroProfile OpenTracing库和io.opentracing.Tracer的实现足以为您的微服务启用分布式跟踪。 在以下示例中,包含MicroProfile OpenTracing API,Jaeger是Tracer的实现。

代码语言:javascript
复制
<dependencies>
	...
	<dependency>
		<groupId>org.eclipse.microprofile.opentracing</groupId>
		<artifactId>microprofile-opentracing-api</artifactId>
	</dependency>
	<dependency>
		<groupId>com.uber.jaeger</groupId>
		<artifactId>jaeger-core</artifactId>
		<version>0.20.0</version>
	</dependency>
	<dependency>		
	<groupId>com.uber.jaeger</groupId>
		<artifactId>jaeger-tracerresolver</artifactId>
		<version>0.20.0</version>
	</dependency>
</dependencies>

使用此默认配置,将自动跟踪所有传入和传出请求。 这意味着您无需编写任何自定义检测代码来支持跟踪,从而大大简化了应用程序代码。

可以使用@Traced注释进一步配置此行为。 这允许您手动定义要跟踪的自定义跨度。

使用@Traced Annotation

应用于类时,@ Traced注释会自动应用于该类的所有方法。 如果@Traced注释应用于类和方法,则应用于该方法的注释配置将覆盖类级别的注释配置。 注释在方法执行开始时开始跨度,并在方法执行结束时完成跨度。

@Traced注释具有以下两个可选参数:

值可以在类或方法级别启用或禁用显式跟踪。 如果在类级别指定了@Traced注释,则使用@Traced(false)注释特定方法以禁用为这些方法创建范围。 默认情况下,该值设置为true。

operationName用于指定span的自定义名称。 如果@Traced注释发现operationName未设置或设置为空字符串,则实现使用默认操作名称,即:

代码语言:javascript
复制
<HTTP method>:<package name>.<class name>.<method name>

以下示例包括在方法上使用@Traced注释:

代码语言:javascript
复制
package com.redhat.training.bookstore.inventory.rest;

...imports excluded...

@Path("/")
@Api("inventory")
public class InventoryResource {

	private final Logger log = LoggerFactory.getLogger(InventoryResource.class);

	@Inject
	private InventoryDatabase db;

	@GET
	@Path("/inventory/{isbn}")
	@Produces(MediaType.APPLICATION_JSON)
	@ApiOperation("Returns the inventory count for a book identified by ISBN")	
       @Traced(value = true, operationName = "getInventory")
	public Response getInventory(@PathParam("isbn") String isbn) {
		log.debug("get Inventory endpoint called");
		for (BookInventory inventory : db.getInventory()) {
			if (isbn.equals(inventory.getIsbn()))
				return Response.ok(inventory,MediaType.APPLICATION_JSON).build();
		}


		return Response.status(404).build();
	}
}

四、使用Jaeger查看跟踪数据

Jaeger是Uber Technologies公开发布的分布式跟踪系统。 Jaeger具有OpenTracing兼容的数据模型,包括Go,Java,Node,Python和C ++中的实现。 Jaeger由多个组件组成,包括Web UI和后端收集代理。

Jaeger Web UI使用流行的开源框架React在Javascript中实现。它提供了应用程序中所有跟踪数据的统一视图,并提供了有用的可视化。 Jaeger后端作为Docker镜像的集合分发。二进制文件支持各种配置方法,包括命令行选项,环境变量和配置文件。

此外,Jaeger还提供了一体化的Docker容器映像。此容器映像专为快速本地测试而设计,可使用内存存储组件启动Jaeger UI,收集器,查询和代理。

启动一体化容器映像的最简单方法是使用以下命令使用发布到DockerHub的预构建映像:

代码语言:javascript
复制
[user@localhost ~]$ docker run -d -e \COLLECTOR_ZIPKIN_HTTP_PORT=9411\
  -p 5775:5775/udp \
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  -p 16686:16686 \
  -p 14268:14268 \
  -p 9411:9411 \
  jaegertracing/all-in-one:latest

然后,您可以导航到http://localhost:16686以访问Jaeger UI。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-09-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大魏分享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档