接入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。