πŸš€ jackson blackbird둜 μ „ν™˜ν•΄μ„œ json μ§€μ—°μ‹œκ°„μ„ λŒ€ν­ 쀄인 방법

Β·5 min readΒ·1Β·
πŸš€ Jackson Blackbird둜 μ „ν™˜ν•΄μ„œ JSON μ§€μ—°μ‹œκ°„μ„ λŒ€ν­ 쀄인 방법

πŸš€ Jackson Blackbird둜 μ „ν™˜ν•΄μ„œ JSON μ§€μ—°μ‹œκ°„μ„ λŒ€ν­ 쀄인 방법

πŸ’‘ 핡심 λ©”μ‹œμ§€

Jackson Blackbirdλ₯Ό λ„μž…ν•΄μ„œ 33% μ§€μ—°μ‹œκ°„ κ°μ†Œ, 12% λ©”λͺ¨λ¦¬ μ ˆμ•½μ„ λ‹¬μ„±ν•œ μ‹€μ „ κ²½ν—˜λ‹΄


🎯 TL;DR

2025λ…„, μ„±λŠ₯이 λͺ¨λ“  것을 μ’Œμš°ν•©λ‹ˆλ‹€. κ³ μ²˜λ¦¬λŸ‰ REST APIλ₯Ό λ‹€λ£¨λŠ” Java κ°œλ°œμžλ‘œμ„œ, JSON 처리 병λͺ©ν˜„상에 μ’Œμ ˆν•˜κ³  μžˆμ—ˆμŠ΅λ‹ˆλ‹€. Jackson의 databind APIλŠ” μ•ˆμ •μ μ΄μ—ˆμ§€λ§Œ μ΄ˆλ‹Ή 수천 개의 μš”μ²­μ„ μ²˜λ¦¬ν•˜λŠ” λ§ˆμ΄ν¬λ‘œμ„œλΉ„μŠ€μ—λŠ” λ„ˆλ¬΄ λŠλ ΈμŠ΅λ‹ˆλ‹€.

그러던 쀑 μƒλ‹Ήν•œ μ„±λŠ₯ ν–₯상을 μ•½μ†ν•˜λŠ” Jackson Blackbird λͺ¨λ“ˆμ„ λ°œκ²¬ν–ˆμŠ΅λ‹ˆλ‹€. μ „ν™˜μ„ κ²°μ •ν–ˆκ³ , κ·Έ κ²°κ³ΌλŠ” ν˜μ‹ μ μ΄μ—ˆμŠ΅λ‹ˆλ‹€.


🚨 JSON μ§€μ—°μ‹œκ°„ 문제

문제 상황

  • JSON 직렬화/μ—­μ§λ ¬ν™”λŠ” ν˜„λŒ€ μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ ν•΅μ‹¬μ΄μ§€λ§Œ μ„±λŠ₯ 병λͺ©μ§€μ 
  • Jackson databindλŠ” κΈ°λŠ₯이 ν’λΆ€ν•˜μ§€λ§Œ λ°˜μ‚¬(reflection) 의쑴으둜 μ˜€λ²„ν—€λ“œ λ°œμƒ
  • 우리 API: λ³΅μž‘ν•œ JSON νŽ˜μ΄λ‘œλ“œ μ²˜λ¦¬μ— μš”μ²­λ‹Ή 100-150ms μ†Œμš”
  • μ§€μ—°μ‹œκ°„ λͺ©ν‘œμ— λΆ€μ ν•©ν•œ μ„±λŠ₯

ν•΄κ²°μ±… 발견

Jackson Blackbird (Afterburner의 μ§„ν™” 버전)

  • βœ… μ½”λ“œ 생성을 톡해 λ°˜μ‚¬ 우회
  • βœ… POJO 기반 μž‘μ—…μ—μ„œ 20-40% μ„±λŠ₯ ν–₯상 약속

⚑ μ „ν™˜ κ³Όμ •

1단계: μ˜μ‘΄μ„± μΆ”κ°€ 및 μ„€μ •

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.blackbird.BlackbirdModule;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    private final ObjectMapper mapper;

    public UserController() {
        // πŸ”₯ Blackbird λͺ¨λ“ˆ 등둝
        this.mapper = new ObjectMapper().registerModule(new BlackbirdModule());
    }

    @PostMapping("/users")
    public User processUser(@RequestBody String json) throws Exception {
        User user = mapper.readValue(json, User.class);
        // μ‚¬μš©μž 처리 (예: λ°μ΄ν„°λ² μ΄μŠ€ μ €μž₯)
        return mapper.readValue(mapper.writeValueAsString(user), User.class);
    }
}

2단계: 데이터 λͺ¨λΈ μ •μ˜

// λ³΅μž‘ν•œ 쀑첩 ꡬ쑰의 POJO
record User(
    Long id,
    String name,
    String email,
    int age,
    boolean isSubscribed,
    List<Order> orders
) {}

record Order(String orderId, double totalAmount) {}

πŸ’‘ 포인트: JSON νŽ˜μ΄λ‘œλ“œλ₯Ό User 객체둜 역직렬화 β†’ 처리 β†’ μž¬μ§λ ¬ν™”ν•˜λŠ” 일반적인 API μ›Œν¬ν”Œλ‘œμš°


πŸ—οΈ μ•„ν‚€ν…μ²˜

μ‹œμŠ€ν…œ ꡬ쑰도

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    Spring Boot App      β”‚ ← Virtual Threads ν™œμš©
β”‚   (Virtual Threads)     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Jackson Blackbird     β”‚ ← πŸ”₯ μ½”λ“œ μƒμ„±μœΌλ‘œ μ„±λŠ₯ μ΅œμ ν™”
β”‚   (Code Generation)     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Jackson Databind      β”‚ ← JSON νŒŒμ„œ/생성기
β”‚   (JSON Parser/Gen)     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  HTTP Request/Response  β”‚
β”‚     (JSON Payload)      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

핡심 λ™μž‘ 원리

  • Blackbird: μ½”λ“œ μƒμ„±μœΌλ‘œ POJO 직렬화/역직렬화 가속화
  • Jackson Core: μ›μ‹œ JSON 토큰 처리 λ‹΄λ‹Ή

πŸ“Š 벀치마크 κ²°κ³Ό

ν…ŒμŠ€νŠΈ ν™˜κ²½

  • μ„œλ²„: 16μ½”μ–΄, 32GB RAM
  • 도ꡬ: JMH (Java Microbenchmark Harness)
  • 데이터: 1,000개 μ‚¬μš©μž λ ˆμ½”λ“œ (μœ„ User ν΄λž˜μŠ€μ™€ μœ μ‚¬)

μ„±λŠ₯ 비ꡐ

μ§€ν‘œJackson DatabindJackson Blackbirdκ°œμ„ μœ¨
μ²˜λ¦¬λŸ‰1,200 ops/sec1,800 ops/sec+50% ⬆️
평균 μ§€μ—°μ‹œκ°„120ms80ms-33% ⬇️
λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰400MB350MB-12% ⬇️

🎯 μ‹€μ œ μ„œλΉ„μŠ€ μ„±κ³Ό

  • 처리 λŠ₯λ ₯: μ΄ˆλ‹Ή 5,000개 μš”μ²­ 처리 κ°€λŠ₯
  • 응닡 μ‹œκ°„: 100ms 미만 μ§€μ—°μ‹œκ°„ 달성
  • μ‚¬μš©μž κ²½ν—˜: κ²Œμž„ 체인저급 κ°œμ„ 

🌟 μ‹€μ œ ν™˜κ²½μ—μ„œμ˜ 영ν–₯

βœ… 긍정적 λ³€ν™”

  • πŸš€ ν”„λ‘œλ•μ…˜ API 응닡 속도 체감할 μ •λ„λ‘œ κ°œμ„ 
  • πŸ“‰ μ‚¬μš©μž λŒ€λ©΄ μ—”λ“œν¬μΈνŠΈ P99 μ§€μ—°μ‹œκ°„ 30% κ°μ†Œ
  • πŸ’° ν•˜λ“œμ›¨μ–΄ μΆ”κ°€ 없이 λ§ˆμ΄ν¬λ‘œμ„œλΉ„μŠ€ ν™•μž₯ κ°€λŠ₯
  • ⚑ 인프라 λΉ„μš© μ ˆμ•½ 효과

⚠️ μ£Όμ˜μ‚¬ν•­

  • POJOμ—μ„œλ§Œ μ΅œμ ν™”: JsonNode μž‘μ—…μ—μ„œλŠ” μ„±λŠ₯ ν–₯상 μ—†μŒ
  • κ΅¬μ‘°ν™”λœ 데이터에 μ ν•©ν•œ μ†”λ£¨μ…˜

πŸ› οΈ 도전과 κ΅ν›ˆ

λ°œμƒν•œ λ¬Έμ œλ“€

λ¬Έμ œμ›μΈν•΄κ²°μ±…
Java ν˜Έν™˜μ„±Java 8 λ ˆκ±°μ‹œ λͺ¨λ“ˆβœ… Java 11+ μ—…κ·Έλ ˆμ΄λ“œ
디버깅 μ–΄λ €μ›€μƒμ„±λœ μ½”λ“œμ˜ λ³΅μž‘ν•œ μŠ€νƒ μΆ”μ βœ… VisualVM λ“± ν”„λ‘œνŒŒμΌλ§ 도ꡬ ν™œμš©
μ‹œμž‘ μ‹œκ°„ μ¦κ°€μ½”λ“œ 생성 μ˜€λ²„ν—€λ“œβœ… λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰ λͺ¨λ‹ˆν„°λ§

🎯 베슀트 ν”„λž™ν‹°μŠ€

ꢌμž₯μ‚¬ν•­μ΄μœ 
ObjectMapper μΈμŠ€ν„΄μŠ€ μž¬μ‚¬μš©μ΄ˆκΈ°ν™” μ˜€λ²„ν—€λ“œ λ°©μ§€
μ‹€μ œ νŽ˜μ΄λ‘œλ“œλ‘œ ν…ŒμŠ€νŠΈλ°μ΄ν„° ꡬ쑰에 λ”°λ₯Έ μ„±λŠ₯ 차이 쑴재
λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰ λͺ¨λ‹ˆν„°λ§μ½”λ“œ μƒμ„±μœΌλ‘œ μΈν•œ 영ν–₯ 좔적

πŸ’‘ Blackbirdκ°€ μ€‘μš”ν•œ 이유

πŸš— β†’ 🏎️ μ—…κ·Έλ ˆμ΄λ“œ κ²½ν—˜

"μ„Έλ‹¨μ—μ„œ 슀포츠카둜 μ—…κ·Έλ ˆμ΄λ“œν•˜λŠ” 것 κ°™μ•˜μŠ΅λ‹ˆλ‹€"

  • μ½”λ“œ μž‘μ„± 방식 λ³€κ²½ λΆˆν•„μš”
  • μ„±λŠ₯만 λŒ€ν­ ν–₯상
  • 2025λ…„ λ°€λ¦¬μ΄ˆκ°€ μ€‘μš”ν•œ μ‹œλŒ€μ— ν•„μˆ˜ 도ꡬ

적용 μ‹œλ‚˜λ¦¬μ˜€

βœ… μ ν•©ν•œ 경우❌ λΆ€μ ν•©ν•œ 경우
JSON 쀑심 κ³ μ„±λŠ₯ APIJPA 쀑심 μ• ν”Œλ¦¬μΌ€μ΄μ…˜
POJO 기반 직렬화JsonNode 쀑심 처리
λ³΅μž‘ν•œ 쀑첩 κ΅¬μ‘°λ‹¨μˆœν•œ JSON λ³€ν™˜
Java 11+ ν™˜κ²½λ ˆκ±°μ‹œ Java 8 μ‹œμŠ€ν…œ

🎬 마무리

개발자의 μ†”μ§ν•œ ν›„κΈ°

"μ²˜μŒμ—” κ³Όμž₯된 것 μ•„λ‹Œκ°€ νšŒμ˜μ μ΄μ—ˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ Blackbirdκ°€ μ§€μ—°μ‹œκ°„μ„ 쀄이고 우리 μ„œλΉ„μŠ€λ₯Ό ν™•μž₯ν•˜λŠ” 것을 λ³Έ ν›„ ν™•μ‹ ν•˜κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€."

πŸš€ μΆ”μ²œ λŒ€μƒ

JSON μ„±λŠ₯ 문제둜 κ³ λ―Ό 쀑인 개발자라면 Blackbirdλ₯Ό κΌ­ μ‹œλ„ν•΄λ³΄μ„Έμš”!

  • πŸ‘₯ μ‚¬μš©μžκ°€ 감사할 κ²ƒμž…λ‹ˆλ‹€
  • πŸ’» μ„œλ²„λ„ 감사할 κ²ƒμž…λ‹ˆλ‹€

πŸ“Ž κ΄€λ ¨ νƒœκ·Έ

#Java #SpringBoot #JSON #Performance #Jackson #Blackbird #APIμ΅œμ ν™”


πŸ“š 좜처 정보

원문: I Switched to Jackson Blackbird and Slashed JSON Latency: Here's How It Changed Everything

μž‘μ„±μž: inside Nikita's Mind

λ°œν–‰μΌ: 2025λ…„ 7μ›” 21일

ν”Œλž«νΌ: Medium

λ²ˆμ—­: λ…Έμ…˜ κ²Œμ‹œμš©μœΌλ‘œ νŽΈμ§‘λ¨