[Spring boot] Axon Framework๋กœ ์‹œ์ž‘ํ•˜๋Š” CQRS ๊ธฐ์ดˆ

๋ฐ˜์‘ํ˜•

๋งŽ์ด ๋ฏธ๋ฃจ์–ด์ง„ Axon Framework์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด ํฌ์ŠคํŠธ๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์ „์— ์•„์ฃผ ์˜ค๋žœ ์‹œ๊ฐ„ ์ „, MSA์˜ ํŠธ๋žœ์žญ์…˜ ์ด์•ผ๊ธฐ ์ค‘ ์ด๋ฒคํŠธ ์†Œ์‹ฑ๊ณผ CQRS์— ๋Œ€ํ•ด ๋‹ค๋ค„๋ณธ ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ๋‚ด์šฉ์„ ๋จผ์ € ์ˆ™์ง€ํ•˜์‹  ๋‹ค์Œ ์ง„ํ–‰ํ•ด๋ณด๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

 

2021.03.21 - [Architecture/MSA] - [MSA] 7. MSA์˜ ํŠธ๋žœ์žญ์…˜ ์ด์•ผ๊ธฐ 3 - ์ด๋ฒคํŠธ ์†Œ์‹ฑ๊ณผ CQRS

 

[MSA] 7. MSA์˜ ํŠธ๋žœ์žญ์…˜ ์ด์•ผ๊ธฐ 3 - ์ด๋ฒคํŠธ ์†Œ์‹ฑ๊ณผ CQRS

์ด๋ฒคํŠธ ์†Œ์‹ฑ์„ ์ฒ˜์Œ ์ ‘ํ•˜๊ฒŒ ๋œ ๊ฒƒ์€ 2017 SpringCamp์—์„œ์˜€์Šต๋‹ˆ๋‹ค. ๋‹น์‹œ์—๋Š” MSA๋ผ๋Š” ๊ฐœ๋…์— ๋Œ€ํ•ด ์ž˜ ์•Œ์ง€๋„ ๋ชปํ–ˆ๊ณ , MSA๋Š” ๋Œ€๊ธฐ์—…์—์„œ๋‚˜ ์“ธ ์ˆ˜ ์žˆ๊ณ , ์ ์šฉ๊ฐ€๋Šฅํ•œ ์—„์ฒญ๋‚˜๊ฒŒ ํฐ ์•„ํ‚คํ…์ฒ˜์˜€๋‹ค. ๋ผ๊ณ ๋งŒ ์ธ

blog.neonkid.xyz

 

 

 

Axon Framework

Axon Framework๋Š” Java ์–ธ์–ด์—์„œ Event Sourcing๊ณผ CQRS๋ฅผ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•˜๋„๋ก ๋„์™€์ฃผ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. Axon Framework๋Š” ๋„ค๋œ๋ž€๋“œ์—์„œ ์„ค๋ฆฝ๋œ AxonIQ ํšŒ์‚ฌ์—์„œ ๊ฐœ๋ฐœ์„ ์ฃผ๋„ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ํ˜„์žฌ ์˜คํ”ˆ ์†Œ์Šค๋กœ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

https://github.com/AxonFramework/AxonFramework

 

GitHub - AxonFramework/AxonFramework: Framework for Evolutionary Event-Driven Microservices on the JVM

Framework for Evolutionary Event-Driven Microservices on the JVM - GitHub - AxonFramework/AxonFramework: Framework for Evolutionary Event-Driven Microservices on the JVM

github.com

Axon Framework๋Š” Event Store์™€ ๊ฒฐํ•ฉํ•˜์—ฌ, CQRS, Event Sourcing์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์—ฌ๊ธฐ์— MSA๋ฅผ ์ ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๊ฐ ์„œ๋น„์Šค๋ผ๋ฆฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ฃผ๊ณ  ๋ฐ›๊ธฐ ์œ„ํ•œ Axon Server๊นŒ์ง€ ์‚ฌ์šฉํ•˜๋ฉด Java ์–ธ์–ด์—์„œ ์šฐ๋ฆฌ๊ฐ€ ์ด์ „์— ๋‹ค๋ค˜๋˜ MSA์˜ ๋‹ค์–‘ํ•œ ํŠธ๋žœ์žญ์…˜์„ ๊ตฌํ˜„ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

 

Axon Framework Architecture

ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๊ธฐ ์ „, Axon Framework๊ฐ€ ์–ด๋–ค ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”์ง€์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

UI์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋ช…๋ น(command)๋ฅผ ๋ณด๋‚ด๋ฉด ๋ช…๋ น์„ ํ•ธ๋“ค๋งํ•˜๋Š” Component๊ฐ€ ๋ช…๋ น์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ฒ˜๋ฆฌ ์ค‘์— ์™ธ๋ถ€ ์ €์žฅ์†Œ(DB)์— ์˜์†์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ persist ์ž‘์—…์„ ๊ฑฐ์น˜๊ณ , ์ด๋Ÿฌํ•œ ๋ณ€ํ™”์— ๋Œ€ํ•œ ์ด๋ฒคํŠธ(Event)๋ฅผ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง Component๊ฐ€ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋Š” ์•„ํ‚คํ…์ฒ˜์ž…๋‹ˆ๋‹ค.

 

์ด๋Ÿฌํ•œ ๊ตฌ์กฐ๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ง€๋‚œ ํฌ์ŠคํŠธ์—์„œ ๋‹ค๋ค˜๋˜ CQRS ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. Axon Framework๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ CQRS ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , Java ์–ธ์–ด์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

Install Axon Server

์ด์ œ ๊ตฌ์กฐ๋ฅผ ํŒŒ์•…ํ–ˆ์œผ๋‹ˆ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” JVM ๊ณ„์—ด์—์„œ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” Spring Framework๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ REST API ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค๊ณ  ๊ทธ ๋‚ด๋ถ€์—์„œ Axon Framework๋ฅผ ์ด์šฉํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋จผ์ € ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›๊ธฐ ์œ„ํ•œ Axon Server๋ฅผ ๊ตฌ๋™ํ•ฉ๋‹ˆ๋‹ค. Axon Server ๊ตฌ๋™์„ ์œ„ํ•ด Docker๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

docker run ๋ช…๋ น์„ ์ด์šฉํ•˜์—ฌ Axon Server๋ฅผ ๋กœ์ปฌ์— ๋„์›๋‹ˆ๋‹ค. ์ด ๋•Œ 8024๋ฒˆ ํฌํŠธ๋Š” ์›น์—์„œ ์Šคํ† ์–ด์˜ ์ƒํƒœ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๋Œ€์‹œ๋ณด๋“œ ์ ‘์†์šฉ ํฌํŠธ์ด๊ณ , 8124๋ฒˆ ํฌํŠธ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ์ฃผ๊ณ  ๋ฐ›๋Š” ํฌํŠธ์ž…๋‹ˆ๋‹ค.

 

์ด๋ฏธ์ง€๋ฅผ ๋‹ค์šด๋กœ๋“œ ๋ฐ›๊ณ  ์‹คํ–‰๋˜์—ˆ๋‹ค๋ฉด docker ps ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜์—ฌ ์„œ๋ฒ„๊ฐ€ ์ œ๋Œ€๋กœ ๊ตฌ๋™๋˜์—ˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

 

์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์—ด๊ณ , 8024๋ฒˆ ํฌํŠธ์— ์ ‘์†ํ•˜์—ฌ ๋Œ€์‹œ๋ณด๋“œ๊ฐ€ ๋‚˜์˜จ๋‹ค๋ฉด ์„ค์น˜๊ฐ€ ์™„๋ฃŒ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

 

 

Create Project

์ด์ œ ์Šคํ”„๋ง ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด ์ฃผ์ œ์—์„œ๋Š” ๋ฉ€ํ‹ฐ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•  ๊ฒƒ์ด์ง€๋งŒ ์ด๋ฒˆ ํฌ์ŠคํŠธ์—์„œ๋Š” Axon Framework๋ฅผ ์–ด๋–ป๊ฒŒ ์Šคํ”„๋ง ํ”„๋กœ์ ํŠธ์— ๋„์ž…ํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๋จผ์ € ์‚ดํŽด๋ณด๊ธฐ ์œ„ํ•จ์ด๋ฏ€๋กœ ๋‹จ์ผ ๋ชจ๋“ˆ๋กœ ์ง„ํ–‰ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์ธํ…”๋ฆฌJ๋ฅผ ์—ด๊ณ  Spring Initializr๋ฅผ ์ด์šฉํ•ด ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

 

build.gradle์„ ์—ด์–ด์„œ Axon Framework 4.2.1 ๋ฒ„์ „์œผ๋กœ implementation ์ฝ”๋“œ๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

 

 

 

Config Axon Server

์ด์ œ ์•„๊นŒ ๊ตฌ๋™ํ•œ Axon Server์˜ ์ฃผ์†Œ์™€ ํฌํŠธ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. Spring ํ”„๋กœ์ ํŠธ์—์„œ application.yml์„ ์—ฝ๋‹ˆ๋‹ค.

 

axon ํ”„๋กœํผํ‹ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ Axon Server ์ฃผ์†Œ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  serializer๋Š” xstream์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์—ฌ๊ธฐ์„œ serializer๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ์ฃผ๊ณ  ๋ฐ›์„ ๋–„ ์‚ฌ์šฉํ•˜๋Š” ์‹œ๋ฆฌ์–ผ๋ผ์ด์ง• ํฌ๋งท์„ ์ŠคํŠธ๋ฆผ์œผ๋กœ ํ•˜๊ฒ ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

 

 

Command Handler / Event Handler

Axon Framework์—์„œ๋Š” ์ด๋ฒคํŠธ๋ฅผ ๋ฐœํ–‰ํ•˜๋Š” Command์™€ ์ด๋ฒคํŠธ๋ฅผ ๊ตฌ๋…ํ•˜๋Š” Query๋กœ ํ•˜์—ฌ๊ธˆ ๋ฉ”์‹œ์ง€๋ฅผ ์ฃผ๊ณ  ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด CQRS์˜ ๊ธฐ๋ณธ์ด๋ฉฐ Axon Framework์—์„œ๋Š” ์ด๋“ค์˜ ์ด๋ฒคํŠธ๋ฅผ ํ•ธ๋“ค๋ง ํ•  ์ˆ˜ ์žˆ๋Š” ์–ด๋…ธํ…Œ์ด์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

 

  • CommandHandler
  • EventHandler

 

CommandHandler๋Š” ์ด๋ฒคํŠธ๋ฅผ Event Store๋กœ ์ „๋‹ฌํ•˜๋Š” ํ•ธ๋“ค๋Ÿฌ์ด๊ณ , EventHandler๋Š” ํ•ด๋‹น ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•ธ๋“ค๋Ÿฌ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ Spring ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋‘ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์„ ์–ธํ•ด์•ผ๋งŒ Axon Server์— ์—ฐ๊ฒฐ์ด ๋ฉ๋‹ˆ๋‹ค.

 

Spring boot ๋ฉ”์ธ ์ฝ”๋“œ์— CommandHandler๋ฅผ ์„ ์–ธํ•˜๊ณ  ๊ทธ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์„ ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋‹จ ์—ฐ๊ฒฐ์ด ๋˜๋Š”์ง€๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๋ฉ”์„œ๋“œ์—๋Š” ์•„๋ฌด๋Ÿฐ ๋‚ด์šฉ๋„ ์ ์ง€ ์•Š๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿฐ ๋‹ค์Œ Spring boot Application์„ ์‹คํ–‰ํ•˜๋ฉด Axon Server ์ฃผ์†Œ์— ์—ฐ๊ฒฐ๋˜์—ˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์œผ๋ฉฐ Command Handler ํ•˜๋‚˜๊ฐ€ ๋“ฑ๋ก๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ๋ฉ”์„œ๋“œ์˜ argument๋กœ ์ง€์ •ํ•œ obj๋Š” ์‹ค์ œ Command์ด๋ฉฐ ์ฐจํ›„ Event Handler๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ argument๋กœ ์ฃผ๋Š” ๊ฒฝ์šฐ, Command Handler์—์„œ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœํ–‰ํ–ˆ์„ ๋•Œ ํ•ด๋‹น Event Handler๊ฐ€ ์‹คํ–‰๋˜๋Š” ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค.

 

Dashboard์— ์ ‘์†ํ•˜๋ฉด application์ด Axon Server์™€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ์— EventHandler๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด CommandHandler์—์„œ ๋‚˜ํƒ€๋‚˜๋Š” ์ด๋ฒคํŠธ๋ฅผ EventHandler๊ฐ€ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ํ›„ ๋กœ๊ทธ๋ฅผ ๋ณด๋ฉด TrackingEventProcessor๊ฐ€ ํ• ๋‹น๋˜์—ˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ฐ”๋กœ ์ด๋ฒคํŠธ๋ฅผ ์ถ”์ ํ•˜๋Š” ๋…€์„์ž…๋‹ˆ๋‹ค.

 

 

 

๋งˆ์น˜๋ฉฐ..

Axon Framework๋ฅผ ํ†ตํ•ด์„œ CQRS๊ฐ€ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„๋  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๊ฐ„๋‹จํžˆ ์‚ดํŽด๋ดค์Šต๋‹ˆ๋‹ค. CQRS์˜ ๋ณธ์งˆ์€ ์ด๊ฒƒ์ด ๋์ด ์•„๋‹ˆ๋ฉฐ ์šฐ๋ฆฌ๋Š” ๊ทธ ์ค‘์—์„œ ๊ฐ€์žฅ ๊ธฐ์ดˆ์ ์ธ ๋ถ€๋ถ„์ธ ์„ค์น˜์™€ ์—ฐ๊ฒฐ์„ ๋‹ค๋ฃฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

์•„์ง๊นŒ์ง€ ์ƒ์†Œํ•œ ๋‹จ์–ด๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค. CommandBus, EventHandler, CommandHandler ๊ธฐ์ดˆ์ ์ธ ๊ฐœ๋…์€ ์•Œ์•˜์ง€๋งŒ ์ด ๋ถ€๋ถ„์„ ์–ด๋–ป๊ฒŒ ์“ฐ๋ฉด ์ข‹์„๊นŒ์š”?

 

๋‹ค์Œ ํฌ์ŠคํŠธ์—์„œ ์‹ค์ „ ์˜ˆ์ œ๋ฅผ ๊ฐ€์ง€๊ณ  ํ•œ ๋ฒˆ ๋‹ค๋ค„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•
TAGS.

Tistory Comments