+ All Categories
Home > Documents > The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the...

The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the...

Date post: 25-May-2020
Category:
Upload: others
View: 4 times
Download: 0 times
Share this document with a friend
56
The Big Friendly Monolith
Transcript
Page 1: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

The Big Friendly Monolith

Page 2: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Frans van Buul

About [email protected]

+31 6 5068 2984

https://www.linkedin.com/in/frans-van-buul-8030743/

Page 3: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

What is AxonIQ?• AxonIQ was founded in July 2017 as a commercial company with

a focus on the open source Axon Framework.

• AxonIQ delivers:• Support, training, consultancy for Axon Framework• Commercial software products that work in conjunction with Axon

Framework.

• Based in Amsterdam, 11 people as of November 2017

Page 4: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Agenda• Microservices in the context of layered architecture and DDD

• CQRS, event sourcing and Axon Framework concepts

• Axon Framework code examples

Page 5: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Layered Architecture

Dom

ain Model

User Interface

Service Layer

Data Access Layer

Page 6: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Evolution of a Domain Model

Page 7: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Evolution of a Domain Model

Page 8: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Example

OrderOrder

Order Linequantity

Order Linequantity

Productprice

Productprice

Customer Order

*1

Page 9: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Example

OrderOrder

Order Linequantity

Order Linequantity

Productprice

Productprice

Product CategoryProduct

Category

Customer Order perspective

Product catalogueperspective

* *1

Page 10: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Example

OrderOrder

Order Linequantity

Order Linequantity

ProductProduct

Product CategoryProduct

CategoryCustomer Order perspective

Product catalogueperspective

*

*1

PricePrice1

* 1 (current)

Page 11: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Evolution of a Domain Model

Page 12: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Big Ball of “Mud”

Source: http://www.sabisabi.com/images/DungBeetle-on-dung.JPG

Page 13: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

This won’t help!

Dom

ain Model

User Interface

Service Layer

Data Access Layer

Page 14: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Source:http://geek-and-poke.com/geekandpoke/2013/7/13/foodprints

“We gave up finding proper names for the

layers long ago. Since then we justname them aftertheir architects.”

Page 15: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Microservice Architecture

Source: http://martinfowler.com/articles/microservices.html

Page 16: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Microservices vs Monoliths

Microservices systemAlmost all the cases where I've heard of asystem that was built as a microservice systemfrom scratch, it has ended up in serious trouble.

MonolithsAlmost all the successful microservice storieshave started with a monolith that got too bigand was broken up

Martin Fowler

Source: http://martinfowler.com/bliki/MonolithFirst.html

Page 17: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Microservices vs Monoliths

Going from monoliths to microservicesIt’s really difficult to break up our legacymonolith into microservices!

Pretty much everybody these days

Page 18: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Microservice journeyThe big, friendly monolith!

Page 19: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Axon Framework• “CQRS Framework” for Java

• Open source (Apache 2 License)

• Simplify CQRS based applications• Building blocks common in CQRS-based architectures

• More information: http://www.axonframework.org

Page 20: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Core Principles• Message oriented

• Events

• Commands

• Queries

• Location transparency• Separate infrastructure from business logic

• Customizable• Configure to match your infrastructure, not vice versa

Page 21: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Command Query Responsibility Segregation

Command model

Projections

Client

Events

Commands Queries

Page 22: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Source: https://giphy.com

Page 23: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Why?• Throughput characteristics

• Mixing technologies (SQL, NoSQL)

• Query complexity

• Event sourcing

• Simplification on the long run

Page 24: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Aggregates

Command model

Page 25: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Revisiting the example

OrderOrder

Order Lineproduct name

unit pricequantity

total price

Order Lineproduct name

unit pricequantity

total price

Productnameprice

Productnameprice

Product CategoryProduct

Category

Order aggregate Product aggregate

* *

Page 26: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Read modelsProjections

Optimized for the specificread use-cases (e.g. screens, API methods)

Many separated onesinstead of one big one.

Page 27: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Read modelsProjections

Page 28: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

CQRS Based Architecture

Page 29: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

All togetherProduct

AggregateOrder

AggregateProduct

ProjectionOrder

Projection

Product manager

CreateProductCmdProductCreatedEvent

Registers product in read model

Customer

GetProductInfoQuery

AddProductToOrderCmd

ProductAddedToOrderEvent

Page 30: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Traditional method

About persisting aggregates

• Store the current state directly to database (e.g. byusing JPA).

Page 31: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Traditional method Event Sourcing

About persisting aggregates

• Store the current state directly to database (e.g. byusing JPA).

• Aggregates only change state through events.

• Events are distributed andpersisted to an event store.

• To read an aggregate, readall events belonging to thataggregate and replay them.

Page 32: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Business reasons Technical reasons

Why use event sourcing?

• Auditing / compliance / transparency

• Data mining, analytics:value from data

• Guaranteed completeness of raised events

• Single source of truth• Concurrency / conflict resolution• Facilitates debugging• Replay into new read models (CQRS)• Easily capturing intent

Page 33: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Traditional

Example: interesting history

Order:

2 bananas1 peach

Page 34: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Traditional Event Sourcing

Example: interesting history

Order:

2 bananas1 peach

Order:3 apples added2 bananas added3 apples removed1 peach added

Page 35: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Traditional

Example: capturing intent

UPDATE customer_address

SET line1 = “10 Random St”

Page 36: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Traditional Event Sourcing

Example: capturing intent

UPDATE customer_address

SET line1 = “10 Random St”

WrongAddressCorrectedEvent(newLine1 = “10 Random St”)

Or

CustomerRelocatedEvent(newLine1 = “10 Random St”)

Page 37: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

CQRS (+ optionally event sourcing):

1 ingredient for the big friendly monolith

Page 38: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Location transparency

A Component should not be aware, nor make any assumptions, of the location of Components it

interacts with

A component should neither be aware of nor make any assumptions about the location of components it interacts with.

Location transparency starts with good API design (but doesn’t end there)

Page 39: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Components Infrastructure

Location transparency in Axon

• All communicationsbetween components take place through a bus API.

• Components don’t knowwhere the others are.

• Implementations of thosebuses can be switchedwithout changing thebusiness logic.

Page 40: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

It’s NOT just events!

Page 41: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

It’s NOT just events!

A BEvent

Dependency

Page 42: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

It’s NOT just events!

A B

Event

Dependency

Event

Dependency

Page 43: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

It’s NOT just events!

A BCommand

Dependency

Page 44: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

It’s NOT just events!

A BCommand

Dependency

Event

Page 45: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Messaging patternsCommand

- Handled once

- Confirmed

- Consistent routing

Event- Sent to everyone

- Unconfirmed

- Order consistency

Query- Gets an answer

- Usually handled once

- May have scatter/gather characteristics

Page 46: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Code examples

Page 47: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Command and Eventsdata class CreateProductCommand(

val productId: UUID, val name: String, val price: BigDecimal)

data class CreateNewOrderCommand(val orderId: UUID)

data class AddOrderLineCommand(@TargetAggregateIdentifier val orderId: UUID, val orderLineId: UUID, val productId: UUID, val productName: String, val quantity: Int, val unitPrice: BigDecimal)

Page 48: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Sending commands@Componentpublic class OrderService {

@Autowiredprivate final CommandGateway commandGateway;

public UUID createNewOrder() {UUID id = UUID.randomUUID();commandGateway.send(new CreateNewOrderCommand(id));return id;

}

}

Page 49: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Aggregates@Aggregatepublic class Order {

@AggregateIdentifier UUID orderId;

@CommandHandlervoid handle(AddOrderLineCommand cmd) {

if(cmd.getQuantity() < 1) throw new IllegalArgumentException("quantity must be >= 1");apply(new OrderLineAddedEvent(cmd.getOrderId(), cmd.getOrderLineId(), cmd.getProductId(),

cmd.getProductName(), cmd.getQuantity(), cmd.getUnitPrice()));}

@EventHandlervoid handle(OrderLineAddedEvent evt) {}

}

Page 50: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Aggregates@Aggregatepublic class Order {

@AggregateIdentifierUUID orderId;BigDecimal totalOrderValue;

@CommandHandlervoid handle(AddOrderLineCommand cmd) {

if(cmd.getQuantity() < 1) throw new IllegalArgumentException("quantity must be >= 1");if(totalOrderValue.add(cmd.getUnitPrice().multiply(BigDecimal.valueOf(cmd.getQuantity())))

.compareTo(BigDecimal.valueOf(10000L)) > 0) {throw new IllegalStateException("Total order value must be <= 10000");

}apply(new OrderLineAddedEvent(cmd.getOrderId(), cmd.getOrderLineId(), cmd.getProductId(),

cmd.getProductName(), cmd.getQuantity(), cmd.getUnitPrice()));

}

@EventHandlervoid handle(OrderLineAddedEvent evt) {

totalOrderValue = totalOrderValue.add(evt.getUnitPrice().multiply(BigDecimal.valueOf(evt.getQuantity())));

}

}

Page 51: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Read models@Componentpublic class AllOrdersProjection {

@AutowiredEntityManager entityManager;

@EventHandlervoid handle(OrderLineAddedEvent evt) {

/* Find Order JPA entity, add the line so it gets persisted. */}

public List<OrderRecord> findAllOrders() {return entityManager.createQuery("select e from OrderRecord e",

OrderRecord.class).getResultList();}

}

Page 52: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Setting up Axon with default command gateway, commandbus, eventbus, event sourcingrepositories, and serialization mechanism

This page intentionally left blank.

Page 53: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Making the command bus async/* The default with Axon Spring Boot */@Beanpublic CommandBus commandBus() {

return new SimpleCommandBus();}

/* To make this async */@Beanpublic CommandBus commandBus() {

return new AsynchronousCommandBus();}

Page 54: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Making the command bus distributed with JGroups

axon.distributed.enabled=true

Put JGroups and Axon distributed command bus on the classpath.

Set property:

Page 55: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

Making the command bus distributed withSpring Cloud

/* To make this distributed */@Beanpublic CommandRouter springCloudCommandRouter(DiscoveryClient discoveryClient) {

return new SpringCloudCommandRouter(discoveryClient, new AnnotationRoutingStrategy());}@Beanpublic CommandBusConnector springHttpCommandBusConnector(@Qualifier("localSegment")

CommandBus localSegment, RestOperations restOperations, Serializer serializer) {

return new SpringHttpCommandBusConnector(localSegment, restOperations, serializer);}@Primary // to make sure this CommandBus implementation is used for autowiring@Beanpublic DistributedCommandBus springCloudDistributedCommandBus(CommandRouter commandRouter,

CommandBusConnector commandBusConnector) {return new DistributedCommandBus(commandRouter, commandBusConnector);

}

Page 56: The Big Friendly Monolith - GOTO ConferenceCQRS (+ optionally event sourcing): 1 ingredient for the big friendly monolith Location transparency A Component should not be aware, nor

To summarize• CQRS, DDD and location transparency are the key ingredients

to a big friendly monolith that enables evolutionarymicroservices.

• CQRS enables event sourcing, which has a important set of benefits in and by itself.

• Axon Framework enables you to implement this as easily as possible in Java applications.


Recommended