2026-01-19

1일 1아티클

QuestDB

프로그래머의 존재 의의

문제 상황

  • DB 내에서 어떤 작업이 CPU를 많이 소모하는지 실시간 모니터링
  • 시도 방법 : Java 표준 API ThreadMXBean.getCurrentThreadUserTime() 통한 스레드별 CPU 사용 내역 주기적 확인
  • 결과 : 모니터링 도구가 오히려 성능을 잡아먹는 범인이 됨

원인 분석

  • 작동 원리 : 사용된 Java method는 리눅스에서 getrusage() 시스템 함수 호출
  • 병목 구간 : getrusage()는 커널 내부 데이터를 읽을 때, 안전을 위해 Lock 걸어버림
  • 문제 발생 : 수많은 스레드가 동시에 CPU 소모량을 보기 위해 함수 호출 시, 하나의 Lock을 차지하기 위해 모든 스레드가 대기하는 상황 발생

해결 방법

  • Lock 없이 정보를 얻을 수 있는 방법으로 선회
  • 방법 : 리눅스의 /proc 파일 시스템 직접 read
  • 장점 : 파일을 직접 읽어서 CPU 시간 파싱하는 방식은 커널의 무거운 락을 건드리지 않고 데이터 가져오기 가능

결과

  • JMH 테스트 벤치마크
  • 기존 방식 : 초당 60만번 호출 가능
  • 개선 방식 : 초당 1,500만번 호출 가능 (약 25배 성능 향상)

오늘 배운 것

  1. 메인기능 CRUD
  2. Swagger 설정

트러블슈팅

Default 설정 누락 문제

문제 상황

  • java.sql.SQLIntegrityConstraintViolationException: Column 'status' cannot be null
  • Lombok의 @Builder 동작 방식 : 필드 명시적 지정을 통해 객체 생성하는 패턴. 이때 값이 설정되지 않은 필드는 해당 타입의 기본값(null, 0, etc.)으로 초기화
  • 문제 원인 : @Builder 사용 시, 클래스 필드에 직접 할당한 초기값은 기본적으로 무시됨
  • @ColumnDefault("'OPEN'") 동작 방식 : Hibernate의 기능, 주로 DDL 생성 시 관여. JPA가 INSERT문 생성 시 필드값이 null이면, SQL에 명시적으로 NULL 포함하여 전송.
  • 문제 원인 2 : DB는 명시적으로 NULL 값이 들어오면 컬럼의 DEFAULT 값 사용이 아닌, NOT NULL 제약조건 우선 확인 → 에러 발생

해결 방법

  • 엔티티 필드에 @Builder.Default 추가
  • @Builder 패턴 사용 시, 해당 필드 값을 명시적 설정하지 않으면 필드에 직접 할당된 초기값을 기본값으로 사용

내일 할 일

  1. WebRTC

참고자료

results matching ""

    No results matching ""