Mano CQRS patirtis
• Susidomėjau 2010
• Išbandžiau praktikoje 2011-2013
• Kas yra CQRS?
• Kam teko dalyvauti projektuose su CQRS architektūra?
• CQRS, problemos, privalumai
2
Command Query Responsibility Segregation
• Komandų ir užklausų atsakomybės atskyrimas
• Priekaištas CRUD’ui
• Praktinis įgyvendinimo pavyzdys
3
Event handlers
Command handlers
Command
“Sukurti vartotoją”
Client
Event/Aggregate
DB
Aggregate
Vartotojas
(Aggregate root)
Addr.
CC
1
n
1
n
Events
“Vartotojas sukurtas”
Events
“Vartotojas sukurtas”
Events
“Vartotojas sukurtas”
Publish events
Query
DB
Update
query model
27
User name Main address Main CC
Andrius Sukilėlių g. 45 32423
Juozas Utenos g. 12 63575
Petras Klevo g. 114 83465
Event handlers
Command handlers
Command
“Sukurti vartotoją”
Client
Event/Aggregate
DB
Aggregate
Vartotojas
(Aggregate root)
Addr.
CC
1
n
1
n
Events
“Vartotojas sukurtas”
Events
“Vartotojas sukurtas”
Events
“Vartotojas sukurtas”
Publish events
Query
DB
Update
query model Integrate with 3rd party
28
User name Main address Main CC
Andrius Sukilėlių g. 45 32423
Juozas Utenos g. 12 63575
Petras Klevo g. 114 83465
Event handlers
Command handlers
Command
“Sukurti vartotoją”
Client
Event/Aggregate
DB
Aggregate
Vartotojas
(Aggregate root)
Addr.
CC
1
n
1
n
Events
“Vartotojas sukurtas”
Events
“Vartotojas sukurtas”
Events
“Vartotojas sukurtas”
Publish events
Query
DB
Update
query model
Send emails
Integrate with 3rd party
29
User name Main address Main CC
Andrius Sukilėlių g. 45 32423
Juozas Utenos g. 12 63575
Petras Klevo g. 114 83465
Event handlers
Command handlers
Command
“Sukurti vartotoją”
Client
Event/Aggregate
DB
Aggregate
Vartotojas
(Aggregate root)
Addr.
CC
1
n
1
n
Events
“Vartotojas sukurtas”
Events
“Vartotojas sukurtas”
Events
“Vartotojas sukurtas”
Publish events
Query
DB
Update
query model
Send emails
Integrate with 3rd party
etc.
30
User name Main address Main CC
Andrius Sukilėlių g. 45 32423
Juozas Utenos g. 12 63575
Petras Klevo g. 114 83465
Event handlers
Command handlers
Command
“Sukurti vartotoją”
Client
Event/Aggregate
DB
Aggregate
Vartotojas
(Aggregate root)
Addr.
CC
1
n
1
n
Events
“Vartotojas sukurtas”
Events
“Vartotojas sukurtas”
Events
“Vartotojas sukurtas”
Publish events
Query
DB
Update
query model
Send emails
Integrate with 3rd party
etc.
31
User name Main address Main CC
Andrius Sukilėlių g. 45 32423
Juozas Utenos g. 12 63575
Petras Klevo g. 114 83465
Event handlers
Command handlers
Command
“Sukurti vartotoją”
Events
“Vartotojas sukurtas”
Events
“Vartotojas sukurtas”
Events
“Vartotojas sukurtas”
Event/Aggregate
DB
Publish events
Send emails
Integrate with 3rd party
etc.
Query
DB
Update
query model
Aggregate
Vartotojas
(Aggregate root)
Addr.
CC
1
n
1
n
Client
32
User name Main address Main CC
Andrius Sukilėlių g. 45 32423
Juozas Utenos g. 12 63575
Petras Klevo g. 114 83465
Event handlers
Command handlers
Command
“Sukurti vartotoją”
Events
“Vartotojas sukurtas”
Events
“Vartotojas sukurtas”
Events
“Vartotojas sukurtas”
Event/Aggregate
DB
Publish events
Send emails
Integrate with 3rd party
etc.
Query
DB
Update
query model
Aggregate
Vartotojas
(Aggregate root)
Addr.
CC
1
n
1
n
Client
Facade
33
User name Main address Main CC
Andrius Sukilėlių g. 45 32423
Juozas Utenos g. 12 63575
Petras Klevo g. 114 83465
Event handlers
Command handlers
Command
“Sukurti vartotoja”
Events
“Vartotojas sukurtas”
Events
“Vartotojas sukurtas”
Events
“Vartotojas sukurtas”
Event/Aggregate
DB
Publish events
Send emails
Integrate with 3rd party
etc.
Query
DB
Update
query model
Aggregate
Vartotojas
(Aggregate root)
Addr.
CC
1
n
1
n
Client
Facade
C
34
User name Main address Main CC
Andrius Sukilėlių g. 45 32423
Juozas Utenos g. 12 63575
Petras Klevo g. 114 83465
Q
Event handlers
Command handlers
Command
“Sukurti vartotoją”
Events
“Vartotojas sukurtas”
Events
“Vartotojas sukurtas”
Events
“Vartotojas sukurtas”
Event/Aggregate
DB
Publish events
Send emails
Integrate with 3rd party
etc.
Query
DB
Update
query model
Aggregate
Vartotojas
(Aggregate root)
Addr.
CC
1
n
1
n
Client
Facade
User name Main address Main CC
Andrius Sukilėlių g. 45 32423
Juozas Utenos g. 12 63575
Petras Klevo g. 114 83465
36
1
2
3
4
5
6
7
8
9
10
Problemos
1. Nėra įrankių
2. Daug boilerplate kodo
3. Per daug architektūros nuo pat pradžių
4. UI negalima lengvai nustatyti, kada query modelis buvo atnaujintas
5. Tradicinis UI ir CQRS turi nesuderinamumų
6. Commandos ir eventai dažnai būna arba per smulkūs, arba per stambūs
7. Sunku refactorint/migruoti Commandų, Aggregatų, Eventų pakeitimus
8. AR ir EH turėtų būti suprogramuoti “pure functions” principu, o tą sunku
padaryti
37
Problemos 2
9. „More than once delivery“, idempotencijos problema
10. Unikalumo užtikrinimas
11. Eventų eiliškumo svarba
12. Sufailinusių commandų/eventų administravimas
13. Eventų versijavimas
14. Veiksmų koordinavimas tarp skirtingų AR (tranzakcijos nebuvimas, Saga?)
15. AR merge/split
16. Nepavyks taisyti sistemos būsenos tiesiai production DB (bent jau be
savo toolingo)
17. Sudėtingumas
38
Privalumai (kuriuos patyriau asmeniškai)
1. Programuotojo tobulėjimas (projekto sudėtingumo sąskaita)
2. Query DB yra lengvai perkuriama
3. Lengva pridėti naujų agreguotų viewsų
4. Agregatas gali būti bet kokiu .Net objektu
5. Priverčia mąstyti apie data flow per sistemą
6. Messaging ir Queue pažinimas
7. CQRS atrodė rimta mano CV 2012 metais
8. Galima atsisakyti gigantiškų ir sudėtingų SQL querių ir indexų
9. Galima rinktis bet kokią DB technologiją tiek read, tiek ir write
modeliams (bet geriau imti SQL)
39
Privalumai (kurių nespėjau patirti)
10. Turėtų būti scaling friendly
11. Galimybė atsukti sistemos būseną į bet kurią akimirką
12. Galimybė vėliau iš eventų traukti naujas analitines įžvalgas
13. Galimybė labiau paskirstyti backend developerių darbą (ar tikrai
privalumas?)
40