链路跟踪-SkyWalking系列(一)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 链路跟踪-SkyWalking系列(一)

、SkyWalking三大架构模式

①、AOP架构模式

②、插件式架构模式

③、微内核架构模式

一个组件具有高扩展架构的话,需要具有微内核架构/插件式架构/无入侵

架构,例如:

二、skywalking介绍:应用监控和链路跟踪

随着互联网行业的飞速发展,业务规模增长迅速,复杂与过去相比大大提升。与此同时,微服务等技术的蓬勃发展,同样给开发带来不小的运维压力,导致我们经常需要面临这些问题:

①、链路较长:在微服务场景下,整个链路会变得很长,服务出问题时,往往不能第一时间排查出问题。

②、缺少监控:缺少对于服务器,应用组件的实时运行信息,做到心中有数。

③、预警不及时,粒度较大:经常在服务器响应延迟甚至宕机后,才能发现问题,同时粒度较大,无法在接口层面进行预警。

在这种背景下,SkyWalking作为应用监控和链路跟踪的利器,便脱颖而出

基于Agent技术,SkyWalking提供了例如吞吐量,QPS,JVM信息等丰富的指标供参考,做到有效同时地告警,利用其丰富的插件,能帮助我们跟踪Dubbo,ElasticSearch,Redis等这些组件的调用链路。

在这几年,SkyWalking同时也作为Apachc顶级项目,走上了世界的舞台,可以说SkyWalking就是目前APM体系中最受关注的一款软件。通过SkyWalking做了链路跟踪,系统监控,异常告警的落地,解决了开发过程中问题定位慢的痛点。

三、javaAgent探针技术, 使用场景

①、无入侵  链路跟踪

②、无入侵 动态线程池

③、无入侵  TransmitThreadLocal

④、无入侵的  命令行交互模式JVM诊断Arthas

四、分布式系统链路跟踪背景

随着微服务架构的流行,服务按照不同的维度进行拆分,一次请求往往需要涉及到多个服务,互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发,可能使用不同的编程语言来实现,有可能部署在了几千台服务器,横跨多个不同的数据中心,因此,就需要一些可以帮助理解系统的行为,用于分析性能问题的工具,以便发生故障的时候,能够快速定位和解决问题。

全链路监控组件就在这样的问题背景下产生了,最出名的是谷歌公开的论文提到的Google Dapper。想要在这个上下文中理解分布式系统的行为,就 需要监控那些横跨了不同的应用,不同的服务器之间的关联动作。

‘所以,在复杂的微服务架构系统中,几乎每一个前端请求都会形成一个复杂的分布式服务调用链路,一个请求完整的调用链路可能如下图所示:

bd2093249556f26dc18c6131dc5ecca2.png

一个请求完整的调用链路:

那么在业务规模不断增大,服务不断增多以及频繁变更的情况下,面对复杂的调用链路就带来一系列问题:

①、如何快速发现问题?

②、如何判断故障影响范围?

③、如何梳理服务依赖以及依赖的合理性?

④、如何分析链路性能以及实时容量规划?

⑤、吞吐量,根据拓扑可计算相应组件,平台,物理设备的实时吞吐量

⑥、响应时间,包括整体调用的响应时间和各个服务的响应时间等。

⑦、错误记录,根据服务返回统计单位时间异常次数。

全链路性能监控从整体维度到局部维度展示各个指标,将跨应用的所有调用链路性能信息集中展现,可方便度量整体和局部性能,并且方便找到故障产生的源头,生产上可极大缩短故障排查时间。

有了全链路监控工具,我们能够达到:

①、请求链路跟踪,故障快速定位:可以通过调用链路结合业务日志快速定位错误信息。

②、可视化:各个阶段耗时,进行性能分析

③、依赖优化:各个调用环节的可用性,梳理服务依赖关系以及优化

④、数据分析,优化链路:可以得到用户的行为路径,汇总分析应用在很多业务场景。

五、常见的监控工具对比:

237ac90a6bb6f5ee09dfc9dd2da27493.png

六、SkyWalking的特点

①、性能好:针对单实例5000tps的应用,在全量采集的情况下,只增加10%的CPU开销

②、支持多语言探针

③、无入侵,支持自动以及手动探针

自动探针:java支持的中间件,框架与类库列表

手动探针:OpenTrackingApi,@Trace注解,traceId集成到日志中

七、完成SkyWaking平台的部署

用容器启动的,准备好docker-compose文件


version: "3.5"#容器列表services:  elasticsearch:     image: elasticsearch:7.9.0     container_name: elasticsearch     restart: always     ports:       - 9200:9200     volumes:      - ./elasticsearch7/logs:/usr/share/elasticsearch/logs      - ./elasticsearch7/data:/usr/share/elasticsearch/data     environment:       - "discovery.type=single-node"  #es单机模式       - "ES_JAVA_OPTS=-Xms512m -Xmx512m"       - "TZ=Asia/Shanghai"       - "TAKE_FILE_OWNERSHIP=true"   #volumes 挂载权限 如果不想要挂载es文件改配置可以删除     ulimits:       memlock:         soft: -1         hard: -1     networks:       monitor-network:         aliases:          - elasticsearch  #数据的接入和聚合。  skywalking-oap:     image: apache/skywalking-oap-server:8.0.1-es7     container_name: skywalking-oap     depends_on:       - elasticsearch     links:       - elasticsearch     restart: always     ports:#SkyWalking搭建的IP和端口       - 11800:11800       - 12800:12800     environment:       - "SW_STORAGE=elasticsearch7"  # 指定ES版本会把数据持久化到es       - "SW_STORAGE_ES_CLUSTER_NODES=elasticsearch:9200"        - "TZ=Asia/Shanghai"   #时区设置       - "TAKE_FILE_OWNERSHIP=true"  #解决 volumes 挂载权限问题     networks:                           monitor-network:         aliases:          - skywalking-oap  # dashboard  skywalking-ui:     image: apache/skywalking-ui:8.0.1     container_name: ui     depends_on:       - skywalking-oap     links:       - skywalking-oap     restart: always     ports:       - 13800:8080     environment:       # 拿数据用的12800端口,通过后台服务aop拿数据       - "SW_OAP_ADDRESS=skywalking-oap:12800"       - "TZ=Asia/Shanghai"     networks:       monitor-network:         aliases:          - skywalking-ui
# docker network create monitor-networknetworks:  monitor-network:    external:      name: "monitor-network"

然后部署,docker-compose  up  -d

2a1a9caff7982f198a8ef5cf9dc942e6.png

docker ps:可以看到容器的启动:

2d11292ec85df04f01b9ad57eec4b49c.png

然后访问:

c96cc0e90a43642095edcb1be0ca4d63.png

七、一键完成带skywalkingAgent的SpringBoot应用的部署

(1)、如何进行SpringBoot,java应用的链路数据接入

356a8932b269a1cefb65eb342f065e3c.png


因为skywalking采用无侵入的探针模式,那什么是探针呢?探针就是jvm提供了一套专门的接口给开发者使用,JVMTI这套接口是双向接口,对应用程序理解为客户端,也叫做探针,对JVM来说是目标的vm。链路收集的数据放入到探针里面,提供springboot应用使用进行链路采集,然后发送到skywalking的后台oap:观测分析平台。

JVMTI Client也叫agent代理或者探针,基于event事件机制,它接受事件,并执行JVM的控制,也能对事件进行回应。它有一个重要的特性:回调函数机制:JVM可以产生各种事件,面对各种事件,它提供了一个Callback数组,每个事件执行时,都会调用Callback函数,所以编写JVM TI Client的核心就是放置Callback函数。

正是有了这个机制能让我们向JVM发送指令,加载新的类定义

八、skywalingAgent的部署实操

skywalking的探针其实是一个jar包:skywalking-agent.jar

①、准备好两个应用:

demo-application和uaa-application

通过uaa进行远程的rpc调用demo

下面是demo-application的应用,work目录是映射到容器里面去的

5d4939a323520e3c808bf57e5c7a103e.png

在agent目录下skywalking的探针agent,skywalking-agnet.jar就是skywalking给我们提供的jar包:用来采集数据的

585203364400836f92f8e9986e9d8321.png skywalking本身还是挺复杂的,它需要提供各种组件的链路收集,它以插件的形式支持不同组件数据的收集,还有配置数据,启动时的插件,日志数据。

②、如何使用探针的jar包呢?

如果我们在普通的环境下,我们使用如下命令:


使用如下命令,需要折成一行java-javaagent:D:\dev\apm\sky-walking\skywalking-agent\skywalking-agent.jar#应用的名字-Dskywalking.agent.service_name=apm-demo#aop的服务ip和端口-Dskywalking.collector.backend_service=cdh1:11800#项目的jar-jar xxxx.jar

如果我们在容器启动的话:看下编排文件:作用是制作镜像,然后把容器启动


version: '3.5'services:  demo-provider:    build:      context: .      dockerfile: Dockerfile    image: w/demo-provider:1.0-SNAPSHOT    container_name: demo-provider    restart: always     networks:      base-env-network:        aliases:          - demo-provider    extra_hosts:      - "cdh1:192.168.56.121"      - "cdh2:192.168.56.122"      - "cdh3:192.168.56.123"    volumes:       #这个work目录是映射到容器里面去的      - ./work:/work    ports:      - "7700:7700"    environment:      - TAKE_FILE_OWNERSHIP=true  #解决 volumes 挂载权限问题      - NACOS_SERVER=cdh1:8848      - LOG_PATH=/work/logs      - JVM_CONF=-server -Xms64m -Xmx256m      - filebeat_enable=false      #把变量的值放到环境变量里面方便我们在shell脚本使用      - SKYWALKING_JAR_PATH=/work/agent/skywalking-agent.jar      # 所搭建的aop服务的ip和端口      - SKYWALKING_RPC_ADDRESS=cdh1:11800      - SCAFFOLD_DB_HOST=cdh1      - SCAFFOLD_DB_USER=root      - SCAFFOLD_DB_PSW=123456      - SCAFFOLD_REDIS_HOST=cdh1      - SCAFFOLD_REDIS_PSW=123456      - SCAFFOLD_EUREKA_ZONE_HOSTS=http://cdh1:7777/eureka/      - RABBITMQ_HOST=cdh1      - SCAFFOLD_ZOOKEEPER_HOSTS=cdh1:2181
# docker network create base-env-network          networks:  base-env-network:    external:      name: "base-env-network"

看下shell脚本,这个shell脚本是在DockerFile文件里面做处理的,DockFile文件是制作镜像的。首先看下shell脚本。

e69868658209a4b9e9be0c20c87b4f35.png


#!/bin/bash
#服务参数 定制化SERVER_PORT=7700MAIN_CLASS="com.yang.springcloud.demo.start.DemoCloudApplication"
PRO_NAME="demo-provider"
#服务保持不变
JAR_NAME="/app/JarApplication.jar"
WORK_PATH="/work"
# export NACOS_SERVER=cdh2:8848# 向hosts文件追加内容# echo "192.168.56.121 cdh1"  >> /etc/hosts# echo "192.168.56.122 cdh2"  >> /etc/hosts# echo "192.168.56.123 cdh3"  >> /etc/hosts
#BOOT_STRAP_YML= "-Dspring.config.location=bootstrap.yaml"
PROFILES_ACTIVE="-Dspring.profiles.active=sit"APPLICATION_CONFIG="-Dserver.port=${SERVER_PORT} ${PROFILES_ACTIVE} -Duser.timezone=GMT+08"REMOTE_CONFIG="-Xdebug -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n"
SKYWALKING_CONFIG="-javaagent:${SKYWALKING_JAR_PATH} -Dskywalking.agent.service_name=${PRO_NAME} -Dskywalking.collector.backend_service=${SKYWALKING_RPC_ADDRESS}"
#START_CMD="nohup java ${JVM_CONF} ${SKYWALKING_CONFIG}  ${APPLICATION_CONFIG}  -jar ${JAR_NAME} ${MAIN_CLASS}  &"
#如果环境变量配置了这个SKYWALKING_JAR_PATH走这个分支启动探针# 否则走下面的分支if [ "$SKYWALKING_JAR_PATH" != "" ]; then   START_CMD="java ${JVM_CONF} ${SKYWALKING_CONFIG}  ${APPLICATION_CONFIG}  -jar ${JAR_NAME} ${MAIN_CLASS}"else   START_CMD="java ${JVM_CONF} ${APPLICATION_CONFIG}  -jar ${JAR_NAME} ${MAIN_CLASS}"fi
RETVAL="0"
# See how we were called.function start() {
    if [ "$filebeat_enable" != "" ]; then     echo " start filebeat .........."     chmod 777 /usr/local/filebeat-7.14.0-linux-x86_64/filebeat     chmod go-w /work/filebeat/filebeat.yml     chmod go-w /work/filebeat/input.yml     nohup  /usr/local/filebeat-7.14.0-linux-x86_64/filebeat -e -c /work/filebeat/filebeat.yml   >> /work/filebeat/out.log 2>&1  &    fi
    echo " start  ${PRO_NAME} .........."    echo "PORT:$SERVER_PORT"    echo "JVM_CONF:$JVM_CONF"    echo "START_CMD:$START_CMD"    echo "LOG_PATH: $LOG_PATH"    echo "SKYWALKING_CONFIG: $SKYWALKING_CONFIG"
    # nohup java ${JVM} ${APPLICATION_CONFIG}  -jar ${WORK_PATH}/lib/${JAR_NAME} ${MAIN_CLASS} >> ${LOG} 2>&1 &    # nohup java ${JVM} ${SKYWALKING_CONFIG}  ${APPLICATION_CONFIG}  ${BOOT_STRAP_YML}   -jar ${JAR_NAME} ${MAIN_CLASS}  &    ${START_CMD}    status
}
function stop() {    pid=$(ps -ef | grep -v 'grep' | egrep $JAR_NAME| awk '{printf $2 " "}')    if [ "$pid" != "" ]; then        echo -n $"Shutting down boot: "        kill -9 "$pid"    else        echo "${JAR_NAME} is stopped"    fi    status}
function debug() {    echo " start remote debug mode .........."    if [ ! -f ${LOG} ]; then        touch ${LOG}    fi        nohup java ${JVM} ${APPLICATION_CONFIG} ${REMOTE_CONFIG}  -jar ${WORK_PATH}/lib/${JAR_NAME} ${MAIN_CLASS} >> ${LOG} 2>&1 &}
function status(){    pid=$(ps -ef | grep -v 'grep' | egrep $JAR_NAME| awk '{printf $2 " "}')    #echo "$pid"    if [ "$pid" != "" ]; then        echo "${JAR_NAME} is running,pid is $pid"    else        echo "${JAR_NAME} is stopped"    fi}
function usage(){    echo "Usage: $0 {start|debug|stop|restart|status}"    RETVAL="2"}
# See how we were called.case "$1" in    start)        start    ;;    debug)        debug    ;;    stop)        stop    ;;    restart)        stop      start    ;;    status)        status    ;;    *)        usage    ;;esac
exit ${RETVAL}

DockerFile文件如下:


#FROM openjdk:8-jre-alpine3.9-bashFROM  filebeat:7.14.0ADD demo-provider-1.0-SNAPSHOT.jar  /app/JarApplication.jar#这个脚本是放到容器里面的/app目录下的并改名为run.shADD deploy-sit.sh  /app/run.shRUN chmod +x /app/run.sh
# WORKDIR /app/#然后这个脚本会启动ENTRYPOINT /bin/bash -c  "/app/run.sh start"# ENTRYPOINT /bin/bash

项目的部署结果如下:

fe126a004bfd17d370f333a76706678a.png

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
2月前
|
消息中间件 Java 中间件
链路跟踪-SkyWalking系列(三)
链路跟踪-SkyWalking系列(三)
|
2月前
|
存储 缓存 数据可视化
链路跟踪-SkyWalking系列(二)
链路跟踪-SkyWalking系列(二)
|
6月前
|
Java 微服务
skywalking链路追踪时忽略指定异常
skywalking链路追踪时忽略指定异常
|
存储 机器学习/深度学习 运维
基础篇丨链路追踪(Tracing)其实很简单(3)
基础篇丨链路追踪(Tracing)其实很简单
195 0
基础篇丨链路追踪(Tracing)其实很简单(3)
|
存储 运维 监控
基础篇丨链路追踪(Tracing)其实很简单(2)
基础篇丨链路追踪(Tracing)其实很简单
164 0
基础篇丨链路追踪(Tracing)其实很简单(2)
|
存储 NoSQL Java
链路跟踪Jaeger使用总结
链路跟踪Jaeger使用总结
161 0
|
数据采集 调度 数据库
基础篇丨链路追踪(Tracing)其实很简单(1)
基础篇丨链路追踪(Tracing)其实很简单
152 0
|
SQL 缓存 运维
使用篇丨链路追踪(Tracing)很简单:链路实时分析、监控与告警
使用篇丨链路追踪(Tracing)很简单:链路实时分析、监控与告警
6547 10
使用篇丨链路追踪(Tracing)很简单:链路实时分析、监控与告警
|
监控 Java BI
链路追踪Skywalking应用实战 1
链路追踪Skywalking应用实战
285 0
|
JSON 运维 监控
链路追踪Skywalking应用实战 2
链路追踪Skywalking应用实战
250 0