'2025/11/18'에 해당되는 글 2건

  1. 2025.11.18 java CPU가 높을때 문제원인 찾는 법
  2. 2025.11.18 mongoDB 업그레이드 절차

🔥 결론: 하나의 Java 프로세스 안에 있는 thread들을 전부 분리해서 확인할 수 있다

방법은 바로 이것:


✅ 1. Linux에서 Java 프로세스의 thread를 분리해서 보는 방법

명령어

 
top -H -p <java_pid>

예:

 
top -H -p 12345

그럼 하나의 Java 프로세스(PID=12345) 안에 있는 모든 thread(TID) 가 각각 CPU를 얼마나 쓰는지 나옵니다.

예:

 
PID %CPU COMMAND 12345 10.0 java <-- 전체 12347 280.0 java <-- 문제 쓰레드(스레드 ID) 12349 12.3 java 12351 5.6 java
  • 12347: 하나의 TID(thread ID)
  • 이게 CPU 280% 먹고 있음 → 문제 쓰레드

즉, Java 한 개 프로세스 안의 각 thread CPU 사용량을 분리해서 알 수 있음.


✅ 2. 문제 thread가 “Java 내부에서 어떤 함수”를 돌고 있는지도 확인 가능

이건 Java thread dump(jstack)를 사용합니다.


Step A. thread ID(TID)를 16진수로 변환

Java thread dump는 hex 값으로 thread를 표시함.

 
printf "%x\n" 12347

출력 예:

 
303b

Step B. jstack 실행

 
jstack 12345 > /tmp/stack.txt

Step C. thread ID(hex)로 검색

 
grep -n "0x303b" /tmp/stack.txt

그럼 이렇게 나옵니다:

 
"pool-1-thread-3" #32 prio=5 tid=0x00007fda900303b nid=0x303b runnable at com.myapp.service.OrderService.process(OrderService.java:182) at com.myapp.service.OrderService.runLoop(OrderService.java:155) at java.lang.Thread.run(Thread.java:748)

여기서:

  • nid=0x303b ← 이게 바로 문제 thread
  • process() 함수에서 CPU를 많이 먹고 있음
  • runLoop() 안에서 무한 loop가 돌고 있을 수 있음

이렇게 정확한 함수 이름 + 라인번호까지 알 수 있습니다.


🔥 추가: thread 이름까지 알 수 있음

Java에서는 thread를 만들 때 이름을 붙이면

 
new Thread(() -> {...}, "Worker-1").start();

jstack에서 이렇게 보입니다:

 
"Worker-1" #25 prio=5 ...

즉,

  • thread 이름
  • thread 상태
  • thread call stack
  • CPU 점유율
  • lock(JVM monitor) 보유 여부

전부 확인 가능.


🔥 추가: thread 목록 전체 보기

 
jcmd <pid> Thread.print

또는 자동으로 thread hierarchy 확인 가능.


🔥 결론 요약

하나의 Java 프로그램이라도 내부 thread들은 개별 TID를 가지므로
CPU 사용량, 함수 위치, thread 이름 등을 전부 분리해서 확인 가능하다.

✔ top -H -p PID → thread CPU 식별
✔ printf "%x" TID → hex 변환
✔ jstack PID → thread dump
✔ grep hex → problem thread 찾기
✔ 어떤 함수인지 100% 확인 가능


원하면 지금 사용 중인 Java 서버에서
문제가 되는 thread를 실시간으로 찾는 쉘 스크립트도 만들어줄게!

나의 말:

thread ID는 찾아도 어떤 코드인지 알수는 없는건가요?

ChatGPT의 말:

알 수 있습니다.
단순히 “thread ID 숫자만 보인다 → 코드 위치는 모른다”가 아니라,
thread ID(TID) → jstack → Java 함수명 + 파일명 + 라인번호까지 정확히 찾을 수 있습니다.

즉,

thread ID만 알면 “어떤 코드(어떤 함수)가 문제인지 100% 추적 가능합니다.”

아래를 보면 왜 가능한지 이해됩니다.


🔥 핵심 개념:

리눅스에서 보이는 thread ID(TID)는 JVM 내부 스레드의 nid(native thread id)와 1:1로 매핑됩니다.

예를 들어 top에서:

 
TID = 12347

라고 CPU를 많이 먹는 스레드가 보이면,

  • 이걸 HEX로 바꾸고
  • jstack에서 해당 TID를 검색하면
  • 그 스레드가 어떤 Java 코드(메소드) 를 실행 중인지 정확히 알 수 있습니다.

실제로 이렇게 나옵니다:


🚀 실전 예제 (이게 실제로 나오는 화면)

Step1 — CPU 많이 먹는 thread 찾기

 
top -H -p <java_pid>

예:

 
12347 280% java ← 문제 스레드

Step2 — 10진수를 16진수(hex)로 변환

 
printf "%x\n" 12347

출력:

 
303b

Step3 — jstack 덤프 생성

 
jstack <java_pid> > dump.txt

Step4 — 문제 스레드 검색

 
grep -n "0x303b" dump.txt

🔥 실제로 보이는 결과

 
"pool-4-thread-1" #47 prio=5 os_prio=0 tid=0x00007fda900303b nid=0x303b runnable at com.company.payment.PaymentService.calculateFee(PaymentService.java:183) at com.company.payment.PaymentWorker.run(PaymentWorker.java:92) at java.lang.Thread.run(Thread.java:748)

즉, thread ID 하나만으로

  • 어떤 클래스인지
  • 어떤 메소드인지
  • 몇 번째 줄(line number)인지
    정확히 나온다.

여기서는:

  • calculateFee() 함수가 CPU를 폭주시키고 있음
  • 파일: PaymentService.java
  • 라인: 183

이 수준까지 바로 알 수 있습니다.


💡 정리하면

❗ thread ID 자체로는 코드 이름이 안 보이지만

❗ thread ID → jstack 검색을 하면

👉 스레드가 실행 중인 메소드
👉 메소드가 있는 클래스
👉 Java 파일 이름
👉 라인 번호
👉 Lock held 여부
👉 JVM 상태(runnable / waiting / blocked)

까지 전부 알 수 있습니다.


🎯 결론

thread ID만 알면 어떤 코드가 문제인지 100% 찾아낼 수 있습니다.
단순한 추론이 아니라, 실제 Java stack trace에 메소드/라인번호가 정확히 찍힙니다.

Posted by yongary
,

✅ 1. MongoDB 5.0 지원 종료 사실

MongoDB 5.0은 2024년 10월부로 End of Life(EOL) 입니다.
→ Security patch 포함 지원 없음, CVE 발생 시 패치 불가

현재 지원되는 LTS 버전은:

  • 6.0 LTS
  • 7.0 LTS

즉, 실질적 업그레이드 목표는:

 
5.0 → 6.0 → 7.0

(6.0을 LTS로 오래 운영해도 됨)

MongoDB는 메이저 버전 건너뛰기 업그레이드를 허용하지 않습니다.
5 → 7로 직접 업그레이드하면 ReplicaSet 자체가 깨집니다.


✅ 2. “서비스 중단 없이” 업그레이드할 수 있는 구조

현재 EC2 3대로 구동 중이라면 아마 아래 형태일 거예요:

 
Replica Set - Primary - Secondary - Secondary

이 구조에서는 롤링 업그레이드(Rolling Upgrade) 를 사용하면
서비스 중단 없이 업그레이드 가능합니다.


✅ 3. 정식 업그레이드 절차 (MongoDB 공식 절차 기반)

전체 플로우

 
1) Pre-check (호환성, 스토리지 엔진, Feature Compatibility Version) 2) Secondary 1대 업그레이드 3) Secondary 2대 업그레이드 4) Primary를 Step Down 후 업그레이드 5) FCV 변경 6) 클러스터 정상화 확인

아래에 실제 현장에서 쓰는 구체 절차를 적어볼게요.


🔥 4. 실제 상세 절차

Step 0 — 백업/스냅샷 생성

  • EC2 EBS Snapshot
  • 혹은 mongodump
    → 실패 시 즉각 롤백 가능하게

Step 1 — 사전 체크

mongo 콘솔에서:

 
db.adminCommand({ getParameter: 1, featureCompatibilityVersion: 1 })

FCV가 5.0이어야 정상.

또한:

 
rs.status() rs.conf()

오류 없는지 확인.


Step 2 — Secondary 한 대를 업그레이드

  1. Secondary 한 대를 선택
  2. mongod 종료
 
sudo systemctl stop mongod
  1. MongoDB 6.0 패키지 설치
    (amazon linux / ubuntu에 따라 다름 — 필요하면 상세 스크립트 제공 가능)
  2. 재기동
 
sudo systemctl start mongod
  1. 클러스터 정상 합류 확인
 
rs.status()
  1. oplog sync OK 확인

→ 이 서버가 6.0으로 잘 돌아가면 계속 진행.


Step 3 — 나머지 Secondary도 동일 절차로 업그레이드


Step 4 — Primary 업그레이드

Primary는 직접 Upgrade 하면 다운타임 위험 있으므로:

  1. Primary를 강제로 step down
 
rs.stepDown()

→ 다른 Secondary가 Primary가 됨
서비스 중단 없음

  1. 기존 Primary 서버를 mongod stop
  2. MongoDB 6.0 설치 후 start

Step 5 — FeatureCompatibilityVersion 변경

모든 노드가 6.0에서 정상적으로 올라온 뒤:

 
db.adminCommand({ setFeatureCompatibilityVersion: "6.0" })

Step 6 — 정상 동작 확인

  • rs.status()
  • replication lag 확인
  • 애플리케이션 write/read 정상 동작 확인
  • op log 증가 확인
  • mongod.log 에 error 없는지

🔁 6. (선택) 6.0 → 7.0 업그레이드

같은 방식으로 “롤링 업그레이드” 하면 됩니다.

 
5.0 → 6.0 → 안정화 후 → 7.0

바로 7.0까지 갈 필요 없으면 6.0 LTS 유지해도 안전합니다.


⚠️ “바로 5.x → 7.x or 5.x → 5.9.x” 하면 안 되는 이유

  • MongoDB는 메이저 버전 건너뛰기 허용 안함
  • WiredTiger 스토리지 메타데이터가 다름
  • FCV 매커니즘 때문에 클러스터 자체가 올라오지 않음
  • 5.9는 정식 릴리즈가 아님 (개발 프리뷰)

🧩 추가 고려사항 (실무에서 꼭 필요)

✔︎ 바뀌는 parameter / deprecated 기능

  • setParameter, replication.enableMajorityReadConcern 같은 값의 호환성 체크

✔︎ Driver 버전 업데이트

Node/Java/Python에서 MongoDB Driver도 버전 호환 필요

  • 6.x 이상에서는 5.x 드라이버가 deprecated 되는 경우 있음

✔︎ Monitoring (CloudWatch/Datadog/Prometheus)

업그레이드 후 connection pool 동작이 달라질 수 있음


🎯 최종 요약

MongoDB 5.0 → 6.0 롤링 업그레이드 절차

  1. Snapshot/백업 생성
  2. FCV 확인
  3. Secondary 1 업그레이드 → 정상 확인
  4. Secondary 2 업그레이드
  5. Primary stepDown → 업그레이드
  6. 6.0 전체 업 후 FCV 6.0 설정
  7. 정상 동작 확인
  8. (선택) 같은 방식으로 7.0까지 업그레이드 가능

👉 서비스 중단 없음 (Zero downtime 유지 가능)
👉 메이저는 반드시 계단식 업그레이드 (5 → 6 → 7)

Posted by yongary
,