New Relic for Java (에이전트 버전 3.37 이상)에는 비동기 활동을 계측하는 API가 포함되어 있습니다. 지원되는 프레임워크 의 경우 에이전트는 일반적으로 비동기 작업을 자동으로 계측합니다. 그러나 비동기 API는 세부 정보를 추가하는 데 여전히 유용할 수 있습니다. 이 문서는 앱을 계측하기 위해 토큰과 세그먼트를 사용하는 예를 제공합니다.
UI 에서 뉴렐릭 컴포넌트 및 디스플레이 비동기 작업 방식에 대한 자세한 내용은 로그에 대한 모델링 고려 사항을 참조하세요.
: 세그먼트는 메서드나 스레드와 반드시 연관될 필요는 없는 임의의 비동기 애플리케이션 코드 조각을 측정하는 데 사용됩니다. 세그먼트는 일반적으로 콜백 메커니즘에 의해 완료된 외부 통화를 추적하는 데 사용됩니다.
토큰: 비동기 스레드 연결
토큰을 사용하여 별도의 스레드에 있는 임의의 작업 단위를 연결합니다. 이 섹션에서는 토큰 관련 호출을 함께 사용하여 비동기 작업을 계측하는 방법을 설명합니다. 클래스 및 메소드에 대한 자세한 정보는 Javadoc을 참조하십시오.
토큰을 사용하려면 먼저 토큰을 만든 다음 다른 호출을 원래 트랜잭션에 연결해야 합니다. 다른 호출 내에서 가능한 한 빨리 토큰을 연결해야 합니다. 토큰을 즉시 연결하지 않으면 연결하려는 호출 아래에 @Trace 이 포함된 메서드가 손실될 위험이 있습니다. 원래 호출에서 토큰을 만료시킬 수도 있습니다. 그러면 Java 에이전트가 New Relic UI에서 작업을 연결합니다. 다음 예에서는 토큰 관련 호출을 함께 사용하는 방법을 보여줍니다.
아래 코드 스니펫에서 parallelStream() 메서드를 고려하세요. requestItemAsync() 에 대한 일부 호출은 별도의 스레드에서 발생하기 때문에 토큰이 생성되고 해당 비동기 작업을 다시 요청 스레드에 연결하기 위해 전달됩니다.
/**
* Example showing multi-threaded implementation of requesting data using a parallel {@link Stream}.
.map(id ->requestItemAsync(id, token))// requestItemAsync represents an example of work being passed to another thread. The token is passed along to allow linking the work on the new thread back to the thread that the token was originally created on.
@Trace(dispatcher = true): 에이전트에게 트랜잭션을 시작하도록 지시합니다. 이 방법에 대한 자세한 내용은 Javadoc 을 참조하십시오.
getToken(): 작업을 함께 연결할 토큰을 만듭니다. 이 방법에 대한 자세한 내용은 Javadoc 을 참조하십시오.
token.expire(): 토큰이 만료됩니다. 이렇게 하면 트랜잭션이 종료됩니다. 이 방법에 대한 자세한 내용은 Javadoc 을 참조하십시오.
다음 코드 예시는 요청 스레드와 별도의 스레드에서 실행될 수 있는 requestItemAsync 를 보여줍니다. 이러한 이유로 이전 코드 예에서 생성된 토큰은 requestItemAsync 의 트랜잭션에 연결됩니다. requestItemAsync() 에는 기존 트랜잭션에 연결된 경우 이 메서드를 추적하도록 에이전트에 알리는 @Trace(async=true) 주석이 있습니다.
parallelStream() 이 모든 결과를 수집한 후 토큰이 만료됩니다. 이는 parallelStream() 이 완료된 후 트랜잭션이 열린 상태로 유지되지 않도록 하기 때문에 중요합니다.
@Trace(async =true)
privateItemrequestItemAsync(long id,Token token){
token.link();
returnrequestItem(id);
}
이 샘플의 에이전트 API 호출은 다음과 같습니다.
@Trace(async = true): 트랜잭션을 시작합니다. 이 방법에 대한 자세한 내용은 Javadoc 을 참조하십시오.
token.link(): requestItemAsync() 에서 수행 중인 작업(다른 스레드에서 실행 중임)을 요청 스레드에 연결합니다. 이 방법에 대한 자세한 내용은Javadoc 을 참조하십시오.
프로세서 트레이스 세부정보를 보려면 다음으로 이동하세요. one.newrelic.com APM & services > (select an app) > Transactions > Transaction trace > Trace details.
비동기 활동은 시간 차원에서 수평으로 서로 겹치는 세그먼트로 추적 폭포 보기에 표시됩니다.
같은 스레드에 있는 메서드를 연결할 필요는 없지만 그렇게 해도 부정적인 영향은 없습니다. parallelStream() 예와 같이 단일 토큰을 공유할 수 있는 경우가 많습니다.
팁
기본적으로 트랜잭션은 최대 3000개의 토큰을 생성할 수 있으며 각 토큰의 기본 제한 시간은 180초입니다. 전자 한도는 token_limit 구성 옵션으로 변경하고 후자는 token_timeout 구성 옵션으로 변경할 수 있습니다. token_limit 를 초과하는 트랜잭션에 대한 추적에는 token_clamp 속성이 포함됩니다. 구성 옵션을 늘리면 에이전트 메모리 사용량이 늘어날 수 있습니다.
세그먼트: 임의의 비동기 활동 시간
세그먼트는 메서드나 스레드와 반드시 연관되지 않은 비동기 애플리케이션 코드의 임의 부분을 측정하는 데 사용됩니다. 이것은 외부 서비스에 대한 연결 시간에 가장 일반적으로 사용됩니다. 다음을 수행하려는 경우 세그먼트를 사용합니다.
콜백을 통해 완료되는 타임 코드
여러 메서드에 걸쳐 있는 비동기식 호출 시간
작업이 생성된 시점과 실행된 시점 사이의 시간 측정(예: 스레드 풀에서)
아래 메서드는 storeItem() 메서드를 사용하여 외부 서비스(이 경우 데이터베이스)를 호출합니다.
/**
* Example showing single threaded implementation of inserting data into a datasource.
이 경우 목표는 storeItem() 이 실행되는 시간을 결정하는 것이 아니라 실행하기 전에 Lambda 문의 Callable 이 스레드 풀에서 대기하는 시간을 찾는 것입니다. 이러한 이유로 토큰 대신 세그먼트를 사용하며 토큰의 경우와 같이 @Trace(async = true) 가 필요하지 않습니다.
이 샘플의 에이전트 API 호출은 다음과 같습니다.
@Trace(dispatcher = true): 트랜잭션을 시작합니다. 이 방법에 대한 자세한 내용은 Javadoc 을 참조하십시오.
다음 코드 예시에서는 Lambda 문이 스레드 풀에서 대기하는 시간을 측정하기 위해 storeItem 메서드에서 시작하는 세그먼트를 보여줍니다. 세그먼트 타이밍을 중지하려면 .end() 또는 .ignore() 호출해야 합니다. don't 세그먼트를 상위 트랜잭션의 일부로 보고하려면 .ignore() 호출하세요. 그렇지 않고 상위 트랜잭션의 일부로 세그먼트를 보고하려면 .end() 호출하세요.
startSegment(...): 코드의 시간을 측정할 세그먼트를 시작합니다. 이 방법에 대한 자세한 내용은 Javadoc 을 참조하십시오.
reportAsExternal(DatastoreParameters()): 시간을 데이터 저장소 외부 호출과 연결합니다. 이것은 데이터 저장소 데이터 와 함께 APM에 표시됩니다. 자세한 내용은 reportAsExternal API 를 참조하십시오.
segment.end(): 이 세그먼트의 타이밍을 중지합니다. 이 방법에 대한 자세한 내용은 Javadoc 을 참조하십시오.
메서드가 완료되면 APM은 하나의 외부 호출로 트랜잭션 추적을 표시합니다.
팁
기본적으로 에이전트는 지정된 트랜잭션 동안 최대 1000개의 세그먼트를 추적할 수 있습니다. segment_timeout 구성 옵션을 사용하여 이 제한을 변경할 수 있습니다. 이 제한을 초과하는 트랜잭션 추적에는 segment_clamp 속성이 포함됩니다. 이 제한을 늘리면 에이전트 메모리 사용량이 늘어날 수 있습니다.