1、介绍
在前面的文章中讲到SkyWalking链路追踪系统-部署篇,接下来在正式接入Skywalking
探针agent
之前,先来接着了解一下Skywalking
的整体架构和主要概念(内容主要汇总自官方文档或网络)
1.1 整体架构
以下是来自Skywalking
官方Github
库上的一张架构图
整体架构包含如下三个组成部分:
- 探针(
agent
)负责进行数据的收集,包含了Tracing
和Metrics
的数据,agent
会被安装到服务所在的服务器上,以方便数据的获取。 - 可观测性分析平台
OAP
(Observability Analysis Platform),接收探针发送的数据,并在内存中使用分析引擎(Analysis Core
)进行数据的整合运算,然后将数据存储到对应的存储介质上,比如Elasticsearch
、MySQL
数据库、H2
数据库等。同时OAP
还使用查询引擎(Query Core
)提供HTTP
查询接口。 Skywalking
提供单独的UI
进行数据的查看,此时UI
会调用OAP
提供的接口,获取对应的数据然后进行展示。
Skywalking
提供Tracing
和Metrics
数据的获取和聚合:
Metric
的特点是,它是可累加的:他们具有原子性,每个都是一个逻辑计量单元,或者一个时间 段内的柱状图。 例如:队列的当前深度可以被定义为一个计量单元,在写入或读取时被更新统 计; 输入HTTP
请求的数量可以被定义为一个计数器,用于简单累加; 请求的执行时间可以被定 义为一个柱状图,在指定时间片上更新和统计汇总。
Tracing
的最大特点就是,它在单次请求的范围内,处理信息。 任何的数据、元数据信息都被绑定 到系统中的单个事务上。 例如:一次调用远程服务的RPC
执行过程;一次实际的SQL
查询语句; 一次HTTP
请求的业务性ID
。
总结,Metric
主要用来进行数据的统计,比如HTTP
请求数的计算。Tracing
主要包含了某一次请求的链路数据。
详细的内容可以查看Skywalking
开发者吴晟翻译的文章,Metrics , tracing 和 logging 的关系
1.2 主要概念
Skywalking
主要概念包含:
- 服务(Service) :用户服务就是
Skywalking
的服务Service
,用户服务其实就是一个独立的应用Application
,在6.0
版本之后的Skywalking
将应用更名为服务Service
- 端点(Endpoint) :用户服务对外提供的
HTTP
接口例如/usr/list
就是一个端点,端点就是对外提供的接口 - 实例(Instance):相同服务部署的节点就是实例,实例指同一服务可以部署多个,例如多台虚拟机或多个容器
2、准备agent包
Skywalking
目前支持很多语言的链路追踪,本文以常见的java
应用为例进行记录
下载官方和server
版本相同的发行版本包,并获取agent
我这里对应前面安装的服务端下载地址:https://www.apache.org/dyn/closer.cgi/skywalking/8.4.0/apache-skywalking-apm-8.4.0.tar.gz
下载后解压提取agent
目录,结构如下
-- agent
-- activations
apm-toolkit-log4j-1.x-activation.jar
apm-toolkit-log4j-2.x-activation.jar
apm-toolkit-logback-1.x-activation.jar
...
-- config # 配置文件目录
agent.config
-- plugins # 主要插件目录
apm-dubbo-plugin.jar
apm-feign-default-http-9.x.jar
apm-httpClient-4.x-plugin.jar
.....
-- optional-plugins # 可选插件目录
apm-gson-2.x-plugin.jar
.....
-- bootstrap-plugins
jdk-http-plugin.jar
.....
-- logs # 默认日志目录
skywalking-agent.jar
整个agent
目录大概是30MB
左右,很多插件都是可选的,在启动时启用了插件的话,具有更为强大的功能。部分插件在使用上会影响整体的性能或者由于其他原因放置于可选插件包中,不会直接加载,如果需要使用,将可选插件中的jar
包拷贝到plugins
目录下
最终基于容器环境配置skywalking agent
的方式一种是创建ConfigMap
,然后通过 ConfigMap
挂载到容器里进行覆盖;另一种是在默认配置里引用各种变量,在容器启动时通过环境变量注入
因此这里修改agent
的配置文件config/agent.config
,打开其中某些配置项的注释,但不进行具体配置修改,通过环境变量进行注入以使用
# grep -Ev '^$|#' agent/config/agent.config
agent.namespace=${SW_AGENT_NAMESPACE:default-namespace}
agent.service_name=${SW_AGENT_NAME:Your_ApplicationName}
agent.is_cache_enhanced_class = ${SW_AGENT_CACHE_CLASS:false}
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:127.0.0.1:11800}
logging.file_name=${SW_LOGGING_FILE_NAME:skywalking-api.log}
logging.level=${SW_LOGGING_LEVEL:INFO}
logging.max_file_size=${SW_LOGGING_MAX_FILE_SIZE:314572800}
logging.max_history_files=${SW_LOGGING_MAX_HISTORY_FILES:-1}
plugin.mount=${SW_MOUNT_FOLDERS:plugins,activations}
plugin.mysql.trace_sql_parameters=${SW_MYSQL_TRACE_SQL_PARAMETERS:false}
对应配置说明:
agent.namespace
:命名空间,可通过此参数实现隔离agent.service_name
:在链路追踪UI
中展示的应用名,如果是微服务架构,可以和注册中心中的应用名一致agent.is_cache_enhanced_class
:如果为true
,则SkyWalking
代理会将所有检测到的类文件缓存到内存或磁盘文件中(由类缓存模式决定)collector.backend_service
:后端Collector
收集器的地址logging.file_name
:日志文件名logging.level
:日志等级logging.max_file_size
:日志文件大小控制logging.max_history_files
:历史日志文件个数控制plugin.mount
:挂载插件的文件夹名plugin.mysql.trace_sql_parameters
:收集sql
的参数
除了上面的参数外,还有一个常用参数agent.ignore_suffix
,表示对请求追踪进行忽略,多个路径用逗号分隔,在实际的生产环境中某些请求是不需要被追踪的,例如心跳检查/health
,监控指标/metrics
等等,我们需要将对应的插件jar
包apm-trace-ignore-plugin-8.4.0.jar
拷贝到plugins
目录下并进行对应的配置,配置文件内容部分如下
# If the operation name of the first span is included in this set, this segment should be ignored. Multiple values should be separated by `,`.
# agent.ignore_suffix=${SW_AGENT_IGNORE_SUFFIX:.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg}
更多的配置项可以参考官方配置说明
3、打包制作镜像
官方给出了在java
应用的不同运行环境中java agent配置示例:
本文以spring boot
应用jar
包运行的方式为例,首先修改基础java
镜像的Dockerfile
,将agent
包打入镜像
(一个小Tips
:踩了很多坑,最终自己做oracle jdk
的镜像,而不是用中央仓库的openjdk
,基础镜像基于centos
,为了减小镜像体积这里可以再进行优化)
修改Dockerfile
FROM centos:7.6.1810
LABEL maintainer ssgeek@ssgeek.com
ENV LANG "en_US.UTF-8"
ENV JDK_VERSION 1.8.0_191
ENV SW_VERSION 8.4.0
ADD jdk-8u191-linux-x64.tar.gz /usr/local
ADD agent /skywalking/agent
ENV JAVA_HOME /usr/local/jdk1.8.0_191
ENV CLASSPATH $JAVA_HOME/lib;$JAVA_HOME/jre/lib
ENV PATH $PATH:$JAVA_HOME/bin
RUN set -x &&
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
打包镜像并上传到仓库
代码语言:javascript复制# docker build -t hub.ssgeek.com/basic_image/jdk_8u191:skywalking_v1.0
# docker push hub.ssgeek.com/basic_image/jdk_8u191:skywalking_v1.0
修改业务应用的Dockerfile
,引用加入了agent
包的基础镜像并修改启动参数
FROM hub.ssgeek.com/basic_image/jdk_8u191:skywalking_v1.0
LABEL maintainer ssgeek@ssgeek.com
RUN mkdir /app
WORKDIR /app
COPY target/*.jar /app/app.jar
EXPOSE 8080
CMD java -Djava.security.egd=file:/dev/./urandom -javaagent:/skywalking/agent/skywalking-agent.jar -jar ${JAVA_OPTS} /app/app.jar
4、注入环境变量
这里的java
应用运行在k8s
容器化环境中,因此对配置变量的注入可以通过在部署清单的yaml
中以环境变量的形式注入,这样配置更为轻量和灵活
其中部分参数的环境变量取值,通过在Pod
中使用环境变量把自己的信息呈现给Pod
中运行的容器,可以参考
通过环境变量将 Pod 信息呈现给容器
代码语言:javascript复制...
spec:
imagePullSecrets:
- name: registry-pull-secret
containers:
- name: java
image: hub.ssgeek.com/java/xxx:tag
imagePullPolicy: IfNotPresent
env:
- name: JAVA_OPTS
value: 'JVM参数'
- name: SW_AGENT_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: SW_AGENT_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: SW_AGENT_CACHE_CLASS
value: 'true'
- name: SW_MYSQL_TRACE_SQL_PARAMETERS
value: 'true'
- name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
value: 'skywalking-oap.monitoring.svc:11800'
ports:
- containerPort: 8080
name: AppName
protocol: TCP
网络上有文章的操作方式大多都是添加一个initContainer
将agent
拷贝到应用Pod
中,我个人认为会浪费系统资源且每次启动都需要执行,这必然会增加应用的启动时间,还不如修改基础java
镜像,一劳永逸。
5、部署启动并查看ui
按照上面的操作对Pod
应用注入了Skywalking agent
相关配置,如果应用启动后会有如下的日志提示,表示agent
注入启动成功了
当应用启动完成,正常接收流量后,服务端就可以采集并展示相关数据了,这里我展示一个微服务项目测试环境接入Skywalking
后的仪表盘页面
拓扑图
see you ~