๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
BackEnd๐ŸŒฑ/Kafka

@KafkaListener์˜ concurrency ์„ค์ •(feat.๋ฉ”์‹œ์ง€ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ)

by dkswnkk 2025. 3. 2.

๊ฐœ์š”

@KafkaListener์˜ ์†์„ฑ ์ค‘์—๋Š” concurrency ์„ค์ •์ด ์กด์žฌํ•œ๋‹ค. ์ด ์„ค์ •์€ Kafka ๋ฆฌ์Šค๋„ˆ์˜ ๋ณ‘๋ ฌ ์†Œ๋น„(Parallel Consumption)๋ฅผ ์„ค์ •ํ•˜๋Š” ์˜ต์…˜์œผ๋กœ, ํ•˜๋‚˜์˜ Kafka ํ† ํ”ฝ์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์†Œ๋น„์ž ์Šค๋ ˆ๋“œ๋ฅผ ํ†ตํ•ด ๋ณ‘๋ ฌ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋‹จ์ˆœํžˆ concurrency ๊ฐ’์„ ๋†’์ธ๋‹ค๊ณ  ํ•ด์„œ ๋ฐ˜๋“œ์‹œ ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ํŠน์ • ์ƒํ™ฉ์—์„œ๋Š” ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๊ฐ€ ํšจ๊ณผ์ ์ด์ง€๋งŒ, ์ ์ ˆํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์˜คํžˆ๋ ค ๋ถˆํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค ๋‚ญ๋น„๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋ฒˆ ๊ฒŒ์‹œ๊ธ€์—์„œ๋Š” concurrency์˜ ๊ฐœ๋…๊ณผ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ํšจ๊ณผ์ ์œผ๋กœ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ๋ฅผ ์‚ดํŽด๋ณด๊ณ ์ž ํ•œ๋‹ค.

 

 

Concurrency ๊ธฐ๋ณธ ๊ฐœ๋…

Kafka๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ปจ์Šˆ๋จธ ๊ทธ๋ฃน(Consumer Group) ๋‹จ์œ„๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ํ• ๋‹นํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋™์ผํ•œ ์ปจ์Šˆ๋จธ ๊ทธ๋ฃน ๋‚ด์—์„œ๋Š” ๊ฐ ํŒŒํ‹ฐ์…˜์ด ํ•˜๋‚˜์˜ ์ปจ์Šˆ๋จธ์—๊ฒŒ๋งŒ ํ• ๋‹น๋˜๋ฉฐ, ์—ฌ๋Ÿฌ ์ปจ์Šˆ๋จธ๊ฐ€ ๋™์ผํ•œ ํŒŒํ‹ฐ์…˜์„ ์ค‘๋ณต์œผ๋กœ ์†Œ๋น„ํ•  ์ˆ˜ ์—†๋‹ค.

๊ทธ๋ฆผ 1

์œ„์™€ ๊ฐ™์ด Consumer-1๊ณผ Consumer-2๊ฐ€ ์กด์žฌํ•˜๊ณ , Topic-01์™€ Topic-02์˜ ์—ฌ๋Ÿฌ ํŒŒํ‹ฐ์…˜์ด ๊ฐ๊ฐ ์ด ๋‘ ์ปจ์Šˆ๋จธ์—๊ฒŒ ํ• ๋‹น๋˜๋Š” ๊ตฌ์กฐ๋ฅผ ์‚ดํŽด๋ณด์ž. ๊ธฐ๋ณธ ์„ค์ •์—์„œ๋Š” ๊ฐ ์ปจ์Šˆ๋จธ๊ฐ€ ํ• ๋‹น๋ฐ›์€ ํŒŒํ‹ฐ์…˜์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ํ•˜๋‚˜์”ฉ ์ˆœ์ฐจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ, Consumer-1์ด Topic-01์˜ Partition-1์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•œ ํ›„ Topic-02์˜ Partition-1์˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜ ๊ทธ ๋ฐ˜๋Œ€ ์ˆœ์„œ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ์ด๋Š” Kafka ์ปจ์Šˆ๋จธ ์Šค๋ ˆ๋“œ์˜ ๊ธฐ๋ณธ ์„ค์ •(concurrency)์ด 1๊ฐœ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. (์ฐธ๊ณ ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์ˆœ์„œ๋Š” ์ˆœ์ฐจ์ ์ด์ง€๋งŒ, poll()์„ ํ˜ธ์ถœํ•  ๋•Œ๋Š” ์—ฌ๋Ÿฌ ํŒŒํ‹ฐ์…˜์—์„œ ํ•œ๊บผ๋ฒˆ์— ๋ฉ”์‹œ์ง€๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์€ ๋™์‹œ์— ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์ฒ˜๋ฆฌ ์ž์ฒด๋Š” ํ•˜๋‚˜์”ฉ ์ด๋ฃจ์–ด์ง„๋‹ค.)

๊ทธ๋ฆผ 2

์ด ๊ฒฝ์šฐ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋‹ค. Consumer-1์ด Topic-01์˜ ์„ธ ๊ฐœ์˜ ํŒŒํ‹ฐ์…˜์„ ํ• ๋‹น๋ฐ›์œผ๋ฉด, ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ ํŒŒํ‹ฐ์…˜๋“ค์˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์ž˜ ์ƒ๊ฐํ•ด ๋ณด์ž. ๊ทธ๋ฆผ 1๋ฒˆ์—์„œ Topic-01์™€ Topic-02๋Š” ์„œ๋กœ ๋…๋ฆฝ์ ์ธ ๊ฐœ๋…์ด๋ฏ€๋กœ ๋ฐ˜๋“œ์‹œ ์ˆœ์ฐจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ํ•„์š”๋Š” ์—†์„ ๊ฒƒ์ด๋‹ค. ๋˜ํ•œ ๊ทธ๋ฆผ 2์—์„œ๋„ ๋ฉ”์‹œ์ง€ ์ฒ˜๋ฆฌ ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•˜์ง€ ์•Š๋‹ค๋ฉด ์—ฌ๋Ÿฌ ํŒŒํ‹ฐ์…˜์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ๋” ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

์ด๋ฅผ ์œ„ํ•ด @KafkaListener์—๋Š” concurrency ์†์„ฑ์„ ์ œ๊ณตํ•˜๋Š”๋ฐ, ์ด ๊ฐ’์„ ์„ค์ •ํ•˜๋ฉด ์ปจ์Šˆ๋จธ ์Šค๋ ˆ๋“œ ๊ฐœ์ˆ˜๋ฅผ ์†์‰ฝ๊ฒŒ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. concurrency ๊ฐ’์„ ์ง€์ •ํ•˜๋ฉด ๋‚ด๋ถ€์ ์œผ๋กœ ์—ฌ๋Ÿฌ ๊ฐœ์˜ Kafka ์ปจ์Šˆ๋จธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ƒ์„ฑ๋˜๋ฉฐ, ํ•˜๋‚˜์˜ ๋ฆฌ์Šค๋„ˆ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํŒŒํ‹ฐ์…˜์„ ๋™์‹œ์— ์†Œ๋น„ํ•  ์ˆ˜ ์žˆ์–ด ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.

@KafkaListener(topics = "my-topic", concurrency = "2")
public void listen(String message) {
    System.out.println("Received: " + message);
}

์œ„์™€ ๊ฐ™์ด concurrency ๊ฐ’์„ 2๋กœ ์„ค์ •ํ•˜๋ฉด ํ•˜๋‚˜์˜ ๋ฆฌ์Šค๋„ˆ์—์„œ ๋‘ ๊ฐœ์˜ ์ปจ์Šˆ๋จธ ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰๋˜์–ด ๋ณ‘๋ ฌ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

 

 

concurrency ๊ฐœ์ˆ˜๊ฐ€ ๋†’์œผ๋ฉด ๋ฌด์กฐ๊ฑด ์ข‹์„๊นŒ?

concurrency ๊ฐ’์„ ๋†’์ด๋ฉด ๋” ๋งŽ์€ Kafka ์ปจ์Šˆ๋จธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ƒ์„ฑ๋˜๋ฉฐ, ์—ฌ๋Ÿฌ ํŒŒํ‹ฐ์…˜์„ ๋ฉ”์‹œ์ง€๋ฅผ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ์ฒ˜๋ฆฌ ์†๋„๊ฐ€ ํ–ฅ์ƒ๋œ๋‹ค. ํ•˜์ง€๋งŒ ๋ฌด์กฐ๊ฑด ๋†’์€ ๊ฐ’์„ ์„ค์ •ํ•œ๋‹ค๊ณ  ํ•ด์„œ ํ•ญ์ƒ ์ตœ์ ์˜ ์„ฑ๋Šฅ์„ ๋ณด์žฅํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ์•ž์„œ ์„ค๋ช…ํ•œ ๊ฐœ๋…์—์„œ ๋ˆˆ์น˜์ฑ˜์„ ์ˆ˜๋„ ์žˆ๊ฒ ์ง€๋งŒ, concurrency ๊ฐ’์„ ์„ค์ •ํ•  ๋•Œ๋Š” ๋ฐ˜๋“œ์‹œ ํ• ๋‹น๋ฐ›์€ ํŒŒํ‹ฐ์…˜์˜ ๊ฐœ์ˆ˜๋ฅผ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค. Kafka์˜ ๋ฉ”์‹œ์ง€ ์†Œ๋น„๋Š” ํŒŒํ‹ฐ์…˜ ๋‹จ์œ„๋กœ ์ด๋ฃจ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— concurrency ๊ฐ’์ด ํŒŒํ‹ฐ์…˜ ๊ฐœ์ˆ˜๋ฅผ ์ดˆ๊ณผํ•˜๋ฉด ์„ฑ๋Šฅ ํ–ฅ์ƒ์—๋Š” ๋„์›€์ด ๋˜์ง€ ์•Š๋Š”๋‹ค.

์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์ง์ ‘ ์‚ดํŽด๋ณด์ž.

1. ํ† ํ”ฝ์ด 1๊ฐœ์ผ ๊ฒฝ์šฐ(๋ฉ”์‹œ์ง€ 3๊ฐœ)

  • ํŒŒํ‹ฐ์…˜ 1๊ฐœ, concurrency 1
  • ํŒŒํ‹ฐ์…˜ 1๊ฐœ, concurrency 2
  • ํŒŒํ‹ฐ์…˜ 3๊ฐœ, concurrency 6

1. ํ† ํ”ฝ 1๊ฐœ(ํŒŒํ‹ฐ์…˜ 1๊ฐœ, concurrency 1)

Received message in group 'test': Test Message 0 | Processed by: Thread-1
Received message in group 'test': Test Message 1 | Processed by: Thread-1
Received message in group 'test': Test Message 2 | Processed by: Thread-1

Kafka ํ† ํ”ฝ์— ํ•˜๋‚˜์˜ ํŒŒํ‹ฐ์…˜๋งŒ ์กด์žฌํ•˜๋Š” ์ƒํƒœ์—์„œ concurrency ๊ฐ’์„ 1๋กœ ์„ค์ •ํ•œ ๊ฒฝ์šฐ, ๋‹จ์ผ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ชจ๋“  ๋ฉ”์‹œ์ง€๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋œ๋‹ค. ์‹ค์ œ๋กœ 3๊ฐœ์˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐœํ–‰ํ•œ ํ›„ ๋กœ๊ทธ๋ฅผ ํ™•์ธํ•ด ๋ณด๋ฉด, ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ชจ๋“  ๋ฉ”์‹œ์ง€๋ฅผ ๋‹ด๋‹นํ•˜๊ณ  ์žˆ๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

2. ํ† ํ”ฝ 1๊ฐœ(ํŒŒํ‹ฐ์…˜ 1๊ฐœ, concurrency 2)

Received message in group 'test': Test Message 0 | Processed by: Thread-1
Received message in group 'test': Test Message 1 | Processed by: Thread-1
Received message in group 'test': Test Message 2 | Processed by: Thread-1

์ด์ œ concurrency ๊ฐ’์„ 2๋กœ ์ฆ๊ฐ€์‹œ์ผœ ๋ณด์•˜๋‹ค. ์ง๊ด€์ ์œผ๋กœ ์ƒ๊ฐํ•˜๋ฉด ๋‘ ๊ฐœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์ƒ์„ฑ๋˜์–ด, ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ด ์†Œ์š” ์‹œ๊ฐ„์ด ๋‹จ์ถ•๋  ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค. ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ์—ฌ์ „ํžˆ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ๋ฉ”์‹œ์ง€๋ฅผ ์†Œ๋น„ํ•œ๋‹ค. ์ด์œ ๋Š” ๋™์ผํ•œ ํŒŒํ‹ฐ์…˜์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ํ•ด๋‹น ํŒŒํ‹ฐ์…˜์„ ๋…์ ์ ์œผ๋กœ ๊ฐ€์ ธ๊ฐ€๊ณ , ๋‚˜๋จธ์ง€ ์Šค๋ ˆ๋“œ๋Š” ๋Œ€๊ธฐ ์ƒํƒœ๊ฐ€ ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.(์ด๊ฑด Kafka ๋™์ž‘์˜ ๊ทผ๋ณธ๊ณผ ๊ด€๋ จ๋œ ๊ฒƒ์œผ๋กœ ๋™์ผํ•œ ํŒŒํ‹ฐ์…˜ ๋‚ด์—์„œ๋Š” ๋ฉ”์‹œ์ง€์˜ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.)

๊ฒฐ๊ณผ์ ์œผ๋กœ concurrency=2๋ผ๊ณ  ํ•ด๋„ concurrency=1๊ณผ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ๋ฉ”์‹œ์ง€๊ฐ€ ์ฒ˜๋ฆฌ๋˜์—ˆ๋‹ค.

3. ํ† ํ”ฝ 1๊ฐœ(ํŒŒํ‹ฐ์…˜ 3๊ฐœ, concurrency 6)

Received message in group 'test': Test Message 0 | Processed by: Thread-1
Received message in group 'test': Test Message 1 | Processed by: Thread-2
Received message in group 'test': Test Message 2 | Processed by: Thread-3

์ด๋ฒˆ์—๋Š” ํŒŒํ‹ฐ์…˜์„ 3๊ฐœ๋กœ ๋Š˜๋ฆฌ๊ณ , concurrency ๊ฐ’์„ 6์œผ๋กœ ์„ค์ •ํ•ด ๋ณด์•˜๋‹ค. Kafka๋Š” ํŒŒํ‹ฐ์…˜ ๋‹จ์œ„๋กœ ์ปจ์Šˆ๋จธ๋ฅผ ํ• ๋‹นํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด ๊ฒฝ์šฐ ์„œ๋กœ ๋‹ค๋ฅธ ํŒŒํ‹ฐ์…˜์ด๊ธฐ์— ์ตœ๋Œ€ 3๊ฐœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ๋ฉ”์‹œ์ง€๋ฅผ ์†Œ๋น„ํ•  ์ˆ˜ ์žˆ๋‹ค. ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด 3๊ฐœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ๊ฐ ๋‹ค๋ฅธ ํŒŒํ‹ฐ์…˜์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌํ•˜๊ณ  ์žˆ์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ concurrency ๊ฐ’์„ 6์œผ๋กœ ์„ค์ •ํ–ˆ์Œ์—๋„ 3๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋งŒ ์‚ฌ์šฉ๋˜์—ˆ๋Š”๋ฐ, Kafka์—์„œ ํ™œ์„ฑํ™”๋˜๋Š” ์ปจ์Šˆ๋จธ ์Šค๋ ˆ๋“œ ๊ฐœ์ˆ˜๋Š” ํ• ๋‹น๋œ ํŒŒํ‹ฐ์…˜ ๊ฐœ์ˆ˜๋ฅผ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

 

ํŠน์ • ํ† ํ”ฝ-ํŒŒํ‹ฐ์…˜์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ–ˆ์„ ๋•Œ vs ์ง€์ •ํ•˜์ง€ ์•Š์•˜์„ ๋•Œ

์—ฌ๊ธฐ์„œ ์กฐ๊ธˆ ๋” ๋”ฅ ๋‹ค์ด๋ธŒ๋ฅผ ํ•ด๋ณด๋ฉด ์‚ฌ์‹ค ์ •ํ™•ํžˆ๋Š” ํ† ํ”ฝ-ํŒŒํ‹ฐ์…˜์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ–ˆ๋Š”์ง€ ์—ฌ๋ถ€์— ๋”ฐ๋ผ concurrency ์Šค๋ ˆ๋“œ์˜ ์ƒ์„ฑ ๋ฐฉ์‹์€ ๋‹ฌ๋ผ์ง„๋‹ค.

1. ํŠน์ • ํ† ํ”ฝ-ํŒŒํ‹ฐ์…˜์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•œ ๊ฒฝ์šฐ

ํŠน์ • ํ† ํ”ฝ-ํŒŒํ‹ฐ์…˜์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•œ ๊ฒฝ์šฐ

์œ„๋ฅผ ๋ณด๋ฉด @KafkaListener์—์„œ ๋ช…์‹œ์ ์œผ๋กœ ํ† ํ”ฝ-ํŒŒํ‹ฐ์…˜ ๊ฐœ์ˆ˜๋ฅผ ์ง€์ •ํ•ด ์คฌ๋‹ค. ์ด๋Ÿด ๊ฒฝ์šฐ concurrency๋ฅผ 6์œผ๋กœ ์„ค์ •ํ•˜๋”๋ผ๋„ Kafka๋Š” ์• ์ดˆ์— ์ง€์ •๋œ ํŒŒํ‹ฐ์…˜ ๊ฐœ์ˆ˜๊นŒ์ง€๋งŒ ์ƒ์„ฑํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์‹ค์ œ๋กœ ์‹คํ–‰๋˜๋Š” ์ปจ์Šˆ๋จธ ์Šค๋ ˆ๋“œ๋Š” 3๊ฐœ์ด๋ฉฐ ๋ถˆํ•„์š”ํ•œ ์ถ”๊ฐ€ ์Šค๋ ˆ๋“œ๋Š” ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š”๋‹ค.

2. ํ† ํ”ฝ-ํŒŒํ‹ฐ์…˜์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜์ง€ ์•Š์•˜์„ ๊ฒฝ์šฐ

ํ† ํ”ฝ-ํŒŒํ‹ฐ์…˜์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜์ง€ ์•Š์•˜์„ ๊ฒฝ์šฐ

๋ฐ˜๋ฉด ํŠน์ • ํŒŒํ‹ฐ์…˜์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ concurrency=6์œผ๋กœ ์„ค์ •ํ•˜๋ฉด Spring Kafka๋Š” 6๊ฐœ์˜ ์ปจ์Šˆ๋จธ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Kafka๋Š” ํŒŒํ‹ฐ์…˜ ๊ฐœ์ˆ˜์— ๋งž์ถฐ ์ปจ์Šˆ๋จธ๋ฅผ ํ• ๋‹นํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์ œ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์†Œ๋น„ํ•˜๋Š” ์Šค๋ ˆ๋“œ๋Š” 3๊ฐœ๋ฟ์ด๋ฉฐ, ๋‚˜๋จธ์ง€ 3๊ฐœ๋Š” ์œ ํ›„์ƒํƒœ๋กœ ๋‚จ๊ฒŒ ๋œ๋‹ค. ์ฆ‰ 6๊ฐœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์ƒ์„ฑ๋˜์ง€๋งŒ ์‹ค์ œ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ์†Œ๋น„ํ•˜๋Š” ์Šค๋ ˆ๋“œ๋Š” 3๊ฐœ๋ฟ์ด๋ผ๋Š” ๋ง์ด๋‹ค.

์‹ค์ œ ๋‚ด๋ถ€ ๊ตฌํ˜„ ์ฝ”๋“œ๋Š” ์•„๋ž˜์˜ ConcurrentMessageListenerContainer.java#L243๋ฅผ ๋ณด๋ฉด ๋œ๋‹ค.

https://github.com/spring-projects/spring-kafka/blob/main/spring-kafka/src/main/java/org/springframework/kafka/listener/ConcurrentMessageListenerContainer.java#L243

๋ญ ์ผ๋ฐ˜์ ์œผ๋กœ ์‹ค์ œ ํ˜„์—…์—์„œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ํŒŒํ‹ฐ์…˜ ๊ฐœ์ˆ˜๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์•„๋งˆ ์ž˜ ์—†์„ ๊ฒƒ์ด๋‹ค. ๋ณดํ†ต ํ† ํ”ฝ๋งŒ ์ง€์ •ํ•˜๊ณ  ํŠน์ • ํŒŒํ‹ฐ์…˜๊นŒ์ง€๋Š” ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋‹ˆ๊นŒ.. ๊ทธ๋ƒฅ ์•Œ์•„๋‘๋ฉด ์ข‹์„ ๋‚ด์šฉ์ด๋‹ค.

 

 

์ •๋ฆฌ

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” Kafka์˜ @KafkaListener์—์„œ concurrency ๊ฐ’์„ ํ™œ์šฉํ•œ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์„ ์‚ดํŽด๋ณด์•˜๋‹ค. concurrency๋Š” Kafka์—์„œ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ์œ ์šฉํ•œ ์„ค์ •์ด์ง€๋งŒ, ํŒŒํ‹ฐ์…˜ ๊ฐœ์ˆ˜๋ฅผ ์ดˆ๊ณผํ•˜๋Š” concurrency ๊ฐ’์€ ์˜๋ฏธ๊ฐ€ ์—†์œผ๋ฉฐ, ์„ค์ • ๋ฐฉ์‹์— ๋”ฐ๋ผ ์ƒ์„ฑ๋˜๋Š” ์ปจ์Šˆ๋จธ ์Šค๋ ˆ๋“œ ๊ฐœ์ˆ˜๊ฐ€ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์Œ์„ ํ™•์ธํ–ˆ๋‹ค.

ํŠนํžˆ ํŠน์ • ํŒŒํ‹ฐ์…˜์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•œ ๊ฒฝ์šฐ์—๋Š” Kafka๊ฐ€ ํ•ด๋‹น ํŒŒํ‹ฐ์…˜ ๊ฐœ์ˆ˜๊นŒ์ง€๋งŒ ์ปจ์Šˆ๋จธ๋ฅผ ์ƒ์„ฑํ•˜์ง€๋งŒ, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด concurrency ๊ฐ’๋งŒํผ ์ปจ์Šˆ๋จธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ƒ์„ฑ๋˜๋‚˜ ์ผ๋ถ€๋Š” ์œ ํœด ์ƒํƒœ๋กœ ๋‚จ์•˜๋‹ค.

๊ฒฐ๊ตญ ํšจ์œจ์ ์ธ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด์„œ๋Š” concurrency ๊ฐ’์„ ํŒŒํ‹ฐ์…˜ ๊ฐœ์ˆ˜์™€ ๋งž์ถ”๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์‹ค๋ฌด์— ์ ์šฉํ•  ๋•Œ๋Š” ๊ณ ๋ คํ•ด์•ผ ํ•  ์ ์ด ์žˆ๋‹ค. ๋ฐ”๋กœ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ์ด ์ผ์–ด๋‚  ๋•Œ์ธ๋ฐ ๋ฆฌ๋ฐธ๋Ÿฐ์‹ฑ์ด ๋ฐœ์ƒํ•˜๋ฉด ํŒŒํ‹ฐ์…˜ ์žฌํ• ๋‹น์ด ์ผ์–ด๋‚˜๊ณ  ์ด๋•Œ ๊ฐ ์ปจ์Šˆ๋จธ๊ฐ€ ํ•ญ์ƒ ๋™์ผํ•œ ๊ฐœ์ˆ˜์˜ ํŒŒํ‹ฐ์…˜์„ ํ• ๋‹น๋ฐ›๋Š”๋‹ค๋Š” ๋ณด์žฅ์ด ์—†์œผ๋ฏ€๋กœ, ์œ ํœด ์ƒํƒœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ ์‹ค๋ฌด์— ์ ์šฉํ•œ๋‹ค๋ฉด ์šด์˜ ํ™˜๊ฒฝ๊ณผ ์‹œ์Šคํ…œ์˜ ํŠน์„ฑ์— ๋งž์ถฐ ์œ ์—ฐํ•˜๊ฒŒ ์กฐ์ •ํ•ด์•ผ ํ•จ์„ ์ธ์ง€ํ•˜์ž.

๋Œ“๊ธ€