apm php zipkin,【教程】如何作apm客户端(关键字:Zipkin、Jaeger、SkyWalking、OpenTracing)...

随着微服务架构的流行,一次请求每每须要涉及到多个服务,所以服务性能监控和排查就变得更复杂。APM所以而生。java

目前,市面上的APM服务端已经有了很是多的实现。好比Zipkin、Jaeger、SkyWalking、Elastic APM等(Pinpoint并不支持OpenTracing,因此咱们不介绍)。git

本教程仅提供一些开发思路,对技术要求较高,由于大部分须要涉及到对相应组件源码的理解。所有源码均可以在github上找到。github

本次选择Jaeger做为服务端示例。主要内容以下。spring

第一部分api

在第一部分,咱们来看一下apm的关键信息和一些概念性的东西,为后面的示例作准备。在这里,咱们简单的描述了jaeger是如何安装的,也是一些准备工做。bash

第二部分架构

使用一个简单的java程序,来讲明如何使用OpenTracing api进行trace的生成,并演示一个带有二个节点的调用链生成。并发

第三部分app

使用OkHttp3和SpringBoot,来演示如何实现一个分布式调用。本文依然是使用底层的api进行构建,对开发感受好的到此应该可以应对各类场景。分布式

第四部分

以SpringCloud为例,说明微服务的调用链生成逻辑。因为各类调用内容较多,咱们仅以比较流行的Feign调用来讲明其原理。 SpringCloud的实现已经有了比较好的轮子,考虑的也比较全面,能够参考其源码进行分析。

若是你在开发本身的中间件,或者作一些集成性的工做,本教程可以让你快速给本身的组件加入apm功能。前提是,你的api兼容OpenTracing协议。

总体介绍

对于监控体系和apm链路,小姐姐味道公众号有更加详细的描述,建议先读一下。

如下仅简要说明一下调用链的主要因素。

调用链主要因素

数据收集部分

主要用于多样化的数据收集,为数据分析作准备。要求易用好用侵入尽可能小(开发工做量),而且在极端状况下(如收集组件不可用)不能对业务有任何影响。能够看到此部分的开发量是巨大的,尤为是须要集成Nginx上下游、基础组件多样、技术栈多样的状况下。

数据分析部分

主要有实时分析与线下分析。通常,实时分析的价值更大一些,主要产出如秒级别的调用量、平均响应时间、TP值等。另外,调用链(Trace)须要存储全量数据,一些高并发大埋点的请求,会有性能问题。

监控报警

此部分利用数据分析的产出,经过短信邮件等形式,通知订阅人关注。监控报警平台应尽可能向devops平台靠拢,包括自主化服务平台。

为何选用jaeger

jaeger的开发较为活跃,并且它的模块划分是比较灵活的。在数据量很是大的状况下,数据是能够先用kafka缓冲一下的(同时为接入各类流分析平台作足了准备)。这些内容,咱们在jaeger安装的部分顺便说明。

扩展方式

若是你的项目使用了SpringBoot,是很是方便进行扩展的。如下内容不止一次提起,读过的请忽略。

咱们接下来实现的功能是:任何加了 @OwlTrace注解的方法,都将产生一条调用链信息。

首先,咱们要定义一个注解:

import java.lang.annotation.*;

@Target({ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface OwlTrace {

}

复制代码

而后,实现其处理类。代码经过AOP对Spring管理的Bean进行拦截,很是简单的实现了Trace信息的构造。代码以下:

import io.opentracing.Span;

import io.opentracing.Tracer;

import io.opentracing.tag.Tags;

import lombok.extern.slf4j.Slf4j;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.Around;

import org.aspectj.lang.annotation.Aspect;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Lazy;

import java.util.LinkedHashMap;

import java.util.Map;

@Configuration

@Slf4j

public class OwlTraceAutoConfiguration{

static final String TAG_COMPONENT = "java";

@Autowired

@Lazy

Tracer tracer;

@Bean

public TracingAspect pxTracingAspect(){

return new TracingAspect();

}

@Aspect

class TracingAspect{

@Around("@annotation(com.sayhiai.arch.trace.annotation.OwlTrace)")

public Object pxTraceProcess(ProceedingJoinPoint pjp) throws Throwable{

Span span = null;

if (tracer != null) {

final String cls = pjp.getTarget().getClass().getName();

final String mName = pjp.getSignature().getName();

span = tracer.buildSpan(cls + "." + mName)

.withTag(Tags.COMPONENT.getKey(), TAG_COMPONENT)

.withTag("class", cls)

.withTag("method", mName)

.startActive(false)

.span();

}

try {

return pjp.proceed();

} catch (Throwable t) {

Map exceptionLogs = new LinkedHashMap<>(2);

exceptionLogs.put("event", Tags.ERROR.getKey());

exceptionLogs.put("error.object", t);

span.log(exceptionLogs);

Tags.ERROR.set(span, true);

throw t;

} finally {

if (tracer != null && span != null) {

span.finish();

}

}

}

}

}

复制代码

最后,根据Spring的加载方式,将路径添加到src/main/resources/META-INF/spring.factories中:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

arch.trace.core.owl.OwlTraceAutoConfiguration,\

arch.trace.core.log.LoggingAutoConfiguration

复制代码

将组件打成jar包,一个spring boot starter就实现了。

使用

application.properties

确保开了AOP

# AOP

spring.aop.auto=true

spring.aop.proxy-target-class=true

opentracing.jaeger.log-spans=true

opentracing.jaeger.udp-sender.host=192.168.3.237

opentracing.jaeger.udp-sender.port=5775

复制代码

End

接下来,咱们将逐步进入客户端api的开发之中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值