λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
  • μž₯원읡 κΈ°μˆ λΈ”λ‘œκ·Έ
πŸ“š μ‹œλ¦¬μ¦ˆ/- ν•™μŠ΅ ν…ŒμŠ€νŠΈλ‘œ λ°°μ›Œλ³΄λŠ” kafka

[ν•™μŠ΅ ν…ŒμŠ€νŠΈλ‘œ λ°°μ›Œλ³΄λŠ” kafka] 3. μΉ΄ν”„μΉ΄ ν•™μŠ΅ ν…ŒμŠ€νŠΈ μ€€λΉ„ν•˜κΈ°

by Wonit 2023. 9. 7.

ν•΄λ‹Ή μ‹œλ¦¬μ¦ˆμ—μ„œ μ œκ³΅ν•˜λŠ” λͺ¨λ“  μ†ŒμŠ€μ½”λ“œλŠ” github repository μ—μ„œ μ œκ³΅λ©λ‹ˆλ‹€. μžμ„Έν•œ μ½”λ“œμ™€ ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λŠ” github repository μ—μ„œ ν™•μΈν•΄μ£Όμ„Έμš”.

 

GitHub - my-research/kafka: apache kafka docs & practical usages(with spring) that i composed

apache kafka docs & practical usages(with spring) that i composed - GitHub - my-research/kafka: apache kafka docs & practical usages(with spring) that i composed

github.com

이번 [ν•™μŠ΅ ν…ŒμŠ€νŠΈλ‘œ λ°°μ›Œλ³΄λŠ” kafka] μ‹œλ¦¬μ¦ˆλŠ” μ•„λž˜ μˆœμ„œλŒ€λ‘œ 챕터가 κ΅¬μ„±λ˜κ³ , μ‹œλ¦¬μ¦ˆ μ™Έλ‘œ kafka κ΄€λ ¨ν•˜μ—¬ λ”μš± λ§Žμ€ ν•™μŠ΅ μ •λ³΄λŠ” kafka 심화 μ„Έμ…˜ μ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

μ‹œλ¦¬μ¦ˆ λͺ©μ°¨

  1. μ‹œλ¦¬μ¦ˆλ₯Ό μ‹œμž‘ν•˜λ©°
  2. kafka λΉ λ₯΄κ²Œ 훑어보고 μ•„λŠ”μ²΄ν•˜κΈ°
  3. kafka 컨셉과 μš©μ–΄ 정리
  4. ν•™μŠ΅ν…ŒμŠ€νŠΈ μ€€λΉ„ν•˜κΈ° <-- ν˜„μž¬ κΈ€
  5. ν•™μŠ΅ ν…ŒμŠ€νŠΈλ‘œ kafka producer μ•Œμ•„λ³΄κΈ°
  6. ν•™μŠ΅ ν…ŒμŠ€νŠΈλ‘œ kafka consumer μ•Œμ•„λ³΄κΈ°
  7. ν•™μŠ΅ ν…ŒμŠ€νŠΈλ‘œ partitioning μ•Œμ•„λ³΄κΈ°
  8. ν•™μŠ΅ ν…ŒμŠ€νŠΈλ‘œ consumer group κ³Ό rebalancing μ•Œμ•„λ³΄κΈ°

ν•™μŠ΅μ˜ 단계별 μˆœμ„œλ‘œ λͺ©μ°¨κ°€ κ΅¬μ„±λ˜μ–΄μžˆμœΌλ―€λ‘œ μ„ ν–‰λ˜μ–΄μ•Ό ν•˜λŠ” 챕터가 μ‘΄μž¬ν•©λ‹ˆλ‹€


 

이번 μ±•ν„°μ—μ„œλŠ” μ•žμœΌλ‘œ ν•™μŠ΅ν•  μΉ΄ν”„μΉ΄μ˜ κ°œλ…μ„ μ½”λ“œλ‘œ μ΄ν•΄ν•˜κΈ° μœ„ν•΄μ„œ μ‚¬μš©ν•  방식인 ν•™μŠ΅ ν…ŒμŠ€νŠΈμ— λŒ€ν•΄ μ•Œμ•„λ³Ό 것이닀.

 

μš°μ„  ν•™μŠ΅ ν…ŒμŠ€νŠΈμ— λŒ€ν•΄μ„œ 잘 λͺ¨λ₯Ό 수 μžˆμœΌλ‹ˆ ν•™μŠ΅ν…ŒμŠ€νŠΈκ°€ 무엇인지, 그리고 μ–΄λ–€ μž₯점이 μžˆμ–΄μ„œ 이번 μ‹œλ¦¬μ¦ˆμ—μ„œ μ±„νƒν•˜μ˜€λŠ”μ§€ μ•Œμ•„λ³΄λ„λ‘ ν•˜μž

 

ν•™μŠ΅ ν…ŒμŠ€νŠΈλž€?

 

ν•™μŠ΅ ν…ŒμŠ€νŠΈλŠ” μ–΄λ–€ λΌμ΄λΈŒλŸ¬λ¦¬λ‚˜ ν”„λ ˆμž„μ›Œν¬λ₯Ό ν•™μŠ΅ν•˜κ³  읡히기 μœ„ν•΄μ„œ μž‘μ„±ν•˜λŠ” ν…ŒμŠ€νŠΈμ΄λ‹€.

 

이 κ°œλ…μ€ martin fowler κ°€ "Refactoring: Improving the Design of Existing Code" μ±…μ—μ„œ "ν•™μŠ΅ ν…ŒμŠ€νŠΈ" λΌλŠ” μš©μ–΄λ₯Ό 처음 μ‚¬μš©ν–ˆλŠ”λ°, 이후 μš°λ¦¬λ‚˜λΌμ—μ„œλŠ” ν† λΉ„μ˜ μŠ€ν”„λ§μ—μ„œ μ–ΈκΈ‰λ˜μ–΄ λ§Žμ€ 관심을 λŒμ—ˆλ˜ κ°œλ…μ΄λ‹€

 

μ‹€μ œ ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό λ§Œλ“€κ³  μ‹€ν–‰ν•˜λ©΄μ„œ κΈ°μˆ μ„ 읡히고 λ™μž‘μ„ μ‹€ν—˜ν•˜λŠ” λͺ¨λ“  과정을 ν¬ν•¨ν•˜λŠ”λ°, μ΄λŸ¬ν•œ 방법듀이 μƒˆλ‘œμš΄ κΈ°μˆ μ„ μŠ΅λ“ν•˜κ³  μ΅νžˆλŠ”λ°μ— 개인적으둜 κ°€μž₯ νš¨κ³Όκ°€ μ’‹μ•˜λ‹€.

 

ν•™μŠ΅ ν…ŒμŠ€νŠΈλŠ” 일반적으둜 λ‹€μŒκ³Ό 같은 μˆœμ„œλ₯Ό κ±°μΉœλ‹€

 

  1. ν…ŒμŠ€νŠΈ λŒ€μƒ μ„ μ •
  2. ν…ŒμŠ€νŠΈ μ½”λ“œ μž‘μ„±
  3. ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ μ‹€ν–‰ (μ‹€νŒ¨)
  4. μ‹€νŒ¨ μ›μΈλ§Œ λΉ λ₯΄κ²Œ ν•΄κ²° (μ„±κ³΅μ‹œν‚€κΈ°)
  5. 쑰금의 variation 을 μΆ”κ°€ν•˜μ—¬ μ‹€νŒ¨ μΌ€μ΄μŠ€ λ§Œλ“€κΈ°
  6. variation μΌ€μ΄μŠ€ μ„±κ³΅μ‹œν‚€κΈ°

 

μœ„μ˜ 과정을 λ°˜λ³΅ν•˜λ©° μ μ§„μ μœΌλ‘œ κ°œλ…κ³Ό 지식을 ν™•μž₯ν•˜λŠ” 것을 λͺ©ν‘œλ‘œ ν•œλ‹€.

 

예λ₯Όλ“€μ–΄ μ–΄λ–€ λ―Έμ§€μ˜ Calculator λΌλŠ” ν΄λž˜μŠ€κ°€ μžˆλ‹€κ³  κ°€μ •ν•΄λ³΄μž.

 

그리고 이 클래슀의 λ‚΄λΆ€ κ΅¬ν˜„μ€ λ¬Έμ„œλ„ μ—†κ³  λ―ΈμΉœλ“―μ΄ λ³΅μž‘ν•΄μ„œ 눈으둜 둜직 파읡이 μ–΄λ ΅λ‹€κ³  κ°€μ •ν•˜μž.

 

ν•™μŠ΅ ν…ŒμŠ€νŠΈμ˜ 접근법은 μš°μ„  ν•΄λ³΄λŠ” 것이닀.

 

λŒ€μΆ© μ–΄λ– ν•  κ²ƒμ΄λΌλŠ” μ˜ˆμΈ‘λ§Œμ„ 가지고 (μΌλ°˜μ μœΌλ‘œλŠ” λ¬Έμ„œλ‚˜ 주석, μ‹œκ·Έλ‹ˆμ²˜λ₯Ό 보면 μ˜ˆμΈ‘μ„ ν•˜λŠ” 정확도가 더 높을 것이닀) 이것저것 ν•΄λ³΄λŠ” 것이닀

 

Calculator λΌλŠ” 클래슀의 int calc(int a, int b) λΌλŠ” μ‹œκ·Έλ‹ˆμ²˜κ°€ μžˆλŠ”λ°, λŒ€μΆ© 연산을 ν•˜κΈ΄ ν•˜λŠ”λ°, λ§μ…ˆμΈμ§€ κ³±μ…ˆμΈμ§€ λͺ¨λ₯΄κ² λ‹€λ©΄?

 

κ·Έλƒ₯ 일단 ν…ŒμŠ€νŠΈλ₯Ό λ§Œλ“œλŠ” 것이닀.

 

그리고 λ§μ…ˆμ΄κ² κ±°λ‹ˆ ν•˜κ³  μ‹€ν–‰μ‹œμΌœλ³Έλ‹€

 

class UsageTest {

  Calculator sut = new Calculator();

  @Test
  void test() {
    int actual = sut.calc(10, 20); // λ§μ…ˆμΌ κ²ƒμœΌλ‘œ μΆ”μΈ‘ & μ‹€ν–‰

    // AssertionFailedException λ°œμƒ
    assertThat(actual).isEqualTo(10 + 20)
  }
}

 

μ‹€νŒ¨ν–ˆλ‹€. 그럼 μ™œ μ‹€νŒ¨ν–ˆλŠ”μ§€ 원인을 νŒŒμ•…ν•΄λ³΄κ³  λ‹€λ₯Έ 방식을 μ‹œλ„ν•΄λ³Έλ‹€.

 

class UsageTest {

  Calculator sut = new Calculator();

  @Test
  void test() {
    int actual = sut.calc(10, 20); // μ•žμ„œ μ‹€νŒ¨ν–ˆμœΌλ‹ˆκΉŒ λΊ„μ…ˆμ΄λΌκ³  μΆ”μΈ‘ & μ‹€ν–‰

    assertThat(actual).isEqualTo(10 - 20) // 성곡
  }
}

 

이 ν…ŒμŠ€νŠΈλ₯Ό ν†΅ν•΄μ„œ int calc(int a, int b) λŠ” λΊ„μ…ˆ 연산을 μˆ˜ν–‰ν•˜λŠ” λ©”μ„œλ“œλΌλŠ” 것을 μ•Œκ²Œ λ˜μ—ˆλ‹€.

 

λ‚΄κ°€ μƒκ°ν•˜λŠ” ν•™μŠ΅ ν…ŒμŠ€νŠΈμ˜ μž₯점

 

개인적으둜 ν•™μŠ΅ν…ŒμŠ€νŠΈλŠ” 이런 μž₯점이 μžˆλŠ”κ²ƒ κ°™λ‹€.

 

  1. μ›ν•˜λŠ” κΈ°λŠ₯만 λΉ λ₯΄κ²Œ 읡힐 수 μžˆλ‹€.
  2. 점진적인 μ‹€ν—˜μ΄ κ°€λŠ₯ν•˜λ‹€
  3. 거짓말 ν•˜μ§€ μ•ŠλŠ” λ¬Έμ„œλ₯Ό 직접 λ§Œλ“€μ–΄λ‚˜κ°„λ‹€(κ³΅μœ κ°€ κ°€λŠ₯ν•˜λ‹€)

 

μ›ν•˜λŠ” κΈ°λŠ₯만 λΉ λ₯΄κ²Œ 읡힐 수 μžˆλ‹€.

 

μ–΄λ–€ 라이브러리의 νŠΉμ • κΈ°λŠ₯λ§Œμ„ μ›ν• λ•Œ 맀우 μœ μš©ν•˜λ‹€.

 

κ³„μ†ν•΄μ„œ λ˜λŠ” λ°©μ‹λ§Œ μ°Ύκ²Œλ˜λ‹ˆ λͺ¨λ“ κ²ƒμ„ μ•Œμ§€ μ•Šμ•„λ„ λœλ‹€.

 

생산성 μΈ‘λ©΄μ—μ„œ 맀우 μœ λ¦¬ν•œ νŠΉμ§•μ΄ μžˆλ‹€.

 

점진적인 μ‹€ν—˜μ΄ κ°€λŠ₯ν•˜λ‹€

 

ν…ŒμŠ€νŠΈλ₯Ό ν•œλ²ˆ μ‹€ν–‰μ‹œν‚€κ³  λ‚˜λ©΄ μ—¬κΈ°μ„œ μ—¬λŸ¬κ°€μ§€ λ³€ν˜•μ„ μ€€ ν…ŒμŠ€νŠΈκ°€ κ°€λŠ₯ν•˜λ‹€

 

νŒŒλΌλ―Έν„°λ₯Ό 바꿔보고 경계값도 넣어보고 λ“±λ“±.

 

짧은 주기둜 ν…ŒμŠ€νŠΈ ν”Όλ“œλ°±μ„ ν†΅ν•΄μ„œ κΈ°λŠ₯을 μ•Œμ•„κ°€κ³  trouble shooting 을 톡해 더 전문성을 높일 수 μžˆλ‹€

 

거짓말 ν•˜μ§€ μ•ŠλŠ” λ¬Έμ„œλ₯Ό 직접 λ§Œλ“€μ–΄λ‚˜κ°„λ‹€(κ³΅μœ κ°€ κ°€λŠ₯ν•˜λ‹€)

 

ν•™μŠ΅ ν…ŒμŠ€νŠΈλ„ ν…ŒμŠ€νŠΈμ΄λ‹€.

 

ν…ŒμŠ€νŠΈ μ½”λ“œλ₯Ό 잘 μž‘μ„±ν•œλ‹€λ©΄ μ–΄λ””μ„œλ“  항상 κ·Έ κ²°κ³Όκ°€ 참인 regression test κ°€ κ°€λŠ₯ν•˜λ‹€.

 

κ²°κ΅­ λ‚΄κ°€ κ²€μ¦ν•œ κΈ°λŠ₯에 λŒ€ν•΄μ„œ μ–Έμ œλ“  κ±°μ§“μ—†λŠ”, 진싀을 μ œκ³΅ν•˜λŠ” λ¬Έμ„œκ°€ λœλ‹€.

 

그리고 이 λ¬Έμ„œλŠ” μ½”λ“œλ‘œ μž‘μ„±λ˜μ–΄μžˆκΈ° λ•Œλ¬Έμ— μ–Έμ œλ“ μ§€ λͺ¨λ‘μ—κ²Œ κ³΅μœ κ°€ κ°€λŠ₯ν•˜λ‹€

 

이 ν•™μŠ΅ ν…ŒμŠ€νŠΈλ₯Ό μž₯점이 μžˆμ—ˆκΈ°μ— λ‚΄κ°€ μ§€κΈˆ λΈ”λ‘œκ·Έμ˜ μ΄λ ‡κ²Œ μ‹œλ¦¬μ¦ˆ 글을 μ“°κ³  μžˆλ‹€.

 

이번 μ‹œλ¦¬μ¦ˆμ—μ„œ μ‚¬μš©ν•  ν•™μŠ΅ ν…ŒμŠ€νŠΈ μ€€λΉ„ν•˜κΈ°

 

이번 μ‹œλ¦¬μ¦ˆμ˜ 첫번째 λͺ©ν‘œλŠ” spring κ³Ό 상관 없이 단지 apache kafaka λ₯Ό μ‚¬μš©ν•΄λ³΄κ³  λŠκ»΄λ³΄λŠ”κ²ƒ 이닀.

 

그리고 이후에 spring κ³Ό kafka λ₯Ό 잘 μ‚¬μš©ν•˜λŠ” 법에 λŒ€ν•΄μ„œ μ•Œμ•„λ³Ό μ˜ˆμ •μΈλ° μš°μ„  μ›ν™œν•œ ν…ŒμŠ€νŠΈλ₯Ό μœ„ν•΄μ„œ spring 의 도움을 받을 μ˜ˆμ •μ΄λ‹€

 

ν…ŒμŠ€νŠΈλ₯Ό μœ„ν•œ gradle μ˜μ‘΄μ„±

 

사싀 apache kafka λ§Œμ„ μ›ν•œλ‹€λ©΄ ν•„μš”ν•œ μ˜μ‘΄μ„±μ€ 'org.apache.kafka:kafka_2.10' 인데 μš°λ¦¬λŠ” org.springframework.kafka:spring-kafka 을 μ‚¬μš©ν•  것이닀.

 

ν…ŒμŠ€νŠΈλ₯Ό μœ„ν•œ μΉ΄ν”„μΉ΄ ν΄λŸ¬μŠ€ν„°

 

그리고 μΉ΄ν”„μΉ΄λ₯Ό μ‹€ν–‰μ‹œν‚€κΈ° μœ„ν•΄μ„œ, μ •ν™•νžˆλŠ” μΉ΄ν”„μΉ΄ 브둜컀λ₯Ό μ‹€ν–‰μ‹œν‚€κΈ° μœ„ν•΄μ„œλŠ” λ§Žμ€ μ„€μ •λ“€κ³Ό 쀀비물이 ν•„μš”ν•˜λ‹€.

 

μΉ΄ν”„μΉ΄ 브둜컀λ₯Ό μ‹€ν–‰μ‹œν‚€κΈ° μœ„ν•΄μ„œλŠ” ν΄λŸ¬μŠ€ν„°μ— λŒ€ν•œ 관리와 브둜컀 메타데이터 관리λ₯Ό μœ„ν•΄μ„œ ν•¨κ»˜ μ‚¬μš©λ˜λŠ” zookeeper κ°€ ν•„μš”ν•˜λ‹€.

 

ν•˜μ§€λ§Œ 우리의 λͺ©ν‘œλŠ” kafka λ₯Ό μš΄μ˜ν•˜κ³  κ΄€λ¦¬ν•˜λŠ” 것이 μ•„λ‹ˆλ―€λ‘œ μ‹€μ œ μΉ΄ν”„μΉ΄ ν΄λŸ¬μŠ€ν„°λ₯Ό λ„μš°λŠ”λ°μ— 큰 λ…Έλ ₯을 듀이지 μ•Šμ„ μ˜ˆμ •μ΄λ‹€.

 

kafka λ₯Ό μ΄μš©ν•˜λŠ” μ„œλΉ„μŠ€μ—μ„œ λŒ€ν‘œμ μœΌλ‘œ 많이 μ‚¬μš©ν•˜λŠ” ν…ŒμŠ€νŠΈ 방법은 μ•„λ§ˆ 2가지 방법이 일반적일 것이닀.

  1. kafka testcontainers
  2. inmemeory kafka broker

testcontainers μžμ²΄κ°€ 도컀λ₯Ό μ΄μš©ν•œ ν…ŒμŠ€νŠΈμ΄λ‹€ λ³΄λ‹ˆ ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰μ‹œν‚€λŠ”λ°μ— μžˆμ–΄ λ§Žμ€ μ»΄ν“¨νŒ… λ¦¬μ†ŒμŠ€κ°€ ν•„μš”ν•΄μ„œ ν…ŒμŠ€νŠΈμ˜ λΉ λ₯Έ ν”Όλ“œλ°±μ΄ μ–΄λ ΅λ‹€.

 

κ·Έλž˜μ„œ 이번 ν…ŒμŠ€νŠΈμ—μ„œλŠ” inmemory broker λ₯Ό μ΄μš©ν•  것이닀

 

org.springframework.kafka:spring-kafka-test μ˜μ‘΄μ„±μ—μ„œ @EmbeddedKafka λΌλŠ” μ–΄λ…Έν…Œμ΄μ…˜μ„ ν†΅ν•΄μ„œ 쉽고 λΉ λ₯Έ in memory broker λ₯Ό μ œκ³΅ν•œλ‹€.

 

μ•„λž˜λŠ” 이번 μ‹œλ¦¬μ¦ˆμ—μ„œ ν•„μš”ν•œ μ˜μ‘΄μ„±μ„ ν¬ν•¨ν•œ build.gradle

plugins {
    id 'java'
    id 'org.springframework.boot' version '2.7.14'
    id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}

// ..

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.kafka:spring-kafka'

    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.kafka:spring-kafka-test'
}

tasks.named('test') {
    useJUnitPlatform()
}

EmbeddedKafka ν…ŒμŠ€νŠΈ μ„€μ •

μ‹€μ œ μΉ΄ν”„μΉ΄ λ™μž‘ 과정에 λŒ€ν•΄μ„œλŠ” λ‹€μŒ μ‹œκ°„λΆ€ν„° μžμ„Ένžˆ 확인해보도둝 ν•˜κ³  μš°μ„  μš°λ¦¬κ°€ μ€€λΉ„ν•œ ν…ŒμŠ€νŠΈ ν™˜κ²½μ΄ 잘 λŒμ•„κ°€λŠ”μ§€ ν™•μΈν•΄λ³΄μž

/src/test/java/{pkgDir} κ²½λ‘œμ— ν…ŒμŠ€νŠΈ ν•˜λ‚˜λ₯Ό λ§Œλ“€κ³  λ‹€μŒκ³Ό 같이 μž…λ ₯ν•΄λ³΄μž

@SpringBootTest
@EmbeddedKafka(partitions = 1, brokerProperties = { // μΉ΄ν”„μΉ΄ 브둜컀의 κΈ°λ³Έ 속성 μ„€μ • μ„ μ–Έ
    "listeners=PLAINTEXT://localhost:9092", // bootstrap server
})
public class SampleTest {

  private static final Map<String, Object> props = Map.of(
    "bootstrap.servers", "localhost:9092",
    "key.serializer", "org.apache.kafka.common.serialization.StringSerializer",
    "value.serializer", "org.apache.kafka.common.serialization.StringSerializer"
  );

  KafkaProducer<String, String> producer = new KafkaProducer<>(props);

  @Test
  void sample() {
    // message produce to broker
    ProducerRecord<String, String> record = new ProducerRecord<>("a-topic", "hi~");

    producer.send(record);
  }
}

 

그리고 μ‹€ν–‰μ‹œμΌœλ³΄λ©΄ μ•„λž˜ κ·Έλ¦Όκ³Ό 같이 ν…ŒμŠ€νŠΈκ°€ μ„±κ³΅ν•˜κ²Œ λœλ‹€

 

μ›λž˜ ν•™μŠ΅ν…ŒμŠ€νŠΈλŠ” μ‹€νŒ¨ν•˜λŠ” ν…ŒμŠ€νŠΈλ₯Ό 톡해 μ μ§„μ μœΌλ‘œ κΈ°μˆ μ„ μ΅νžˆλŠ” 방식인데,λΈ”λ‘œκ·Έ κΈ€μ˜ 가독성과 νŠΉμ„±μœΌλ‘œ 인해 μ„±κ³΅ν•˜λŠ” ν…ŒμŠ€νŠΈλ§Œ 보여쀄 μ˜ˆμ •μ΄λ‹€

 

ν…ŒμŠ€νŠΈκ°€ μ„±κ³΅ν•œλ‹€λ©΄ 이제 μ€€λΉ„λŠ” 끝났닀!

 

λ²ˆμ™Έ

 

λ²ˆμ™Έλ‘œ ν•™μŠ΅ ν…ŒμŠ€νŠΈλŠ” λ‚˜λ§Œμ˜ κ°€μ΄λ“œ λ¬Έμ„œκ°€ 될 수 μžˆλ‹€.

 

κ·Έλž˜μ„œ μ΅œλŒ€ν•œ ν•΅μ‹¬λ§Œ 남겨놓고 κΉ”λ”ν•˜κ²Œ μœ μ§€ν•˜λ„λ‘ λ…Έλ ₯ν•˜λŠ” νŽΈμ΄λ‹€.

 

μ‹œλ¦¬μ¦ˆ 쀑간쀑간 ν…ŒμŠ€νŠΈ μ½”λ“œ λ¦¬νŒ©ν† λ§μ„ ν†΅ν•΄μ„œ Helper λ‚˜ Fixture class λ₯Ό 많이 λ§Œλ“€ μ˜ˆμ •μΈλ°, κ·Έλ•Œλ§ˆλ‹€ μ•Œλ €μ£ΌκΈ΄ ν•˜κ² μ§€λ§Œ ν˜Ήμ‹œ λ†“μΉ˜λŠ” λΆ€λΆ„κ³Ό 이해가 가지 μ•ŠλŠ” 뢀뢄이 μžˆμ„ 수 μžˆμœΌλ―€λ‘œ μžμ„Έν•œ μ½”λ“œλŠ” dhslrl321-kafka github repository μ—μ„œ 확인할 수 μžˆλ‹€

 

그런 λ§₯락으둜 보면 μΉ΄ν”„μΉ΄ 브둜컀λ₯Ό μ„€μ •ν•˜λŠ” μ½”λ“œλ₯Ό 쑰금 κΉ”λ”ν•˜κ²Œ λ§Œλ“€κΈ° μœ„ν•΄μ„œ ν…ŒμŠ€νŠΈ μ–΄λ…Έν…Œμ΄μ…˜μ„ λ§Œλ“€μ–΄λ΄€λ‹€

 

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@SpringBootTest
@EmbeddedKafka(partitions = 2, brokerProperties = {
        "listeners=PLAINTEXT://localhost:9092",
        "port=9092",
})
public @interface KafkaTest {
    String testDescriptions() default "";
}

 

그리고 μ‹€μ œ ν…ŒμŠ€νŠΈ μ½”λ“œμ—μ„œλŠ” ν•΄λ‹Ή μ–΄λ…Έν…Œμ΄μ…˜λ§Œ μ‚¬μš©ν•œλ‹€.

 

@KafkaTest
public class SampleTest {
  // ..
}

λŒ“κΈ€