接入ARMS应用监控以后,ARMS探针对常见的Java框架进行了自动埋点,因此不需要修改任何代码,就可以实现调用链信息的采集。但如果您需要跨进程传递上下文,可以引入OpenTelemetry Java SDK实现。
ARMS探针支持的组件和框架,请参见ARMS应用监控支持的Java组件和框架。
使用场景
使用私有协议跨进程网络通信时,通常客户端和服务端无法在链路中串连,这种场景需要用户自行在客户端获取Trace上下文(traceId、spanId、sampleFlag、baggage等信息)并自行传递到服务端后在服务端还原。
前提条件
引入依赖
请先参考如下Maven代码引入OpenTelemetry Java SDK。更多信息,请参见OpenTelemetry官方文档。
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-trace</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-bom</artifactId>
<version>1.23.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
跨进程传递上下文
下方代码中,CustomRpcCallMessage代表了用户私有协议中跨进程通信的数据承载实体。主要利用其中的headerMap传递上下文信息,如果实际的跨进程调用数据承载实体没有该字段,则需要手动修改代码支持该字段。
class CustomRpcCallMessage {
private Map<String, String> headerMap;
//省略其他业务字段
public String getHeader(String key) {
return headerMap.get(key);
}
public void setHeader(String key, String value) {
this.headerMap.put(key, value);
}
public Map<String, String> getHeaderMap() {
return headerMap;
}
}
public class CrossProcessPropagateDemo {
public static void clientSide(String[] args) {
CustomRpcCallMessage rpcCall = new CustomRpcCallMessage();
TextMapSetter<CustomRpcCallMessage> setter = new TextMapSetter<CustomRpcCallMessage>() {
@Override
public void set(CustomRpcCallMessage carrier, String key, String value) {
carrier.setHeader(key, value);
}
};
W3CTraceContextPropagator.getInstance().inject(Context.current(), rpcCall, setter);
W3CBaggagePropagator.getInstance().inject(Context.current(), rpcCall, setter);
}
private static void serverSide() {
//服务端获取请求
CustomRpcCallMessage rpcCall ;
TextMapGetter<CustomRpcCallMessage> getter = new TextMapGetter<CustomRpcCallMessage>() {
@Override
public Iterable<String> keys(CustomRpcCallMessage carrier) {
return carrier.getHeaderMap().keySet();
}
@Override
public String get(CustomRpcCallMessage carrier, String key) {
return carrier.getHeader(key);
}
};
Context context = W3CTraceContextPropagator.getInstance().extract(Context.current(), rpcCall, getter);
context = W3CBaggagePropagator.getInstance().extract(context, rpcCall, getter);
try (Scope scope = context.makeCurrent()) {
//省略 服务端处理逻辑
}
}
}
在实际的业务场景中,您只需要改造上面代码片段中的setter变量和getter变量的实现类,使得其对应的Set、Get方法可以保证能实现对应的语义,其余部分代码为模板代码可以直接使用。
相关文档
您可以在应用的业务日志中关联调用链的TraceId信息,从而在应用出现问题时,能够通过调用链的TraceId快速关联到业务日志,及时定位、分析解决问题。更多信息,请参见Java应用业务日志关联调用链TraceId。
文档内容是否对您有帮助?