一,设计目标
1,低消耗
对服务影响做到最小,防止在高并发场景下导致服务出现延迟,负载高或不可用
2,对应用透明
不在应用中植入代码,可能会因为代码产生bug或导致应用出问题
3,可伸缩性
满足未来在性能上的压力和功能上的需求
二,dapper介绍
请求链路
简单使用的分布式跟踪的实现,就是为服务器上每一次发送和接受动作来收集跟踪标识符和时间戳
采集方法
黑盒法:agent,无需植入代码,缺点需要大量数据才能推导出服务间关系
标记法:为每个请求打标记,并通过一个全局标识符将请求途径的所有服务信息串联,复盘整个链路,记录明确,缺点是需要注入到每个服务中。
在谷歌内部,几乎所有的应用都使用相同的 threading model,control flow 和RPC system,因此可以将打标记的工作集中在少量的公共库中,同样能达到对应用透明的效果。需要做相应开发
跟踪树和span
下单到返回结果
parent id 相对span id不会变
span id 会变会定位追踪 0.2.2 0.1.1 0.3.3
traceId 不会变 123
客户端和服务端 send recv 计算时间戳
植入点介绍
Dapper可以实现对应用开发者近乎零侵入的成本对分布式链路进行跟踪,主要通过通用组件库实现。对于python是模块,对于java是jar包,在服务运行时指定探针,运行在服务上,把请求进行收集并标记
当一个线程在处理跟踪请求链路的过程中,Dapper把这次跟踪的上下文在ThreadLocal中进行存储,追踪上下文是一个小而容易复制的空间,其中记录了scan的属性信息,比如跟踪ID和span iD
当用户的请求处理过程是延迟调用或是异步的,大多数google开发者通过线程池或其他执行器,使用一个通用的控制流库来回调,Dapper确保所有这样的回调可以存储这次跟踪的上下文,而当回调函数被触发时,这次跟踪的上下文会与适当的线程关联上,在这种方式下,Dapper可以使用trace Id和span ID 来辅助构建异步调用的路径
几乎所有的谷歌的进程间通信时建立在一个用C++和Java开发的RPC框架上,我们把跟踪植入该框架来定义RPC中所有的span,span ID和跟踪的ID会从客户端发送到服务端,像那样的基于RPC的系统被广泛使用在Google中,这是一个重要的植入点,当那些非RPC通信框架发展成熟并找到自己的用户群之后,我们会计划对RPC通信框架进行植入
dapper的跟踪记录和收集日志管道跟为三个阶段
1,span 数据写到本地日志文件中
2,dapper的守护进程和收集组件agen把这些数据从生产环境的主机中进行读取
3,写入到dapper的数据仓库es中
一次跟踪被设计成Bigtable中的一行,每一列相当于一个span. Bigtable的支持稀疏表格布局正适合这种情况,因为每一次跟踪可以有任意个span
跟踪代价
守护进程没有超过0.3%的单核cpu使用率,很少内存,还限制了dapper守护进程为内核scheduler的最低优先级,防止在高负载服务器发生cpu竞争
root span 204 ns
一般span 176 ns
写到本地磁盘 IO
三,APM概述
APM 应用性能管理
CAT java 代码侵入性太强
Zipkin java 代码侵入性不是很强
jaeger go 对代码侵入性较少
Pinpint HBase 对代码无无侵入
Skywalking java 国内首个 对代码无侵入
piwik 开源的
OpenTracing
统一标准
一个trace 代表一个事务,一个span 代表系统中具有开始时间和执行时间的逻辑单元,一个trace 中span是首尾连接的
操作名称
起始时间
结束时间
span tag
span log
spanContext
References
模块化设计
探针负责收集数据
前端负责展示数据
后端负责存储读写数据和持久化数据
架构
es 9200 >> skywaking-oap 12800(查询端口) skywalking-ui 8080
agent(收集访问请求) 11800(写入端口)
四,二进制部署
https://archive.apache.org/dist/skywalking/8.7.0/
1,es skywalking-apm部署
root@ubuntu20:~# cat /etc/elasticsearch/elasticsearch.yml |grep -v "#"
cluster.name: skywalking-cluster
node.name: node1
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 192.168.192.250
http.port: 9200
discovery.seed_hosts: ["192.168.192.250"]
cluster.initial_master_nodes: ["192.168.192.250"]
@ubuntu20:/apps/apache-skywalking-apm-bin-es7# ./bin/startup.sh /apps config/application.yml tail -f logs/*.log
storage:
selector: ${SW_STORAGE:elasticsearch7} #
elasticsearch:
nameSpace: ${SW_NAMESPACE:""}
clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:192.168.192.250:9200} #
elasticsearch7:
nameSpace: ${SW_NAMESPACE:""}
clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:192.168.192.250:9200} #
root@ubuntu20:/apps/apache-skywalking-apm-bin-es7# ss -tnl |grep 80
LISTEN 0 4096 *:11800 *:*
LISTEN 0 50 *:12800 *:*
LISTEN 0 100 *:8080 *:*
root@ubuntu20:/apps/apache-skywalking-apm-bin-es7# ss -tnl |grep 250 es
LISTEN 0 4096 [::ffff:192.168.192.250]:9300 *:*
LISTEN 0 4096 [::ffff:192.168.192.250]:9200 *:*
示例1 halo
https://docs.halo.run/getting-started/prepare/
vim config/agent.config
agent.namespace=${SW_AGENT_NAMESPACE:chuan}
# The service name in UI
agent.service_name=${SW_AGENT_NAME:halo}
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:192.168.192.250:11800}
https://skywalking.apache.org/docs/skywalking-java/v8.8.0/en/setup/service-agent/java-agent/readme/
root@ubuntu20:/data/skywalking-agent# java -javaagent:./skywalking-agent.jar -jar ./halo-1.4.7.jar
示例二 tomcat jenkins
root@ubuntu20:~/apache-tomcat-8.5.73/bin# vim catalina.sh
#!/bin/sh
CATALINA_OPTS="$CATALINA_OPTS -javaagent:/data/skywalking-agent/skywalking-agent.jar"; export CATALINA_OPTS
root@ubuntu20:~/apache-tomcat-8.5.73# mv /root/jenkins.war webapps/
端口改为8090 tomcat
root@ubuntu20:~/apache-tomcat-8.5.73#