Pinpoint WebSphere 插件接入指南:配置详解与源码级原理剖析
2026/9/23 3:58:53 网站建设 项目流程

Pinpoint WebSphere 插件接入指南:配置详解与源码级原理剖析

【免费下载链接】pinpointAPM, (Application Performance Management) tool for large-scale distributed systems.项目地址: https://gitcode.com/gh_mirrors/pi/pinpoint

导读

本文以 Pinpoint 仓库中 agent-module/plugins/websphere/README.md 为主体,系统讲解 Pinpoint 如何对 IBM WebSphere Application Server 进行 APM 监控:从 pinpoint.config 中profiler.websphere.*系列参数的逐项说明,到插件在 WebSphere 内部的字节码增强点、请求入口拦截、状态码采集与异步 Servlet 链路传播的实现原理。读完本文,你将能够独立完成 WebSphere(6.1~8 版本区间)应用服务器的 Pinpoint 接入配置,并根据实际场景调优请求参数追踪、URL/HTTP 方法排除、真实 IP 头识别等选项,同时理解每一项配置背后的源码落点。

WebSphere 插件概述

WebSphere 插件是 Pinpoint 众多 Servlet 容器类插件 之一,用于在IBM WebSphere Application Server上采集 HTTP 请求的调用链数据。根据官方 README 声明:

  • 引入版本:Pinpoint 1.7.0 起提供;
  • 支持版本区间[6.1, 8],即 WebSphere Application Server 6.1 至 8.x;
  • 插件源码位置:agent-module/plugins/websphere。

该插件在 Pinpoint 服务类型体系中注册了两个ServiceType,定义见 WebsphereConstants.java:

ServiceType 常量类型码说明
WEBSPHERE1060WebSphere 应用服务器本身,启用RECORD_STATISTICS用于统计
WEBSPHERE_METHOD1061WebSphere 内部方法调用(如请求入口、异步启动点)

插件 Maven 坐标与打包方式见 pom.xml:artifactId 为pinpoint-websphere-plugin,它依赖pinpoint-bootstrap-corejavax.servlet-api(均为provided作用域),并依赖pinpoint-common-servlet(编译期打入插件 jar 并重定位到com.navercorp.pinpoint.plugin.websphere.common.servlet,避免与宿主的类冲突)。

提示:插件对 WebSphere 内部类的引用通过独立的src/main/java-ibm源目录提供(由build-helper-maven-plugingenerate-sources阶段加入编译),其中以com.ibm.*包名定义了IRequestIResponseSRTServletRequestWCCResponseImpl等接口的占位实现,供编译期使用。

接入配置:pinpoint.config

WebSphere 插件的全部开关均位于 agent 的pinpoint.config文件中。官方 README 给出的配置片段,在仓库的 release 环境默认配置 中有完整的对应段落(profiler.weblogic.*之后的# Websphere段落),两者内容一致。

启用开关

profiler.websphere.enable=true
  • 含义:是否启用 WebSphere 插件。
  • 默认值:true(源码中config.readBoolean("profiler.websphere.enable", true),见 WebsphereConfiguration.java)。
  • 源码行为:在 WebspherePlugin.setup() 中,若该值为false,插件直接返回,不做任何字节码注入。

应用服务器类型识别

# Classes for detecting application server type. Comma separated list of fully qualified class names. Wildcard not supported. profiler.websphere.bootstrap.main=
  • 含义:用于识别"当前进程是否为 WebSphere"的主类名列表,多个类名用逗号分隔,不支持通配符
  • 默认行为:留空时使用内置默认值com.ibm.wsspi.bootstrap.WSPreLauncher,见 WebsphereDetector.java。
  • 检测机制:插件通过MainClassCondition读取 JVM 启动主类(bootstrapMainClass),与上述列表比对;命中后才向 Pinpoint 注册WEBSPHERE(1060)应用类型(前提是 WebspherePlugin.java 中context.getConfiguredApplicationType()尚未被其他方式显式指定)。

请求参数追踪

# trace param in request , default value is true profiler.websphere.tracerequestparam=true
  • 含义:是否在 Span 中记录 HTTP 请求的查询字符串参数。

  • 默认值:true

  • 源码行为:WebsphereConfiguration通过ServerConfig.isTraceRequestParam("profiler.websphere.tracerequestparam")读取。参数采集的完整链路见 ParameterRecorderFactory.java:

    • false时,使用DisableParameterRecorder,完全跳过参数提取;
    • true时,由 IRequestParameterExtractor.java 解析IRequest.getQueryString(),逐个拆分key=value对并做 URL 解码,单 key/value 截断长度为 64 字符(eachLimit=64),拼接总长度上限 512 字符(totalLimit=512),超限后以...结尾,防止超长参数拖垮 Span 数据。
    ParameterExtractor<IRequest> parameterExtractor = new IRequestParameterExtractor(64, 512);

排除 URL

# URLs to exclude from tracing. # Support ant style pattern. e.g. /aa/*.html, /??/exclude.html profiler.websphere.excludeurl=
  • 含义:不参与追踪的 URL 列表(逗号分隔),支持Ant 风格通配,例如:
    • /aa/*.html:匹配/aa/下所有.html页面;
    • /??/exclude.html?匹配任意单个字符。
  • 默认值:空,表示不排除任何 URL。
  • 源码行为:经ServerConfig.getExcludeUrlFilter("profiler.websphere.excludeurl")构造为Filter<String>,在 WebContainerHandleRequestInterceptor 中通过builder.setExcludeURLFilter(...)注入ServletRequestListener,命中排除规则的请求不会开启追踪。

排除 HTTP 方法

# HTTP Request methods to exclude from tracing profiler.websphere.excludemethod=
  • 含义:不参与追踪的 HTTP 方法(如GETPOST等,逗号分隔)。

  • 默认值:空。

  • 源码行为:读取为excludeProfileMethodFilter,见 WebsphereConfiguration.java。它同时作用于两个层面:

    1. Span 级:不满足过滤条件的方法仍会记录调用链,但(结合tracerequestparam)不记录参数;
    2. 在 MethodFilterExtractor.java 中,被排除的方法会返回null,从而跳过参数提取。

    另外 release 配置中还预留了一个与 Servlet 通用机制对齐的扩展项:

    # profiler.websphere.trace.excludemethod=

    它在源码中对应ServerConfig.getTraceExcludeMethodFilter("profiler.websphere.trace.excludemethod")(WebsphereConfiguration.java),用于在追踪阶段排除特定方法的 Span 记录。

隐藏 Pinpoint 请求头

# Hide pinpoint headers. profiler.websphere.hidepinpointheader=true
  • 含义:是否在getHeaderNames()返回的头部枚举中过滤掉 Pinpoint 内部使用的请求头(如Pinpoint-TraceID等,见com.navercorp.pinpoint.bootstrap.context.Header)。
  • 默认值:true
  • 源码行为:当开启时,插件对com.ibm.ws.webcontainer.srt.SRTServletRequest织入 SRTServletRequestAspect,将原始getHeaderNames()返回的Enumeration包装为DelegateEnumeration,并用Header.FILTER过滤内部头(WebspherePlugin.java)。该选项主要服务于将请求转发给下游应用时,避免把 Pinpoint 内部头暴露给业务代码。

原始 IP 地址识别(注释示例)

# original IP address header # https://en.wikipedia.org/wiki/X-Forwarded-For #profiler.websphere.realipheader=X-Forwarded-For # nginx real ip header #profiler.websphere.realipheader=X-Real-IP #profiler.websphere.realipemptyvalue=unknown
  • 含义:
    • profiler.websphere.realipheader:指定承载客户端真实 IP 的请求头名称。当 WebSphere 位于 nginx、反向代理或负载均衡之后时,getRemoteAddr()拿到的是代理地址,配置此头可让 Pinpoint 记录真实客户端 IP。release 配置中还给出了多值头示例X-Forwarded-For, Forwarded(对应 RFC 7239 的Forwarded头)。
    • profiler.websphere.realipemptyvalue:可选参数。当上述头的取值为该配置值(如unknown)时,Pinpoint 会忽略该头值,视为无效 IP,避免把占位字符串当作客户端地址。
  • 默认值:realipheader默认按 Pinpoint 全局服务器配置处理,这两项在 release 配置中默认注释,按需取消注释即可。

完整配置清单

以下为官方 README 的原始配置块(可直接粘贴到pinpoint.config):

#### Set enable options. profiler.websphere.enable=true # Classes for detecting application server type. Comma separated list of fully qualified class names. Wildcard not supported. profiler.websphere.bootstrap.main= # trace param in request , default value is true profiler.websphere.tracerequestparam=true # URLs to exclude from tracing. # Support ant style pattern. e.g. /aa/*.html, /??/exclude.html profiler.websphere.excludeurl= # HTTP Request methods to exclude from tracing profiler.websphere.excludemethod= # Hide pinpoint headers. profiler.websphere.hidepinpointheader=true # original IP address header # https://en.wikipedia.org/wiki/X-Forwarded-For #profiler.websphere.realipheader=X-Forwarded-For # nginx real ip header #profiler.websphere.realipheader=X-Real-IP #profiler.websphere.realipemptyvalue=unknown

源码级原理:插件如何改造 WebSphere

官方 README 只给出了配置项,本插件的实际监控能力由 WebspherePlugin.java 中的四处字节码转换(Transform)完成。理解这四处改造点,有助于排查"为什么某个环节没有 Span"。

请求入口:WSWebContainer.handleRequest

插件对com.ibm.ws.webcontainer.WSWebContainerhandleRequest(IRequest, IResponse)方法注入 WebContainerHandleRequestInterceptor(WebspherePlugin.java):

  • before:调用servletRequestListener.initialized(request, WEBSPHERE_METHOD, methodDescriptor),开启新的 Trace/Span,作为 WebSphere 请求的入口点
  • after:根据响应对象取状态码,调用servletRequestListener.destroyed(request, throwable, statusCode),结束 Span 并记录异常与响应码。

该拦截器同时负责:

  • 请求数据适配:通过 IRequestAdaptor.java 将 IBM 的IRequest适配为 Pinpoint 的RequestAdaptor,提供getRpcName(取getRequestURI())、getMethodNamegetEndPointhost:port)、getRemoteAddressgetAcceptorHost等字段;
  • 记录请求头与 Cookie:分别读取ServerHeaderRecorder.CONFIG_KEY_RECORD_REQ_HEADERSServerCookieRecorder.CONFIG_KEY_RECORD_REQ_COOKIES对应的全局配置;
  • 记录 HTTP 状态码错误:通过HttpStatusCodeErrors.of(profilerConfig::readString)读取全局的 HTTP 状态码错误判定配置(对应profiler.http.status.code.errors等项)。

状态码采集:WCCResponseImpl.setStatusCode

com.ibm.ws.webcontainer.channel.WCCResponseImpl会被:

  1. 添加StatusCodeAccessor字段(StatusCodeAccessor.java),用于暂存状态码;
  2. setStatusCode(int)注入 WCCResponseImplInterceptor,在before中把状态码写入 accessor 字段。

之后入口拦截器在after阶段通过StatusCodeAccessor._$PINPOINT$_getStatusCode()读取;若响应对象本身是WCCResponseImpl且尚未注入 accessor,则回退到getHttpResponse().getStatusCodeAsInt()(见 WebContainerHandleRequestInterceptor.java)。这样 WebSphere 应用在 Pinpoint 中即可按 HTTP 状态码维度进行错误统计与分析。

隐藏头与异步链路:SRTServletRequest 与 WSAsyncContextImpl

  • com.ibm.ws.webcontainer.srt.SRTServletRequest:如前文所述,按hidepinpointheader决定是否织入头部过滤 Aspect;同时对其startAsync(ServletRequest, ServletResponse)(Servlet 3.0 异步 API)注入 WCCRequestImplStartAsyncInterceptor,在异步启动成功后创建 WebsphereAsyncListener 并注册到AsyncContext,从而把异步线程的执行纳入同一条调用链;
  • com.ibm.ws.webcontainer.async.WSAsyncContextImpl:添加InitResponseGetter(InitResponseGetter.java),使异步监听器在onComplete时能够取出初始响应对象的状态码,完整记录异步请求的最终 HTTP 结果(WebsphereAsyncListener.java)。

应用类型探测:WebsphereDetector

插件在启动阶段通过 WebsphereDetector.java 判定当前进程是否为 WebSphere:将 JVM 启动主类与profiler.websphere.bootstrap.main(默认com.ibm.wsspi.bootstrap.WSPreLauncher)比对,命中即注册WEBSPHERE(1060)应用类型。因此,即使你不配置该参数,只要应用确实运行在 WebSphere 上,插件也能自动完成类型识别。

插件装配与验证

  • 装配方式pinpoint-websphere-plugin属于 agent-module/plugins 聚合模块,构建 agent 时插件 jar 会被统一打包进 agent 的plugin目录,agent 启动时自动加载,无需额外安装。
  • 配置生效位置:所有profiler.websphere.*参数写入 agent 的pinpoint.config(release 默认配置见 release/pinpoint.config,local 环境同样内置对应段落)。
  • 验证方法
    1. 修改配置后重启应用服务器,观察 agent 日志中Detected application type : WEBSPHEREAdding WebSphere transformers等输出(对应 WebspherePlugin.java);
    2. 在 Pinpoint Web 界面确认应用类型显示为 WEBSPHERE,并检查 HTTP 请求是否有完整调用链;
    3. 若请求未产生 Span,优先核对profiler.websphere.enableexcludeurl/excludemethod是否误配,以及启动主类是否与bootstrap.main匹配。

小结

WebSphere 插件是 Pinpoint 服务器插件体系中典型的 Servlet 容器接入实现,其 README 虽短,却完整覆盖了接入所需的核心开关。本文在继承官方配置的基础上,进一步结合 WebsphereConfiguration.java、WebspherePlugin.java 与 release/pinpoint.config 等源码证据,说明了每个配置项的实际生效链路:入口拦截、参数提取、URL/方法过滤、状态码采集、真实 IP 识别与 Servlet 3.0 异步链路传播。按本文清单配置并观察 agent 日志,即可在 WebSphere 6.1~8 上完成 Pinpoint 的接入与调优。

【免费下载链接】pinpointAPM, (Application Performance Management) tool for large-scale distributed systems.项目地址: https://gitcode.com/gh_mirrors/pi/pinpoint

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询