핀 포인트란

yellow_note·2024년 3월 31일
0

Pinpoint

대규모 분산 시스템의 성능을 분석하고 문제를 진단, 처리하는 플랫폼입니다.
내부적으로 서버맵, 실시간 활성 스레드 차트, 요청 / 응답 차트, API 호출 상세 기록, 서버의 상태를 실시간으로 시각화하여 볼 수 있는 기능을 제공합니다.


구성

구성에 대해 간략히 살펴 보면 다음의 플로우로 진행됩니다.
1. Pinpoint Agent 대상이 되는 서버에서 Pinpoint Collector로 데이터 전달
2. Pinpoint Collector에서 Hbase 저장소로 데이터 적재
3. Pinpoint Web 모니터링 화면에서 시각화 기능 제공


Pinpoint Agent

Pinpoint Agent에서는 모니터링 정보를 수집하여, Manager 서버인 Pinpoint Collector로 데이터를 전송합니다.

Agent는 데이터 전송을 위해 추상화된 인터셉터를 이용하여 클래스 로드 시점에 애플리케이션 코드를 가로채 성능 정보와 분산 트랜잭션 추적에 필요한 코드를 주입합니다.
Spring 서버의 경우 javaagent 명령어를 사용하기 때문에 JVM 실행 중 클래스 로딩 및 실행을 모니터링하고, 조작할 수 있으며 코드의 수정이 불필요합니다.

여러 개의 스프링 서버를 모니터링 하고 싶은 경우, 각 서버 구동 시 javaagent 인자를 포함시켜 추적 데이터를 전달할 수 있도록 합니다.


javaagent란

-javaagent:<jarpath>[=<options>] 

JVM에서 동작하는 Java 애플리케이션으로 JVM의 다양한 이벤트를 전달받거나 정보 질의, 바이트코드 제어 등을 수행할 수 있습니다.

  • Agent는 지정된 JVM의 실행 가능한 최초 진입점인 main 메서드를 가로채기 할 수 있습니다.
  • 지정된 JVM에서 실행됩니다.
  • 지정된 JVM의 동일한 System Class Loader 내에서 로드됩니다.
  • 지정된 JVM의 Security Policy 및 Context의 영향을 받습니다.
  • 실행 시간에 동적으로 bytecode를 조작할 수 있습니다.
dockerfile

...
ENTRYPOINT [
	"nohup",
    "java",
    "-jar",\
	"-javaagent:./pinpoint/pinpoint-bootstrap-2.5.0.jar",\
	...
]

와 같은 식으로 작성 가능합니다.

참조: https://catsbi.oopy.io/6136946a-9139-4541-b2af-2af93bb634a5


Pinpoint Collector

Pinpoint Collector는 Agent로부터 전달받은 정보를 Hbase에 적재하는 역할입니다.

이 때 데이터 전송 시 UDP를 사용하여 서비스에 네트워크 우선권을 부여합니다.


Pinpoint 자료구조

  • span: RPC 추적을 위한 기본 단위입니다. RPC가 도착했을 때 처리한 작업을 나타내며, 추적에 필요한 데이터 및 TraceId가 있습니다. 코드 수준의 가시성 확보를 위해 Span의 자식으로 SpanEvent라는 자료구조를 가지고 있습니다.
  • Trace: Span의 집합으로, 연관된 RPC(Span)의 집합으로 구성됩니다. Span의 집합은 TransactionId가 같습니다. 그리고 SpanId와 ParentId는 RPC의 부모 관계를 나타탭니다.
  • TraceId: TransactionId와 SpanId, ParentId로 이루어진 키의 집합입니다.
  • TransactionId: 분산된 노드를 거쳐 다니는 메시지의 아이디로, 전체 서버군에서 중복되지 않습니다.
  • SPanId: RPC 메시지를 받았을 때 처리되는 작업의 아이디입니다. RPC가 노드에 도착할때 생성됩니다.
  • ParentSpanId: 호출한 부모의 SpanId를 나타냅니다


적용 예시

  1. 요청이 TomcatA에 도착 시 Agent는 TraceId를 발급합니다.
  • TX_ID: TomcatA ^ TIME ^ 1
  • SpanId: 10
  • ParentSpanId: -1 (Root)
  1. Spring Controller의 정보를 기록합니다.

  2. HttpClient.execute() 메서드의 호출을 가로채 HttpGet에 TraceId를 설정한다.

    1. 자식 TraceId 생성
      • TX_ID: TomcatA ^ TIME ^ 1 -> TomcatA^TIME^1
      • SPAN_ID: 10 -> 20
      • PARENT_SPAN_ID: -1 -> 10 (부모의 SpanId)
    2. 자식 TraceId를 HTTP 헤더에 설정
      • HttpGet.setHeader(PINPOINT_TX_ID, "TomcatA ^ TIME ^ 1")
      • HttpGet.setHeader(PINPOINT_SPAN_ID, "20")
      • HttpGet.setHeader(PINPOINT_PARENT_SPAN_ID, "10")
  3. 태그된 요청이 TomcatB로 전송됩니다.

    1. TomcatB는 전송된 요청에서 헤더를 확인합니다.
      • HttpServletRequest.getHeader(PINPOINT_TX_ID)
    2. 헤더에서 TraceId를 인식해 자식 노드로 동작한다.
      • TX_ID: TomcatA ^ TIME ^ 1
      • SPAN_ID: 20
      • PARENT_SPAN_ID: 10
  4. Spring Controller 정보를 기록하고, 요청 메시지 처리를 종료한다.

  5. Tomcat B 요청 처리가 끝나면 Agent는 추적 데이터를 Pinpoint Controller에 보내 HBase에 저장합니다.

  6. Tomcat B Http 호출이 종료된 후 TomcatA의 요청 처리도 종료됩니다. Pinpoint Agent는 추적 데이터를 Pionpoint Collector로 전송해 HBase에 저장합니다.

  7. Web은 추적 데이터를 Hbase에서 읽고, 트리를 정렬해 콜 스택을 생성합니다.

참조: https://d2.naver.com/helloworld/1194202

0개의 댓글

관련 채용 정보