08 微服务链路监控系统


全链路监控是什么

全链路监控解决什么问题

  1. 请求链路追踪:通过分析服务调用关系,绘制运行时拓扑信息,可视化展示
  2. 调用情况衡量:各个调用环节的性能分析,例如吞吐量、响应时间、错误次数
  3. 容器规划参考:扩容/缩容、服务降级、流量控制
  4. 运行情况反馈:告警,通过调用链结合业务日志快速定位错误信息

全链路监控选择依据

全链路监控系统有很多,应从这几方面选择

  1. 探针的性能消耗
    APM组件服务的影响应该做到足够小,数据分析要快,性能占用小。
  2. 代码的侵入性
    即也作为业务组件,应当尽可能少入侵或者无入侵其他业务系统,
    对于使用方透明,减少开发人员的负担。
  3. 监控维度
    分析的维度尽可能多。 • 可扩展性
    一个优秀的调用跟踪系统必须支持分布式部署,具备良好的可扩展性。能够支持的组件越多当然越好。

  4. 主流系统:zipkin、skywalking、pinpoint

Pinpoint 介绍

  1. Pinpoint是一个APM(应用程序性能管理)工具,适用于用Java/PHP编写的大型分布式系统。

特性:

  1. 服务器地图(ServerMap)通过可视化分布式系统的模块和他们之间的相互联系来理解系统拓扑。点击某个节点会,展示这个模块的详情,比如它当前的状态和请求数量。
  2. 实时活动线程图 (Realtime Active Thread Chart): 实时监控应用内部的活动线程。
  3. 请求/响应分布图( Request/Response Scatter Chart ): 长期可视化请求数量和应答模式来定位潜在问题。通过在图表上拉拽可以选择请求查看 更多的详细信息
  4. 调用栈( CallStack :在分布式环境中为每个调用生成代码级别的可视图,在单个视图中定位瓶颈和失败点。
  5. 检查器( Inspector ): 查看应用上的其他详细信息,比如CPU使用率,内存/垃圾回收,TPS,和JVM参数。

Docker 部署 Pinpoint

1
2
3
4
5
6
7
git clone https://github.com/naver/pinpoint-docker.git
cd pinpoint-docker
docker-compose pull && docker-compose up -d

# 官方文档
https://github.com/naver/pinpoint-docker
# 网络太慢的话 可以先下载好包
1
2
3
4
5
6
7
8
9
10
11
[root@k8s-master2 opt]# yum install git
[root@k8s-master2 opt]# git clone https://github.com/naver/pinpoint-docker.git
[root@k8s-master2 opt]# cd pinpoint-docker/
[root@k8s-master2 pinpoint-docker]# docker-compose pull
[root@k8s-master2 pinpoint-docker]# docker-compose up -d

[root@k8s-master2 pinpoint-docker]# docker-compose ps

# 查看web 服务端可以访问到界面即正常
http://47.240.13.206:8079/
http://47.240.13.206:8000/ quickstart 访问后会有测试数据

Pinpoint Agent 部署

探针 随着服务一起启动

1
2
3
4
5
# Tomcat:
# catalina.sh
CATALINA_OPTS="$CATALINA_OPTS -javaagent:$AGENT_PATH/pinpoint-bootstrap-$VERSION.jar" # AGENT_PATH 路径
CATALINA_OPTS="$CATALINA_OPTS -Dpinpoint.agentId=$AGENT_ID" # 区分实例ID 不唯一
CATALINA_OPTS="$CATALINA_OPTS -Dpinpoint.applicationName=$APPLICATION_NAME“ # app 名称 哪个应用
1
2
# Jar:
java -jar -javaagent:$AGENT_PATH/pinpoint-bootstrap-$VERSION.jar -Dpinpoint.agentId=$AGENT_ID -Dpinpoint.applicationName=$APPLICATION_NAME xxx.jar

JAR包下载地址

微服务接入Pinpoint

服务启动时指定 Pinpoint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 每个组件 都需要配置指定 

[root@k8s-master1 microservic-code]# cd simple-microservice-dev4

[root@k8s-master1 simple-microservice-dev4]# cd portal-service/
# pinpoint 下载好后和项目放在同一目录,Dockerfile会copy到容器中
[root@k8s-master1 portal-service]# ls
Dockerfile pinpoint pom.xml src

# 启动在Dockerfile里面指定
[root@k8s-master1 portal-service]# vim Dockerfile

FROM java:8-jdk-alpine
LABEL maintainer lizhenliang/www.ctnrs.com
RUN apk add -U tzdata && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY ./target/portal-service.jar ./
COPY pinpoint /pinpoint
EXPOSE 8080
CMD java -jar -javaagent:/pinpoint/pinpoint-bootstrap-1.8.3.jar -Dpinpoint.agentId=${HOSTNAME} -Dpinpoint.applicationName=ms-protal /portal-service.jar
1
2
3
4
5
6
7
CMD java -jar 
-javaagent:/pinpoint/pinpoint-bootstrap-1.8.3.jar # 路径 /pinpoint
-Dpinpoint.agentId=$(echo $HOSTNAME | awk -F- '{print "portal-"$NF}') # portal + 容器名截取最后一位 与POD对应上
-Dpinpoint.applicationName=ms-portal # 项目名
$JAVA_ARGS
$JAVA_OPTS
/portal-service.jar
1
2
3
4
5
# 修改配置文件的 服务端地址
[root@k8s-master1 portal-service]# vim pinpoint/pinpoint.config
...
profiler.collector.ip=172.31.228.51
...

重新部署 查看采集情况

1
2
# eureka 属于基础组件 无需每次都重新启动配置 一般都是手动部署 发布的时候不要重新部署
# 本次重新部署 是因为增加了 链路监控
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@k8s-master1 k8s]# cat docker_build.sh 
#!/bin/bash

docker_registry=172.31.228.51
# kubectl create secret docker-registry registry-pull-secret --docker-server=$docker_registry --docker-username=admin --docker-password=Harbor12345 --docker-email=admin@ctnrs.com -n ms
# kubectl create secret docker-registry registry-pull-secret --docker-server=172.31.228.51 --docker-username=admin --docker-password=lx@68328153 --docker-email=admin@ctnrs.com -n ms


service_list="eureka-service gateway-service order-service product-service stock-service portal-service"
service_list=${1:-${service_list}}
work_dir=$(dirname $PWD)
current_dir=$PWD

cd $work_dir
mvn clean package -Dmaven.test.skip=true

for service in $service_list; do
cd $work_dir/$service
if ls |grep biz &>/dev/null; then
cd ${service}-biz
fi
service=${service%-*}
image_name=$docker_registry/microservice/${service}:$(date +%F-%H-%M-%S)
docker build -t ${image_name} .
docker push ${image_name}
# 替换镜像名称 直接部署
sed -i -r "s#(image: )(.*)#\1$image_name#" ${current_dir}/${service}.yaml
kubectl apply -f ${current_dir}/${service}.yaml
done
1
2
# 使用脚本重新构建项目
# 本次构建所有微服务加入了 pinpoint 链路监控

查看采集

1
2
3
4
5
# 启动日志中是否含有 pinpoint 加载
[root@k8s-master1 k8s]# kubectl logs order-564b46f676-fb9gh -n ms

# 模拟请求
http://portal.ctnrs.com/

监控JAVA应用 都需要监控哪些指标

  1. JVM相关,堆内存:年轻代,老年代(持久常用对象 不断gcc),非堆内存(持久代,1.9后没有了)
  2. 线程数量
  3. GCC(垃圾回收) ,G1,CMS
  4. CPU利用率
  5. 堆栈跟踪 哪段代码堆内存使用高,cpu使用高
  6. 接口状态
  7. 吞吐量

堆栈信息

  1. 有利于开发定位问题

响应时间 和 load 传入事务 (并发)

1个请求5秒

堆内存

  1. id对应pod
  2. Non-Heap Usage : 非堆内存(持久代)
  3. Heap Usage : 堆内存:年轻代+老年代 , 堆内存的使用率快到达了堆内存大小,那么要重新分配
  4. JVM/System Cpu Usage : CPU消耗
  5. Transactions Per Second : 每秒事务传输,相当于并发平均
  6. Active Thread : 活动线程
  7. Response Time : 请求响应时间
  8. Open File Descriptor : 打开文件描述符的数量