Greenfield Development with CQRS and Windows Azure
-
Upload
resources-global-professionals -
Category
Technology
-
view
1.107 -
download
3
description
Transcript of Greenfield Development with CQRS and Windows Azure
![Page 1: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/1.jpg)
Greenfield Development with CQRS and Windows Azure
David HoersterOctober 18, 2012
![Page 2: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/2.jpg)
C# MVP (since April 2011)Co-Founder of BrainCredits (braincredits.com)Principal at AgileWaysPresident of the Pittsburgh .NET User Group (meetup.com/pghdotnet) and organizer of PGH TechFestTwitter - @DavidHoersterBlog – http://geekswithblogs.net/DavidHoersterEmail – [email protected]
About Me
![Page 3: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/3.jpg)
What is CQRS?Why would you use it?BenefitsSome examplesUsing CQRS in Azure
Goals
![Page 4: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/4.jpg)
Command
Query
Responsibility
Segregation
Is it a pattern or an architecture?
What is CQRS?
![Page 5: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/5.jpg)
Command Query Responsibility Segregation
Based upon Bertrand Meyer’s Command Query Separation (CQS) principle:
“every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, asking a question should not change the answer” (Meyer)
In essence, commands return acknowledgement; queries return data.
What is CQRS?
![Page 6: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/6.jpg)
Backstory
Goals for BrainCredits.com ProductFast readsScalableHandle, potentially, large volumes of requestsBe able to change quicklyAbility to track user in system and events that occurEasy to deploy, manageInexpensive (FREE????)
![Page 7: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/7.jpg)
Backstory
Decided to jump into cloud with AzureScalabilityDeployment via VS2010 (Familiarity)Pretty inexpensive – no HW to manage
BizSpark company (at the time)– Currently 1500 compute hours of small instance– 5 GB of SQL Azure– Small cache instance– 2 million transactions/mo– and more…
But how to store data and design system?
![Page 8: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/8.jpg)
Backstory
I would recommend to start looking along the CQRS style of architectures- Rinat Abdullin
Articles by Greg Young, Udi Dahan, J. Oliver, R. Abdullin
![Page 9: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/9.jpg)
Common Architecture IssuesBusiness logic bleeds through
layersValidation logic ends up
everywhereCopy and Paste developmentApps that cater to modification
opsLeads to general complexity within
tiersCQRS simplifies this with classes performing specific duties (SRP)
What is CQRS?
![Page 10: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/10.jpg)
Simple App (tightly coupled)
Evolution of a System to CQRS
ApplicationDatabase
![Page 11: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/11.jpg)
Breaking out business logic
WriteData(string, string, int, bool, …) { }
Evolution of a System to CQRS
Application
DatabaseBusiness Logic
![Page 12: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/12.jpg)
Introduce messaging
Evolution of a System to CQRS
ApplicationDatabase
Business ServiceMSG
![Page 13: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/13.jpg)
Evolution of a System to CQRS
Client
Read Model StoreEvent Store
Repository Command Service
Domain (ARs)
Denormalizer
Event Handler
Command Issued – ack/nackData Requested/Returned
Command SideQuery Side
Optional
![Page 14: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/14.jpg)
Encapsulates business logic in the domainAllows you to model tasks instead of CRUDAllows for scalability very easilyCan provide for fast reads at the ‘expense’ of more expensive writesOnce the data is read by the client, it’s already old
A system that is eventually consistent is usually acceptableEVENTUAL CONSISTENCY!
– The read model for the system eventually is consistent with the system events
What is CQRS?
![Page 15: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/15.jpg)
Taking this further, CQRS describes a pattern where
Commands are messages (possibly asynchronous)Queries go against a read model
Since commands are returning void, it allows for the message to be transformed into the read modelThis flips the conventional wisdom of fast writes and slow reads
What is CQRS?
![Page 16: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/16.jpg)
Demo
Simple Console-based System
![Page 17: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/17.jpg)
CommandA message sent to tell the system to do something
public class CreateReservation : CommandBase { public Guid ReservationId { get; set; } public String Name { get; set; } public Int32 NumberOfSeats { get; set; } public String DiscountCode { get; set; } }
High-Level Code Walk-through of CQRS
![Page 18: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/18.jpg)
DomainYour system’s business logic and raises eventspublic class Reservation : AggregateRootBase { public void CreateNewReservation(CreateReservation cmd) { //do some logic to figure out TotalCost ApplyEvent(new ReservationCreated() { ReservationId = cmd.ReservationId, ReservationMade = DateTime.UtcNow, NumberOfSeats = cmd.NumberOfSeats, SeatsReservedFor = cmd.Name, TotalCost = totalCost }); }
High-Level Code Walk-through of CQRS
![Page 19: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/19.jpg)
EventsMessages raised by the domain stating that something has been done
public class ReservationCreated : EventBase { public Guid ReservationId { get; set; } public DateTime ReservationMade { get; set; } public Int32 NumberOfSeats { get; set; } public String SeatsReservedFor { get; set; } public Decimal TotalCost { get; set; }}
High-Level Code Walk-through of CQRS
![Page 20: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/20.jpg)
Event Handlers (Denormalizers)Persist event information to the read modelpublic void Handle(ReservationCreated theEvent) { var reservation = new Reservation() {
IsDeleted = false,NumberOfSeats = theEvent.NumberOfSeats,ReservationId = theEvent.ReservationId,ReservationMade = theEvent.ReservationMade,SeatsReservedFor = theEvent.SeatsReservedFor,TotalCost = theEvent.TotalCost };
var repo = new ReservationRepository(); repo.CreateReservation(reservation);}
High-Level Code Walk-through of CQRS
![Page 21: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/21.jpg)
Get all of the orders for user “David” in last 30 days
Benefits
Customer (SalesLT)CustomerID
NameStyle
Title
FirstName
MiddleName
LastName
Suffix
CompanyName
SalesPerson
EmailAddress
Product (SalesLT)ProductID
Name
ProductNumber
Color
StandardCost
ListPrice
Size
Weight
ProductCategoryID
ProductModelID
SellStartDate
SellEndDate
ProductCategory (SalesLT)ProductCategoryID
ParentProductCategoryID
Name
rowguid
ModifiedDate
ProductModel (SalesLT)ProductModelID
Name
CatalogDescription
rowguid
ModifiedDate
SalesOrderDetail (SalesLT)SalesOrderID
SalesOrderDetailID
OrderQty
ProductID
UnitPrice
UnitPriceDiscount
LineTotal
rowguid
ModifiedDate
SalesOrderHeader (SalesLT)SalesOrderID
RevisionNumber
OrderDate
DueDate
ShipDate
Status
OnlineOrderFlag
SalesOrderNumber
PurchaseOrderNumber
AccountNumber
CustomerID
ShipToAddressID
BillToAddressID
ShipMethod
CreditCardApprovalCode
SubTotal
TaxAmt
Freight
![Page 22: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/22.jpg)
Get all the orders for user ‘David’ in last 30 days
Benefits
SELECT c.FirstName, c.MiddleName, c.LastName, soh.SalesOrderID, soh.OrderDate, sod.UnitPrice, sod.OrderQty, sod.LineTotal, p.Name as 'ProductName', p.Color, p.ProductNumber, pm.Name as 'ProductModel', pc.Name as 'ProductCategory', pcParent.Name as 'ProductParentCategory'FROM SalesLT.Customer c INNER JOIN SalesLT.SalesOrderHeader soh
ON c.CustomerID = soh.CustomerIDINNER JOIN SalesLT.SalesOrderDetail sod ON soh.SalesOrderID = sod.SalesOrderIDINNER JOIN SalesLT.Product p ON sod.ProductID = p.ProductIDINNER JOIN SalesLT.ProductModel pm ON p.ProductModelID = pm.ProductModelIDINNER JOIN SalesLT.ProductCategory pc ON p.ProductCategoryID = pc.ProductCategoryIDINNER JOIN SalesLT.ProductCategory pcParent ON pc.ParentProductCategoryID =
pcParent.ProductCategoryIDWHERE c.FirstName = 'David'
AND soh.OrderDate > (GETDATE()-30)
![Page 23: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/23.jpg)
Wouldn’t it be great if it was something like?
Benefits
SELECT FirstName, MiddleName, LastName, SalesOrderID, OrderDate, UnitPrice, OrderQty, LineTotal, ProductName, Color, ProductNumber, ProductModel, ProductCategory, ProductParentCategoryFROM CustomerSalesWHERE FirstName = 'David'
AND OrderDate > (GETDATE()-30)
![Page 24: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/24.jpg)
Command Side Flow
Command Domain
Event 1
Event 2
Event N
Handler 1
Handler 2
Handler N
ReadModel
![Page 25: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/25.jpg)
Read Side Flow
ReadModel
Query Provider(Repo/
WCFDS/etc)
Client
Request for Data
DTO
Query
Results
![Page 26: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/26.jpg)
Demo
Moving CQRS to Azure
![Page 27: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/27.jpg)
Hosting CQRS in AzureTypically, you’d want 2 roles
Web Role for the UI, which also performs queryingWorker Role for the Command handling
Both roles can scale out as much as needed
Multiple web roles with a single worker role, or vice versa or both!
CQRS in the Cloud
![Page 28: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/28.jpg)
CQRS in Azure
Client
Read Model StoreEvent Store
Repository
Command Service
Domain (ARs)
Denormalizer
Event Handler
Worker Role
Web Role Command Side
SQL Azureor other
Repository
Table Storage?
Query Side
![Page 29: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/29.jpg)
How do I issue commands from my web role?Some typical solutions
WCF service on the worker role side3rd party service bus toolUse Azure storage features (blobs, queues, tables)
All have advantages and disadvantages
CQRS in the Cloud
![Page 30: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/30.jpg)
General flow is thisWeb role issues a command by dropping it in a blob container (name is GUID).Command blob name is then dropped in a queueWorker role monitors queue for workWhen it finds a message in the queue, it grabs blob from storage based on id in queue messageDeserializes command and then sends it through normal CQRS pipeline
CQRS in the Cloud
![Page 31: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/31.jpg)
CQRS in the Cloud
ControllerQueue
Blob Storage
Command Handler
Azure Table Storage
Domain
Event(s)
Denormalizer
Read Model
Repository
Web Role Worker Role
Azure Sub-system
![Page 32: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/32.jpg)
Web and Worker Role SeparationShare knowledge of queues and interface
If worker were to go down, web would still run
Commands would queue upProvides some level of fault tolerance
CQRS in the Cloud
![Page 33: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/33.jpg)
Worker role can spawn multiple threads to monitor queues
BrainCredits has several threadsCommandQueue and LogQueueDifferent polling intervalsDepending on importance of information
CQRS in the Cloud
![Page 34: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/34.jpg)
Using Azure Table Storage for logging user actions…
Different than events. Want to know user behavior.Storage is huge – just watch transaction costs
Consider batching log reads
But you can create replays of user interaction
Similar to event sourcing’s replay of eventsEvent sourcing doesn’t capture “Cancels” or “Reads”, which may be useful from a marketing perspective
CQRS in the Cloud
![Page 35: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/35.jpg)
Claim Credit for this Session
BrainCreditshttp://www.braincredits.com/Lesson/17210
![Page 36: Greenfield Development with CQRS and Windows Azure](https://reader035.fdocuments.net/reader035/viewer/2022081400/5553b83fb4c905d4448b4e43/html5/thumbnails/36.jpg)
Resources
Cerebrata Cloud Storage Studio – http://cerebrata.comParaleap AzureWatch – http://paraleap.com
Conference Reservation Example on GitHubhttps://github.com/DavidHoerster/Conference
CQRS Journey – https://github.com/mspnp/cqrs-journey-docCQRS Info Site – http://cqrs.wordpress.com/DDD/CQRS Google Group - http://groups.google.com/group/dddcqrsUdi Dahan’s CQRS article “Clarified CQRS” – http://www.udidahan.com/2009/12/09/clarified-cqrs /Rinat Abdullin’s CQRS information – http://abdullin.com/cqrsDistributed Podcast - http://distributedpodcast.com/