SSH框架如何对接Webfunny Apm后端监控

一只会飞的鱼儿 5月前 ⋅ 711 阅读
ad
前言:为什么需要全链路监控?​
在分布式系统中,一个用户请求可能穿越 Struts2 控制器、Spring 服务、Hibernate 数据访问等多个层级,传统日志排查方式面临三大痛点:​
  1. 故障定位难:无法快速追踪请求流经路径,问题排查耗时久(某银行案例显示,未接入 APM 时异常定位需 45 分钟);​
  1. 性能瓶颈隐蔽:缺乏各组件耗时统计,难以识别慢 SQL、低效方法等瓶颈;​
  1. 系统行为不透明:微服务调用链路复杂,无法直观掌握系统运行状态。​
而 Webfunny APM 结合 OpenTelemetry 可完美解决这些问题 —— 无需大规模改造 SSH 老项目,即可实现零侵入 / 低侵入的全链路追踪。本文将详细拆解对接过程,从环境配置到验证落地,带你快速上手。

一、项目技术栈与对接核心方案​

1. 基础技术栈(SSH 框架适配版)​
​
层级​
 
 
 
 
技术选型​
 
 
 
 
版本​
 
 
 
 
核心作用​
 
 
 
 
Web 框架​
 
 
 
 
Apache Struts2​
 
 
 
 
6.3.0.2​
 
 
 
 
MVC 控制器,接收 HTTP 请求​
 
 
 
 
容器层​
 
 
 
 
Spring Framework​
 
 
 
 
5.3.27​
 
 
 
 
依赖注入、事务管理​
 
 
 
 
ORM 层​
 
 
 
 
Hibernate​
 
 
 
 
5.6.15.Final​
 
 
 
 
数据持久化,生成 SQL 执行​
 
 
 
 
数据库​
 
 
 
 
H2 Database​
 
 
 
 
2.2.224​
 
 
 
 
开发 / 测试环境内存数据库(生产可替换为 MySQL)​
 
 
 
 
构建工具​
 
 
 
 
Maven​
 
 
 
 
3.8+​
 
 
 
 
依赖管理与项目构建​
 
 
 
 
运行环境​
 
 
 
 
Java​
 
 
 
 
11​
 
 
 
 
兼容 SSH 框架与 OpenTelemetry Agent​
 
 
 
 
链路探针​
 
 
 
 
OpenTelemetry Java Agent​
 
 
 
 
2.22.0​
 
 
 
 
自动采集链路数据,无需修改业务代码​
 
 
 
 
 
 
 
 
 
​
2. 核心集成架构​
采用「Agent 自动注入 + OTLP 协议上报」方案,整体链路如下:
用户请求 → OpenTelemetry Java Agent(自动采集)→ SSH 各层级(Struts2→Spring→Hibernate)→ 
OTLP Exporter → OpenTelemetry Collector → Webfunny APM 平台
关键优势:​
  • 零侵入:Agent 方式无需修改 SSH 业务代码,老项目快速适配;​
  • 全覆盖:自动采集 HTTP 请求、SQL 执行、方法调用等核心数据;​
  • 标准化:基于 OpenTelemetry 协议,支持后续对接其他 APM 平台(如 Elastic、Datadog)。
​​

二、详细对接步骤(直接抄作业)​

1. 第一步:添加 Maven 依赖​
在 pom.xml 中引入 OpenTelemetry 核心依赖(用于注解增强和 API 调用):
    <!-- OpenTelemetry API -->
    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>opentelemetry-api</artifactId>
        <version>1.33.0</version>
    </dependency>
    
    <!-- OpenTelemetry 注解支持 -->
    <dependency>
        <groupId>io.opentelemetry.instrumentation</groupId>
        <artifactId>opentelemetry-instrumentation-annotations</artifactId>
        <version>1.33.0</version>
    </dependency>
    <dependency>
      <groupId>io.opentelemetry</groupId>
      <artifactId>opentelemetry-sdk</artifactId>
      <version>1.33.0</version>
    </dependency>
    <dependency>
      <groupId>io.opentelemetry</groupId>
      <artifactId>opentelemetry-exporter-otlp</artifactId>
      <version>1.33.0</version>
    </dependency>
2. 第二步:配置 OpenTelemetry Java Agent​
2.1 下载 Agent 包​
从 OpenTelemetry 官网 下载 opentelemetry-javaagent.jar(版本 2.22.0),放置在服务器目录(如 /opt/otel/)。​
2.2 编写启动脚本(关键配置)​
创建 start-with-otel.sh 启动脚本,整合 Agent 配置与应用启动命令(适配 Jetty/Tomcat 容器):
#!/bin/bash

# ====================== OpenTelemetry 核心配置 ======================
# 服务名称(Webfunny 平台显示用)
OTEL_SERVICE_NAME="Pro-sshDemo"
# 资源属性(环境标识、实例ID,便于多环境区分)
OTEL_RESOURCE_ATTRIBUTES="deployment.environment=production,service.instance.id=ssh-app-01,service.version=2.0"
# Webfunny OTLP 上报端点(注意:原文档中 http://localhost:9013 若解析失败,需检查网络连通性)
OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:9013"
# 传输协议(GRPC 性能更优,若报错可改为 http/protobuf)
OTEL_EXPORTER_OTLP_PROTOCOL="grpc"
# 超时时间
OTEL_EXPORTER_OTLP_TIMEOUT="10s"
# 仅开启 Trace 采集(Metrics/Logs 按需启用)
OTEL_TRACES_EXPORTER="otlp"
OTEL_METRICS_EXPORTER="none"
OTEL_LOGS_EXPORTER="none"
# 全局方法扫描(无需注解,自动采集指定包下所有方法)
OTEL_INSTRUMENTATION_METHODS_INCLUDE="com.demo.web.action.*[*];com.demo.service.*[*];com.demo.dao.*[*]
"
# 排除工具类/配置类(减少冗余 Span)
OTEL_INSTRUMENTATION_METHODS_EXCLUDE="com.yourapp.util.*[*];com.yourapp.config.*[*]"

# ====================== 应用启动配置 ======================
# Agent 路径(替换为你的实际路径)
OTEL_AGENT_JAR="/opt/otel/opentelemetry-javaagent.jar"
# 端口配置(避免冲突)
JETTY_PORT=8080

# 整合启动参数
export MAVEN_OPTS="\
-javaagent:$OTEL_AGENT_JAR \
-Dotel.service.name=$OTEL_SERVICE_NAME \
-Dotel.resource.attributes=$OTEL_RESOURCE_ATTRIBUTES \
-Dotel.exporter.otlp.endpoint=$OTEL_EXPORTER_OTLP_ENDPOINT \
-Dotel.exporter.otlp.protocol=$OTEL_EXPORTER_OTLP_PROTOCOL \
-Dotel.exporter.otlp.timeout=$OTEL_EXPORTER_OTLP_TIMEOUT \
-Dotel.traces.exporter=$OTEL_TRACES_EXPORTER \
-Dotel.metrics.exporter=$OTEL_METRICS_EXPORTER \
-Dotel.logs.exporter=$OTEL_LOGS_EXPORTER \
-Dotel.instrumentation.methods.include=$OTEL_INSTRUMENTATION_METHODS_INCLUDE \
-Dotel.instrumentation.methods.exclude=$OTEL_INSTRUMENTATION_METHODS_EXCLUDE"

# 启动 Jetty 容器(若用 Tomcat,替换为 catalina.sh start)
mvn jetty:run -Djetty.http.port=$JETTY_PORT

 

3. 第三步:链路增强(注解 / 全局扫描二选一)​
方案 A:@WithSpan 注解(精准控制,生产推荐)​
在关键业务方法上添加注解,自定义 Span 名称和类型,适用于核心链路监控:
// Struts2 Action 层(Controller)
@Action("/userList")
public class UserAction {
    @WithSpan(value = "UserAction.listUsers", kind = SpanKind.SERVER)
    public String list() {
        // 业务逻辑...
        userService.getAllUsers();
        return SUCCESS;
    }
}

// Spring Service 层
@Service
public class UserServiceImpl implements UserService {
    @WithSpan(value = "UserService.queryAllUsers", kind = SpanKind.INTERNAL)
    @Override
    public List() {
        return userDao.findAll();
    }
}

// Hibernate DAO 层
@Repository
public class UserDaoImpl implements UserDao {
    @WithSpan(value = "UserDao.findUserList", kind = SpanKind.INTERNAL)
    @Override
    public List findAll() {
        return sessionFactory.getCurrentSession().createQuery("from User").list();
    }
}

 

方案 B:全局方法扫描(零代码,测试 / 快速验证)​
通过启动脚本中的 OTEL_INSTRUMENTATION_METHODS_INCLUDE 配置,自动采集指定包下所有方法,无需添加注解,适合快速验证全链路。​
两种方案对比:​
​
方式​
 
 
 
 
适用场景​
 
 
 
 
优点​
 
 
 
 
缺点​
 
 
 
 
@WithSpan 注解​
 
 
 
 
生产环境、核心链路​
 
 
 
 
性能优、Span 命名清晰​
 
 
 
 
需少量代码修改​
 
 
 
 
全局方法扫描​
 
 
 
 
开发 / 测试、快速验证​
 
 
 
 
零代码、覆盖全面​
 
 
 
 
可能产生冗余 Span​
 
 
 
 
 
 
 
 
 
​正确格式(必须用分号;分隔,必须带 [*])
otel.instrumentation.methods.include=com.demo.web.action.*[*];com.demo.service.*[*];com.demo.dao.*[*]

含义:

  • *[*] = 类下所有方法都追踪
  • ; = 多个包之间分隔符

三、验证与问题排查​

1. 本地验证三步法​
① 启动应用
# 赋予脚本执行权限
chmod +x start-with-otel.sh
# 启动应用
./start-with-otel.sh

 

② 发送测试请求​
curl http://localhost:8080/userList

③ 验证结果​
  • 查看应用日志,若输出以下内容说明采集成功:
[otel.javaagent] LoggingSpanExporter - 'GET /userList' : traceId=xxx spanId=xxx SERVER
[otel.javaagent] LoggingSpanExporter - 'UserAction.listUsers' : traceId=xxx spanId=xxx INTERNAL
[otel.javaagent] LoggingSpanExporter - 'UserService.queryAllUsers' : traceId=xxx spanId=xxx INTERNAL
[otel.javaagent] LoggingSpanExporter - 'SELECT * FROM user' : traceId=xxx spanId=xxx CLIENT

 

  • 登录 Webfunny APM 平台,在「链路追踪」模块查看完整调用链。​

2. 常见问题排查(避坑指南)​
​
问题现象​
 
 
 
 
高频原因​
 
 
 
 
解决方案​
 
 
 
 
无 Trace 日志输出​
 
 
 
 
Agent 未加载成功​
 
 
 
 
1. 检查 -javaagent 路径是否正确;2. 确保 JDK 版本 ≥ 8;3. 避免多个 Agent 冲突(如 SkyWalking、Arthas)​
 
 
 
 
有日志但 Webfunny 无数据​
 
 
 
 
OTLP 端点不通​
 
 
 
 
1. 用 nc -zv staging.webfunny.cn 9013 测试网络连通性;2. 若 GRPC 协议报错,改为 OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf​
 
 
 
 
方法扫描未生效​
 
 
 
 
包名配置错误​
 
 
 
 
1. 包名不要加 java. 前缀;2. 多包用逗号分隔,如 com.yourapp.service.*,com.yourapp.action.*​
 
 
 
 
SQL 语句未采集​
 
 
 
 
Hibernate 版本不兼容​
 
 
 
 
确保 Hibernate 版本 ≥ 3.3,Agent 2.22.0 原生支持 3.3+ 版本​
 
 
 
 
性能下降明显​
 
 
 
 
采样率过高​
 
 
 
 
添加采样率配置:-Dotel.traces.sampler=parentbased_traceidratio -Dotel.traces.sampler.arg=0.3(30% 采样率)​
 
 
 
 
 
 
 
​
​​

四、最佳实践与性能优化​

1. 采样策略优化​
链路追踪会产生一定数据量,合理配置采样率平衡监控效果与性能:​
  • 开发 / 测试环境:全采样(-Dotel.traces.sampler=always_on);​
  • 生产环境:概率采样(如 30% 采样率)或自适应采样,避免高并发场景下的性能开销。​
2. 链路粒度控制​
  • 核心链路(支付、下单):用 @WithSpan 注解精准采集,保留完整细节;​
  • 非核心链路(查询、统计):通过全局扫描排除,或降低采样率;​
  • 排除工具类、循环调用方法,减少冗余 Span。​
3. 资源属性规范​
务必配置 deployment.environment(环境)和 service.instance.id(实例 ID),便于在 Webfunny 中区分生产 / 测试环境、不同服务器实例,快速定位问题节点。​
4. 冷数据处理​
Webfunny 支持链路数据归档,可在平台配置 TTL 策略(如 30 天),避免存储资源浪费,降低运维成本。​
​​

五、总结​

SSH 框架集成 Webfunny APM 的核心优势在于「低侵入、高覆盖」—— 通过 OpenTelemetry Java Agent 实现零代码全链路采集,配合 @WithSpan 注解精准控制粒度,完美适配老项目改造需求。对接后可实现:​
  1. 故障定位效率提升 80%:从 45 分钟缩短至分钟级;​
  1. 全链路可视化:直观查看 HTTP→Action→Service→DAO→DB 的完整调用链;​
  1. 性能瓶颈量化:精准识别慢 SQL、低效方法,为优化提供数据支撑。​
如果你的项目是 SSH 架构,且面临故障排查难、性能优化无方向的问题,不妨按照本文步骤对接 Webfunny APM,让分布式系统的运行状态一目了然。​

关于Webfunny

Webfunny专注于前端监控系统,前端埋点系统的研发。 致力于帮助开发者快速定位问题,帮助企业用数据驱动业务,实现业务数据的快速增长。支持H5/Web/PC前端、微信小程序、支付宝小程序、UniApp和Taro等跨平台框架。实时监控前端网页、前端数据分析、错误统计分析监控和BUG预警,第一时间报警,快速修复BUG!支持私有化部署,Docker容器化部署,可支持千万级PV的日活量!

  点赞 0   收藏 0
  • 一只会飞的鱼儿
    共发布86篇文章 获得10个收藏
全部评论: 0 条