背景
应用在运行过程中,开启性能分析(Profiling)通常是诊断性能瓶颈、内存泄漏和线程问题的关键手段。然而,持续开启 Profiling 会带来显著的性能开销(可能达 5%-20%),并可能生成大量数据,影响生产环境稳定性。动态开启 Profiling 允许开发或运维人员按需、实时地启动/停止数据收集,实现以下目标:
- 降低持续开销:仅在需要时启用,避免长期性能损耗;
- 精准问题定位:针对特定时段(如流量高峰或故障期间)进行分析;
- 在线诊断:无需重启应用即可获取生产环境实时性能快照;
- 灵活控制:可结合监控指标(如 CPU 飙升)自动触发,或在安全审计时手动开启。
通过动态控制,实现了观测能力与系统负载的平衡,保障了关键业务场景的效率和稳定性。
Flameshot
Flameshot 是一个基于 Sidecar 模式运行的轻量级自动性能剖析(Profiling)工具。它通过监控目标进程的资源使用情况(CPU/内存),在达到预设阈值时自动触发底层 Profiler(如 async-profiler ),从而实现无侵入的现场快照采集。
Flameshot 采用 Sidecar 容器 模式部署。它必须与业务主容器(Main Container)运行在同一个 Pod 中,并开启 PID 命名空间共享。
- 监控 (Monitor):Flameshot 持续轮询主容器内目标进程的资源水位。
- 触发 (Trigger):当满足阈值(如 CPU > 80%)或收到 HTTP API 请求时,触发采集任务。
- 执行 (Execute):根据配置的语言类型(目前支持 Java),调用对应的 Profiler 工具 attach 到目标进程。
- 收集 (Collect):生成的 Profile 文件(如
.jfr)存储于共享卷中,随后上传至数据观测中心。
观测云 datakit-operator 从 1.7.0 版本开始支持工具 flameshots,实现动态开启应用 Profiling。
实践
当前在 K8S 环境上部署 JAVA 应用,当 CPU、内存使用率达到 20%(演示方便)则触发 Profiling 数据采集。
前提条件
- 观测云帐号
- K8S 环境
DataKit
DataKit 主要是用来采集数据并上报观测云。
1. 下载 & 安装
wget https://static.guance.com/datakit/datakit.yaml
2. 配置 datakit.yaml
配置 DataWay 数据网关地址
name: ENV_DATAWAY
value: https://openway.guance.com?token=tkn_xxxxx
DataKit 会默认开启主机相关采集器,这里需要追加 pyroscope
name: ENV_DEFAULT_ENABLED_INPUTS
value: cpu,disk,diskio,mem,swap,system,hostobject,net,host_processes,container,pyroscope
3. 启动
调整完配置后,启动 DataKit
root@root:~$ kubectl apply -f datakit.yaml
root@root:~$ kubectl get pods -n datakit
NAME READY STATUS RESTARTS AGE
datakit-4zg7q 1/1 Running 0 14h
datakit-wdtdq 1/1 Running 0 14h
DataKit Operator
1. 下载
下载最新的 datakit-operator.yaml
wget https://static.guance.com/datakit-operator/datakit-operator.yaml
2. 配置 datakit-operator.yaml
主要调整 jsonconfig 下的 flameshots 内容,参考如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: datakit-operator-config
namespace: datakit
data:
jsonconfig: |-
{
"server_listen": "0.0.0.0:9543",
"log_level": "info",
"admission_inject_v2": {
...
"flameshots": [
{
"namespace_selectors": ["default"],
"label_selectors": [],
"image": "pubrepo.jiagouyun.com/datakit/flameshot:0.1.1",
"envs": {
"FLAMESHOT_DATAKIT_ADDR": "http://datakit-service.datakit.svc:9529/profiling/v1/input",
"FLAMESHOT_MONITOR_INTERVAL": "1s",
"FLAMESHOT_PROFILING_PATH": "/flameshot-data",
"FLAMESHOT_HTTP_LOCAL_IP": "{fieldRef:status.podIP}",
"FLAMESHOT_HTTP_LOCAL_PORT": "8089",
"FLAMESHOT_SERVICE": "{fieldRef:metadata.labels['app']}",
"POD_NAME": "{fieldRef:metadata.name}",
"POD_NAMESPACE": "{fieldRef:metadata.namespace}",
"NODE_NAME": "{fieldRef:spec.nodeName}",
"FLAMESHOT_TAGS": "pod_name:$(POD_NAME),pod_namespace:$(POD_NAMESPACE),host:$(NODE_NAME)"
},
"resources": {
"requests": {
"cpu": "100m",
"memory": "128Mi"
},
"limits": {
"cpu": "200m",
"memory": "256Mi"
}
},
"processes": "[{\"command\":\"java\",\"duration\":\"60s\",\"events\":\"--all\",\"language\":\"java\",\"jdk_version\":\"-\",\"tags\":[\"env:testing\",\"version:1.0.0\"],\"cpu_usage_percent\":20,\"mem_usage_percent\":20,\"mem_usage_mb\":1024}]"
}
]
},
...
}
参数说明:
- namespace_selectors: 空间选择,即哪些空间需要开启
flameshots - env: 配置环境变量信息
- processes: 执行命令,如果为空,则
flameshots不生效
processes 通用字段说明:
service(String): 选填,上报到观测中心的服务名称。language(String): 目标进程语言。目前支持 java。command(String): 匹配进程命令行的正则表达式。duration(String): 单次采集时长(例如30s,1m)。注意:受限于执行超时,建议不超过 5 分钟。tags(List): 自定义标签列表,建议包含env,version等元信息。cpu_usage_percent(Int): CPU 触发阈值 (0-N)。多核环境下数值可能超过 100。mem_usage_percent(Int): 内存使用率触发阈值 (0-100)。mem_usage_mb(Int): 内存使用量绝对值触发阈值 (MB)。
当前配置 processes 可以实现所有 JAVA 服务,为了实践方便,当 cpu 使用率达到 20% 或内存使用率达到 20% 或内存使用值达到 1024m,则会触发执行 Profiling 操作。
"processes": "[{\"command\":\"java\",\"duration\":\"60s\",\"events\":\"--all\",\"language\":\"java\",\"jdk_version\":\"-\",\"tags\":[\"env:testing\",\"version:1.0.0\"],\"cpu_usage_percent\":20,\"mem_usage_percent\":20,\"mem_usage_mb\":1024}]"
3. 启动
root@root:~$ kubectl apply -f datakit-operator.yaml
root@root:~$ kubectl get pods -n datakit
NAME READY STATUS RESTARTS AGE
datakit-4zg7q 1/1 Running 0 15h
datakit-operator-849f868b78-zbcd9 1/1 Running 0 58s
datakit-wdtdq 1/1 Running 0 15h
JAVA 应用
1. Yaml 配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: springboot-server
spec:
selector:
matchLabels:
app: springboot-server
replicas: 1
template:
metadata:
labels:
app: springboot-server
spec:
containers:
- image: registry.cn-shenzhen.aliyuncs.com/lr_715377484/springboot-server:flameshots
name: springboot-server
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
protocol: TCP
securityContext:
seccompProfile:
type: Unconfined
2. 启动应用
root@root:~$ kubectl apply -f springboot-server.yaml
root@root:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
springboot-server-d55fc79dd-48c95 2/2 Running 0 3s
3. 查看 flameshot 执行日志
需要指定 containerName 为 -c datakit-flameshot
root@root:~$ kubectl logs -f springboot-server-d55fc79dd-48c95 -c datakit-flameshot
2026-01-15T03:55:58.090Z ERROR flameshot flameshot/config.go:243 read config file failed, err:open /flameshot/flameshot.conf: no such file or directory
2026-01-15T03:55:58.092Z INFO flameshot flameshot/monitor.go:78 start monitor, interval: 1s
2026-01-15T03:55:58.092Z INFO flameshot flameshot/http.go:77 start http server on 10.187.217.101:8089
2026-01-15T03:55:58.092Z INFO flameshot flameshot/http.go:78 profile start at /v1/profile
2026-01-15T03:55:58.092Z INFO flameshot flameshot/http.go:79 prom http start at /metrics
2026-01-15T03:56:58.093Z INFO flameshot flameshot/monitor.go:102 match: PID=7, name=java or cmd=java -jar app.jar
从启动日志上分析,已经找到了 java 服务,且 PID 为 7,等待触发事件
4. 触发阈值
访问应用
root@root:~$ kubectl exec -it springboot-server-d55fc79dd-48c95 -- /bin/bash
Defaulted container "springboot-server" out of: springboot-server, datakit-flameshot
springboot-server-d55fc79dd-48c95:/home/app#
springboot-server-d55fc79dd-48c95:/home/app# curl http://localhost:8080/profiling/generator
write success!springboot-server-d55fc79dd-48c95:/home/app#
再来看看 flameshot 执行日志,已触发了阈值 cpu_avg:36.60 且正常上报数据。

之后恢复了正常,正常之后则不会再产生 Profiling 数据,除非再次触发了阈值。
观测云平台
登录观测云平台,访问「应用性能检测」-「Profling」可以查看到刚刚上报的 Profling 信息

点击列表可以查看 Profling 详细信息,如 CPU 耗时、内存分配情况等,可以更深度的剖析应用代码性能损耗。
