[{"data":1,"prerenderedAt":232},["ShallowReactive",2],{"post-document:\u002Fbackend\u002Fkafka\u002F2026\u002F08\u002F26\u002Fkafka-messaging-system\u002F":3},{"id":4,"title":5,"body":6,"categories":214,"date":217,"description":218,"extension":219,"image":220,"key_concepts":220,"last_modified_at":220,"legacyPath":221,"meta":222,"navigation":223,"part":220,"path":224,"published":223,"robots":220,"seo":225,"series":220,"stem":226,"strengths":220,"summary":220,"tags":227,"tradeoffs":220,"__hash__":231},"posts\u002Fposts\u002FBackend\u002FKafka\u002Fkafka-messaging-system.md","Kafka 메시징 시스템의 구성과 동작 방식",{"type":7,"value":8,"toc":202},"minimark",[9,14,18,23,26,29,38,41,44,47,51,54,57,73,76,79,82,85,88,91,95,98,101,104,107,111,117,120,123,127,130,133,136,139,148,152,155,158,161,165,168,171,174,177,181,184,187,194],[10,11,13],"h1",{"id":12},"게시글-설명","게시글 설명",[15,16,17],"p",{},"클라우드 트랙에서 Kafka로 서비스를 구현해보신 \"떙정\" 님의 게시글을 바탕으로 Kafka를 설명해보려 한다.",[19,20,22],"h2",{"id":21},"_1-메시징-시스템-부분","1. 메시징 시스템 부분",[15,24,25],{},"회원가입·주문 완료\n->\nMemberService \u002F OrderService\n-> 이벤트 발행\nKafka\n-> 이벤트 소비\nMailService\n->\n사용자에게 메일 발송",[15,27,28],{},"예를 들어 주문이 완료되면 OrderService가 다음 메시지를 보낸다.",[15,30,31,32,37],{},"{\n\"orderId\": 1001,\n\"memberId\": 25,\n\"email\": \"",[33,34,36],"a",{"href":35},"mailto:user@example.com","user@example.com","\"\n}",[15,39,40],{},"MailService는 order-completed Topic을 계속 구독하다가 이벤트가 들어오면 메일을 발송",[15,42,43],{},"주의!",[15,45,46],{},"Kafka 메시지는 반드시 HTTP REST API로 전달하는 것이 아닙니다. 보통 애플리케이션 내부의 Kafka Producer Client가 Kafka 전용 네트워크 프로토콜로 Broker에 전송",[19,48,50],{"id":49},"_2-publishsubscribe의-장점","2. Publish\u002FSubscribe의 장점",[15,52,53],{},"그렇다면 REST API를 놓고서 왜 Kafka를 쓰는 걸까?",[15,55,56],{},"OrderService는 다음 내용을 몰라도 된다",[58,59,60,64,67,70],"ol",{},[61,62,63],"li",{},"MailService의 주소",[61,65,66],{},"MailService가 몇 대인지",[61,68,69],{},"메일 발송이 얼마나 걸리는지",[61,71,72],{},"PointService나 AnalyticsService가 추가됐는지",[15,74,75],{},"새로운 서비스가 필요하면 OrderService를 수정하지 않고, 새 Consumer Group을 추가하는 것이 가능하다",[15,77,78],{},"기존\nOrderService → Kafka → MailService",[15,80,81],{},"확장\nOrderService → Kafka → MailService\n→ PointService\n→ AnalyticsService",[15,83,84],{},"한 번에 여러개로 전달할 수 있다.",[15,86,87],{},"코드와 실행 상태는 분리되지만 이벤트 형식에는 의존한다",[15,89,90],{},"다만 이런 경우에 OrderService가 메시지 필드 이름을 갑자기 바꾸면 Consumer들이 깨질 수 있다. 이벤트 스키마의 버전 관리가 필요하다.",[19,92,94],{"id":93},"_3-broker","3. Broker",[15,96,97],{},"운영 환경에서는 보통 Broker를 여러 대 둔다.",[15,99,100],{},"Kafka Cluster\n├─ Broker 1\n├─ Broker 2\n└─ Broker 3",[15,102,103],{},"이렇게 구성한다면",[15,105,106],{},"여러 Broker에 Partition 복제본을 두면 한 서버가 고장 나도 서비스를 계속할 수 있다.",[19,108,110],{"id":109},"_4-topic","4. Topic",[112,113,114],"blockquote",{},[15,115,116],{},"같은 종류의 이벤트를 여러 Partition에 순서대로 보관하는 논리적 로그",[15,118,119],{},"order-completed\nmember-created\npayment-failed",[15,121,122],{},"Topic 이름은 가능하면 명령보다 이미 발생한 사실을 나타내는 과거형이 이해하기 좋다고 한다.",[19,124,126],{"id":125},"_5-partition과-key","5. Partition과 Key",[15,128,129],{},"게시글의 설명처럼 Partition은 Topic을 나눈 샤드",[15,131,132],{},"key = memberId 25",[15,134,135],{},"회원 25 주문 생성\n→ 회원 25 결제 완료\n→ 회원 25 배송 시작",[15,137,138],{},"다만 여기서 내가 주의할만한 점은 2가지이다.",[140,141,142,145],"ul",{},[61,143,144],{},"key가 없으면 같은 사용자 이벤트가 서로 다른 Partition에 들어갈 수 있다.",[61,146,147],{},"Partition 수를 나중에 늘리면 key와 Partition의 매핑이 달라질 수 있다.\n따라서 “Partition을 늘리면 무조건 좋다”는 것은 아니다. 병렬성은 증가하지만 관리 비용과 순서 설계가 복잡해진다.\n(Trade-Off를 잘 고려해서 서버의 갯수를 정해야 한다.)",[19,149,151],{"id":150},"_6-producer","6. Producer",[15,153,154],{},"OrderService 안에 Kafka Producer 라이브러리가 들어 있다.",[15,156,157],{},"OrderService\n└─ KafkaProducer.send(\"order-completed\", event)",[15,159,160],{},"Producer는 Kafka에 메시지를 생산하는 애플리케이션 또는 그 역할",[19,162,164],{"id":163},"_7-consumer와-consumer-group","7. Consumer와 Consumer Group",[15,166,167],{},"Consumer Group에 속한 Consumer들은 메시지 처리를 나눠 가진다.",[15,169,170],{},"다만 하나의 Partition은 같은 그룹 내에서 동시에 한 Consumer만 담당",[15,172,173],{},"Partition 3개 + Consumer 5개\n→ 3개는 처리\n→ 2개는 대기",[15,175,176],{},"따라서 Consumer 수만 늘린다고 무조건 처리량이 증가하지 않는다. 최대 병렬 처리 단위는 기본적으로 Partition 수",[19,178,180],{"id":179},"_8-offset과-commit","8. Offset과 Commit",[15,182,183],{},"Topic 전체 번호가 아니라 각각의 Partition 안에서의 메시지 번호",[15,185,186],{},"참고 자료",[15,188,189],{},[33,190,191],{"href":191,"rel":192},"https:\u002F\u002Frainbow-beard-524.notion.site\u002FKafka-28775575898d8025a9c6e53ff533b89c",[193],"nofollow",[58,195,196,199],{},[61,197,198],{},"Kafka를 이용한 자동 메일 발송 구조",[61,200,201],{},"EC2에서 Kafka Broker를 실행하는 Docker 명령어",{"title":203,"searchDepth":204,"depth":204,"links":205},"",2,[206,207,208,209,210,211,212,213],{"id":21,"depth":204,"text":22},{"id":49,"depth":204,"text":50},{"id":93,"depth":204,"text":94},{"id":109,"depth":204,"text":110},{"id":125,"depth":204,"text":126},{"id":150,"depth":204,"text":151},{"id":163,"depth":204,"text":164},{"id":179,"depth":204,"text":180},[215,216],"Backend","Kafka","2026-08-26T14:08:02+09:00","Kafka 기반 메시징 시스템에서 Publish\u002FSubscribe, Broker, Topic, Partition, Producer, Consumer와 Offset이 동작하는 방식을 정리한다.","md",null,"\u002Fbackend\u002Fkafka\u002F2026\u002F08\u002F26\u002Fkafka-messaging-system\u002F",{},true,"\u002Fposts\u002Fbackend\u002Fkafka\u002Fkafka-messaging-system",{"title":5,"description":218},"posts\u002FBackend\u002FKafka\u002Fkafka-messaging-system",[216,228,229,230],"Messaging","Producer","Consumer","-mwqJM0A5fodqdF3T8FOgepQFiCQLrSSXoWoUr6HaWI",1788744785248]