全部產品
Search
文件中心

Application Real-Time Monitoring Service:通過OpenTelemetry Java SDK實現進程內非同步情境上下文傳遞

更新時間:Dec 25, 2024

接入ARMS應用監控以後,ARMS探針對常見的Java架構進行了自動埋點,因此不需要修改任何代碼,就可以實現調用鏈資訊的採集。但如果您需要在進程內的非同步情境下傳遞上下文,可以引入OpenTelemetry Java SDK實現。

ARMS探針支援的組件和架構,請參見ARMS應用監控支援的Java組件和架構

使用情境

接入ARMS應用監控以後,如果您的應用通過以下方式進行非同步編程,由於ARMS探針對這些Java架構進行了埋點,Trace上下文會自動進行非同步透傳,此時無需改造代碼。

  • 使用JDK線程池、Spring線程池、Netty線程池提交非同步任務。

  • 使用React、RxJava架構編程。

  • 使用Spring @Async註解。

  • 使用Spring Webflux、Spring Gateway等架構編程。

但如果您的應用存在以下非同步處理情境,則需要在進程內通過OpenTelemetry Java SDK手動傳遞Trace上下文:

  • 生產者消費者情境。

    線程T1在處理邏輯中將訊息放入隊列後,線程T2從隊列中拉取訊息處理,此時線程T2需要複用線程T1的Trace上下文。

  • 資料庫批處理情境。

    進程P1在處理邏輯中將一批資料寫入資料庫後,進程P2從資料庫中讀取該批資料並處理,此時進程P2需要複用進程P1的Trace上下文。

前提條件

引入依賴

請先參考如下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>

非同步上下文傳遞

下方是一個簡單的生產者消費者模式程式碼範例,在生產者中生產事件時,將生產者線程的Trace上下文記錄到事件中,在消費事件時,取出上下文並還原。

class Event {
    private Context context;
    private String msg;

    public Event(Context context, String msg) {
        this.context = context;
        this.msg = msg;
    }
}

private final LinkedBlockingQueue<Event> linkedBlockingQueue = new LinkedBlockingQueue<Event>();

public void produce(String msg) {
    linkedBlockingQueue.add(new Event(Context.current(), msg));
}

public void consume() throws Exception {
    Event event = linkedBlockingQueue.take();
    try(Scope scope = event.context.makeCurrent()) {
        processEvent(event);
    }
}

public void processEvent(Event event) {
    //todo process event
}

相關文檔

您可以在應用的業務日誌中關聯調用鏈的TraceId資訊,從而在應用出現問題時,能夠通過調用鏈的TraceId快速關聯到業務日誌,及時定位、分析解決問題。更多資訊,請參見Java應用業務日誌關聯調用鏈TraceId