Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

The "Why", "What" & "How" of Microservices - short version

429 views

Published on

Presentation for JDK.IO September 2016

Published in: Technology
  • Be the first to comment

The "Why", "What" & "How" of Microservices - short version

  1. 1. The “Why”, “What” and of Microservices Jeppe Cramon - @jeppec Chief Architect - INPAY “How”
  2. 2. WHY WOULD WE WANT TO USE MICROSERVICES?
  3. 3. Most feel stuck with a monolith and are look for a way out “The” DB UI Logic Data Access
  4. 4. Microservices promise a solution to our problem Monolith Microservice Microservice Microservice MicroserviceMicroservice Microservice Microservice
  5. 5. Microservices as an architectural style 5
  6. 6. ARCHITECTURE IS ESSENTIAL Because it influences how fast we can respond to changes and what the cost of those changes are
  7. 7. ULTIMATELY WE WANT TO BE ABLE TO ADAPT TO CHANGES IN A CONSTANT AMOUNT OF TIME
  8. 8. E.G. IF YOUR PRICING MODEL WAS WRONG – YOU SHOULD BE ABLE TO CHANGE AND REDEPLOY IT IN HOURS/DAYS
  9. 9. SOME ORGANIZATIONS CALCULATE CHANGE TIMES IN MONTHS OR YEARS
  10. 10. WE ALL WANT TO MOVE FAST But can’t always move fast - for various reasons…
  11. 11. THE MAIN MAIN IMPEDIMENT TO OBTAINING HIGH VELOCITY IS
  12. 12. High coupling
  13. 13. Coupling causes ripple effect – much like circles in the water • You want to change a little thing and all of a sudden you need to change 25 other seemingly unrelated things • Zero coupling is impossible • Question is what is the right level of coupling? • This highly depends on how likely the component/system/service is to change and what parts that change together
  14. 14. The playing field Zero coupling The monolith (an indivisible unit)
  15. 15. It usually starts simple “The” DB UI Logic Data Access
  16. 16. Next step is spaghetti in layers
  17. 17. And finally we end up with a Big Ball Of Mud
  18. 18. MICROSERVICES TELL US TO MAKE THINGS SMALLER Adhering to the Single Responsibility Principle (SRP) – “A Microservice should have one reason – and only one reason – to change”
  19. 19. THERE IS VALUE IN MAKING THINGS SMALLER For one thing it is easier to reason about them in isolation It’s easier to replace them – since coupling is explicit
  20. 20. HOW SMALL SHOULD A MICROSERVICE BE?
  21. 21. BUT I’VE HEARD THAT A “MICROSERVICE SHOULD BE NO LARGER THAN 100 LINES OF CODE!?”
  22. 22. SIZE THIS AND SIZE THAT! BE CAREFUL If Microservices are good, then Nanoservices must be even better? Why not one-liner services?
  23. 23. AKA SERVERLESS 23 https://www.linkedin.com/pulse/how-i-decided-use-serverlessnanoservices-architecture-benefield
  24. 24. AKA SERVERLESS 24 https://www.linkedin.com/pulse/how-i-decided-use-serverlessnanoservices-architecture-benefield
  25. 25. Nano Services Unless we have a very good reason for doing so, we risk building services that are so fine-grained that their costs outweigh their utility* *Read Arnon Rotem-Gal-Oz’s Nano Services Anti Pattern:http://arnon.me/wp-content/uploads/2010/10/Nanoservices.pdf
  26. 26. IS YOUR MICROSERVICE VALUABLE? The value of a microservice must exceed the cost of building & operating it. Microservices entail costs for serializations, deserializations, security, communication, maintenance, configuration, deployment, monitoring, etc.
  27. 27. Let’s transform our monolith to microservices “The” DB UI Logic Microservices Data Access Microservices UI-3 MS-3 MS-C UI-2 MS-D UI-4 MS-4MS-2 MS-B MS-E UI-1 UI-5 MS-5MS-1 MS-A
  28. 28. BEWARE… When we break up big things into small pieces we invariably push the complexity to their interaction. Michael Feathers https://michaelfeathers.silvrback.com/microservices-until-macro-complexity
  29. 29. Let’s zoom in on the data tier MS-A “The” DB MS-C MS-D MS-B MS-E
  30. 30. IF OUR MONOLITHS CODE IS COUPLED AND MESSY Chances are that the data(base) model is equally coupled and messy
  31. 31. We start with a simple model
  32. 32. And as time goes by…
  33. 33. It gets more and more complicated
  34. 34. And finally we drown
  35. 35. AND WE END UP WITH ONE DOMAIN MODEL TO RULE THEM ALL
  36. 36. THE MENTAL CAPACITY REQUIRED TO UNDERSTAND THIS DOMAIN MODEL IS HUGE
  37. 37. TO UNDERSTAND ANY PART IN ISOLATION, REQUIRES YOU TO UNDERSTAND THE ENTIRE MODEL - AS EVERYTHING IS COUPLED TO EACH OTHER
  38. 38. Side effect: Our queries get messy
  39. 39. SOA PRINCIPLE SERVICES ARE AUTONOMOUS Autonomy means that our service is independent and self- contained and as far as possible doesn’t directly depend on other services to be functional.
  40. 40. Service autonomy Component B Component C Component A System X Service A Component B Component C System X Slow/unreliable network Different SLA Slow system
  41. 41. SERVICES ARE AUTONOMOUS For a service to be autonomous is MUST own its data Shipping DB
  42. 42. SERVICES ARE AUTONOMOUS For a service to be autonomous is must NOT share state
  43. 43. SERVICES ARE AUTONOMOUS Autonomy is essential for Scalability (scale out clustering) Reliability (fail over clustering)
  44. 44. SERVICES ARE AUTONOMOUS Autonomy is essential for Reusability Adaptability
  45. 45. Let’s refactor the data tier MS-C MS-D MS-B MS-E MS-A A’s DB B’s DB C’s DB D’s DB E’s DB UI Logic Microservices Data Access Microservices UI-3 MS-3 MS-C UI-2 MS-D UI-4 MS-4MS-2 MS-B MS-E UI-1 UI-5 MS-5MS-1 MS-A A’s DB B’s DB C’s DB D’s DB E’s DB
  46. 46. THIS IS ALSO KNOWN AS A DISTRIBUTED MONOLITH
  47. 47. Things that are not Services • A Service with only functionality (and no data) is a FUNCTION • Like: check if order is valid • A Service that only has data is a DATABASE • Like: Entity CRUD • A database already has a nice API - we don’t need to bubble wrap it with REST or Asynchronous messages • Don’t split the atom – we need cohesion as well as decoupling! • If we want datastore abstraction (so we can swap out Postgresql with Mongo or Redis) there this little pattern called Respository. This is typically seen in a lot of layered SOA usages where a function calls a function that calls a function that calls a database
  48. 48. Let’s refactor the “microservices” UI Microservices UI-3 MS-3 UI-2 UI-4 MS-4MS-2 UI-1 UI-5 MS-5MS-1 1’s DB 2’s DB 3’s DB 4’s DB 5’s DB
  49. 49. SRP What about cross Service relationships? Customer Orders Products
  50. 50. Microservices == distributed objects? Service star chart
  51. 51. Reality rears it’s ugly head
  52. 52. WHAT’S WRONG WITH USING RPC/REST/… BETWEEN SERVICES?
  53. 53. Synchronous calls lower our tolerance for faults • When you get an IO error • When servers crash or restarts • When databases are down • When deadlocks occurs in our databases • Do you retry? With synchronous style Service interaction we can loose business data, there’s no automatic retry or we risk creating data more than once because idempotence* often is an after though 53 Client Server Duplicated Response Duplicated Request Processing Response Request Processing The same message can be processed more than once *Idempotence describes the quality of an operation in which result and state does not change if the operation is performed more than 1 time
  54. 54. Also remember: REST isn’t magic!
  55. 55. WITH CROSS SERVICE INTEGRATION WE’RE BOUND BY THE LAWS OF DISTRIBUTED COMPUTING
  56. 56. The 8 Fallacies of Distributed Computing These fallacies are assumptions architects, designers and developers of distributed systems are likely to make. The fallacies will be proven wrong in the long run - resulting in all sorts of troubles and pains for the solution and architects who made the assumptions. 1. The network is reliable. 2. Latency is zero. 3. Bandwidth is infinite. 4. The network is secure. 5. Topology doesn't change. 6. There is one administrator. 7. Transport cost is zero. 8. The network is homogeneous. See http://www.rgoarchitects.com/Files/fallacies.pdf for a walkthrough of the fallacies and why they’re fallacies
  57. 57. A DISTRIBUTED SYSTEM IS ONE WHERE A MACHINE I’VE NEVER HEARD OF CAN CAUSE MY PROGRAM TO FAIL. — Leslie Lamport
  58. 58. Essential complexity of 2 way integration Component C Component B Component A UI Service Service B:Service() call C:Service() call A:Service() commit() Service Local transaction between System A, B and C
  59. 59. B:Service() call C:Service() call A:Service() if (A:Call-Failed:Too-Busy?) Wait-A-While() call A:Service() if (A:Call-Failed:Too-Busy?) Wait-A-Little-While-Longer() call A:Service() if (A:Call-Failed:IO-Error?) Save-We-Need-Check-If-Call-A-Succeded-After-All AND We-Need-To-Retry call C:Service and call B:Service AND Tell-Customer-That-This-Operation-Perhaps-Went-Well if (A:Call-Went-Well?) commit() Accidental complexity from distributed service integration Component C Component B System A UI Service Service Service Local transaction between System B and C
  60. 60. Consequence: Availability goes down (without additional instances of each service) Service A Service B Service C Availability: 99% Availability: 99% Availability: 99% Combined availability: 97%
  61. 61. DECIDE IF YOU CAN LIVE WITH THE CONSEQUENCES OF COUPLING SERVICES TO EACH OTHER USING REQUEST/RESPONSE Different situations – different tradeoffs
  62. 62. HOW CAN WE BUILD SERVICES THAT DON’T EXPERIENCE THESE PROBLEMS?
  63. 63. GUIDANCE CAN BE FOUND IN Pat Hellands “Life Beyond Distributed Transactions? An Apostate ‘s Opinion” Link: http://www-db.cs.wisc.edu/cidr/cidr2007/papers/cidr07p15.pdf
  64. 64. Life Beyond Distributed Transactions? According to Pat Helland, we must find the solution to our problem by looking at: 1. How do we split our data / services 2. How do we identify our data 3. How do we communicate between our services
  65. 65. 1. How do we split our data / services Data must be collected in pieces called aggregates. These aggregates should be limited in size (but not smaller), so that, after a transaction they are consistent. Rule of thumb: One transaction involves only one aggregate.
  66. 66. DOMAIN DRIVEN DESIGN The term Aggregate comes from DDD
  67. 67. Aggregates Invoice InvoiceLine * Account * What: • Cluster coherent Entities and Value Objects, with complex associations into Aggregates with well defined boundaries. • Choose one entity to be root and control access to objects inside the boundary through the root. Motivation: Control invariants and consistency through the aggregate root. Enables: Loading schemes, coarse grained locking and… Ensuring consistency & transactional boundaries for Distributed scenarios Root * *
  68. 68. THE SMALLEST SERVICE Would be responsible for all logic and data related to a single Aggregate
  69. 69. WHY? Because consistency can only be guaranteed within an Aggregate It cannot span aggregates - due to lack of coordinating transactions
  70. 70. Example of bad aggregate boundaries
  71. 71. RULE OF THUMB 1 use case = 1 transaction = 1 aggregate
  72. 72. 2. How do we identify our data According to Pat Helland we need to be able to uniquely identify each Aggregate using an ID. • This ID will usually a UUID/GUID • Aggregates refer to each other by their ID • they NEVER use memory pointers, join tables or remote calls {21EC2020-3AEA-4069-A2DD-08002B30309D} 2122 (approximately 5.3×1036) combinations
  73. 73. WE STILL HAVEN’T CONQUERED THE TEMPORAL COUPLING PROBLEM
  74. 74. 3. How we communicate between our services • What do we do when our use case involves more than one aggregate and therefore likely more than one service?
  75. 75. Synchronous calls are the crystal meth of programming At first you make good progress but then the sheer horror becomes evident when you realise the scalability limitations and how the brittleness holds back both performance and development flexibility. By then it is too late to save. http://www.infoq.com/news/2014/10/thompson-reactive-manifesto-2 We need the reactive properties and then apply protocols for the message interactions. Without considering the protocols of interaction this world of micro-services will become a coordination nightmare. Martin Thompson
  76. 76. IF WE WANT TO DECOUPLE OUR SERVICES AS MUCH AS POSSIBLE THEN WE NEED TO LOOK TOWARDS COMPOSITE UI’S AND EVENTS
  77. 77. WHAT’S A COMPOSITE UI A Composite UI is a way to allow different services to participate an applications UI without revealing their internals and thereby removing the need for other services to know the this services internal data This helps us keep coupling low and encapsulation high
  78. 78. Applications and Services iOS Homebanking Call center support portal Bank Backoffice application Customer information service Legal and contract information service Accounts service Credit card service Mortgage loans service
  79. 79. Who owns the UI? • For a service to be fully autonomous is must be self contained – which means it must: • Own its UI • Own its Business Logic • Own its Data model User interface Business Logic Data model & storage Service A similar approach is available under the name Self Contained Systems http://scs-architecture.org/
  80. 80. If a Service doesn’t own its UI we often find the need for a Gateway or Backend For a Frontend (BFF) • Experience shows if you get your Service API wrong the first time around, it is really expensive to fix it* • The granularity of APIs provided by microservices is often different than what a client needs* * See http://thenewstack.io/microservices-calls-robust-api-management-tools/
  81. 81. Gateway or Backend For a Frontend (BFF) • Unfortunately Gateways & BFF’s introduce a lot of coupling between the Gateway and the underlying services • If an underlying service changes its contract in a non-backwards compatible way the gateway needs to change • In these cases the clients of the gateway may also need to change since the changes can permeate upwards (the gateway abstraction is leaky) * See http://thenewstack.io/microservices-calls-robust-api-management-tools/
  82. 82. Gateway/BFFGateway/BFF GATEWAY OR BACKEND FOR A FRONTEND UI Microservices UI-3 MS-3 UI-2 UI-4 MS-4MS-2 UI-1 UI-5 MS-5MS-1 1’s DB 2’s DB 3’s DB 4’s DB 5’s DB Gateway/BFF
  83. 83. Application UI’s • An applications is a composition of different services • The composition can be: • Resource Oriented Client Architecture (ROCA) style service integration (http://roca-style.org/) • Mashup of Service UI components in a dedicated Application – aka. Composite UI Both solutions involve integration via Services web interfaces to minimize coupling to other services. Image from http://scs-architecture.org/
  84. 84. Composite UI - example Page Context: { type: Book, id: ISBN-10 0-321-83457-7 } ImageService BookService ReviewService PriceService InventoryService OthersAlsoBoughtService PriceService ReviewService BookService ImageService BookService
  85. 85. Widget Widget Page Widget Service A Service B Service C Widget Widget Widget Service A Service B Service C Widget Service C • Overall structure of the page is “owned” by the application. • Each widget is owned and delivered by the underlying Service. Page layout
  86. 86. A SERVICE OWNS ITS UI IN ALL CONTEXTS AND FOR ALL COMPOSITE UI’S Not just for HTML clients
  87. 87. Invoice Composite UI example InvoiceHeader Order:ShippingI nfo Invoice: InvoiceNumber Invoice: Data and Due date Order: RelationInformation Order:Item- Qty Product:Ite m Product: Description Order: Item-Unit-Price Order: Item- Total- Price Order:Total Billing:Balance All Services participate at the UI level for each individual Item in the Order
  88. 88. Coupling matrix* * Modified version of Ian Robinson’s matrix: http://iansrobinson.com/2009/04/27/temporal-and-behavioural-coupling/ Behavioral coupling Temporal coupling Low High Low High Event oriented Command oriented Emergency services Distributed 3 layer
  89. 89. TO BREAK TEMPORAL COUPLING & BEHAVIORAL COUPLING SERVICES NEEDS TO COMMUNICATE ASYNCHRONOUSLY USING BUSINESS EVENTS Services communicate facts without making assumptions about what other services intend to do with the events
  90. 90. Let’s make the implicit explicit! Old wisdom seems to have been forgotten. Let’s introduce: Business/Domain Events Which: • Signal that something has happened • Closely aligned to the Domain Model • Are handled by a messaging system • They are in the past tense: • CustomerBilled • ParcelShipped • CustomerCreated • ReviewCreated • CommentAdded • CommentDeleted
  91. 91. Events are often the side effect of Commands A Command message is prescriptive of what should happen. This is a stronger form of coupling than Events. A Command’s primary goal is to capture USER INTENT A Command supports a single usecase and targets a single Aggregate Commands always carry a name in its imperative form: CreateOrder, ShipOrder, CancelOrder, ReimburseCustomer, etc. “A command describes a Task that you want someone else to carry out for you and the recipient can reject the Command”
  92. 92. Commands & Events Commands mutate Aggregate state – and if succesful – will result in one or more Events being published Command Event(s) AcceptOrder OrderAccepted ShipOrder OrderShipped AddComment CommentAdded QuarantineReview ReviewQuarantined UnquarantineReview ReviewUnquarantined
  93. 93. WE NEED TO CHANGE FOCUS FROM SHORT TECHNICAL TRANSACTIONS To long running business transactions supporting business processes
  94. 94. Using Business Events to drive Business Processes Sales Service Shipping Billing Sales Customers MessageChannel Online Ordering System Web Shop (Composite UI) Billing Service Shipping Service Order Accepted Event AcceptOrder Command The sales fulfillment processing can now begin…
  95. 95. Choreographed Event Driven Processes Sales Service Order Accepted Invoicing Service Order Fulfilment (Saga/ Process-Manager) Shipping Service Online Ordering System MessageChannel(e.g.aTopic) Order Accepted Order Accepted Customer Billed Customer Billed Order Approved Order Approved Works as a Finite State Machine (WorkFlow) handling the life cycle of Shipping and thereby forms a very central new Aggregate in the System
  96. 96. Choreography is very different from the classical orchestrated integration process
  97. 97. The INPAY approach to Microservices
  98. 98. SERVICES AT INPAY
  99. 99. Different perspectives on data With in a given Domain, e.g. Retail, there will exist multiple bounded contexts/sub-domains/business capabilities such as: • Product management • Purchase • Sales • Pricing • Inventory • Shipping • Support • Accounting • Management Each of these lines of business have very specific and unique needs which are relevant for them alone in order to conduct their business. They might use the same name for the entities they’re interested in or they might use different names for the same logical entity.
  100. 100. Many perspectives on data Online Retail System Product Unit Price Promotional Price Promotion End Date Stock Keeping Unit (SKU) Quantity On Hand (QOH) Location Code Price Quantity Ordered Name The lifecycle of the data is VERY important! Customer Pricing Inventory Sales Management Reporting
  101. 101. Smaller models & clear data ownership Retail System Pricing Product ProductID Unit Price Promotional Price … Pricing Inventory Product ProductID SKU QOH Location Code … Inventory Sales Product ProductID Name Description Quantity Ordered … Sales Shared Entity identitySOA: Service
  102. 102. Billing Product Catalogue Shipping Sales Inventory Pricing Retail domain split into a Macro architecture Usually contains more than one aggregate 
  103. 103. What’s a macro architecture • It’s the static/stable(r) parts of your architecture • Which are very costly to refactor and change • Business capabilities are stable • Therefore we should strive to align services with business capabilities / bounded contexts (DDD)
  104. 104. Service and Business Capability alignment “The advantage of business capabilities is their remarkable level of stability. If we take a typical insurance organisation, it will likely have sales, marketing, policy administration, claims management, risk assessment, billing, payments, customer service, human resource management, rate management, document management, channel management, commissions management, compliance, IT support and human task management capabilities. In fact, any insurance organisation will very likely have many of these capabilities.” See http://bill-poole.blogspot.dk/2008/07/business- capabilities.html
  105. 105. A Service is • The technical authority for a given business capability • It is the owner of all the data and business rules that support this business capability – everywhere (including the UI) • It forms a single source of truth for that capability • This form of business and IT alignment ensures that we can maintain service Autonomy & Encapsulation
  106. 106. Services/Business-capabilities in INPAY Currency Service Finance Service Banking Service Identity Management Service Sales Service PSP Service 3rd party Providers Service Virtual Banking Service IT Operations
  107. 107. Applications in INPAY Identity Management Application Contract Manager Application Treasury Application Compliance Application Operations Application CRM PSP Gateway PSP Merchant Application ERP
  108. 108. Services, Applications and code • Each Service and Application is maintained in separate Git repositories • Common IT Operations libraries and infrastructure are maintained in other separate Git repositories
  109. 109. So what’s inside a Service source repository? • Autonomous Components • Libraries • Adapters • Front-end UI components • API contracts (mainly Events) • DB Schemas • Build file(s)
  110. 110. Autonomous Components?
  111. 111. Service and deployment • A Service represents a logical responsibility boundary • Logical responsibility and physical deployment of a Service DOES NOT have to be 1-to-1 • It’s too constraining • We need more degrees of freedom • Philippe Krutchen 4+1 views of architecture: Logical and Physical designs should be independent of each other A service needs to be deployed everywhere its data is needed
  112. 112. Service deployment • Many services can be deployed to the same physical server • Many services can be deployed in the same application • Application boundary is a Process boundary which is a physical boundary • A Service is a logical boundary • Service deployment is not restricted to tiers either • Part of service A and B can be deployed to the Web tier • Another part of Service A and B can be deployed to the backend/app-service tier of the same application • The same service can be deployed to multiple tiers / multiple applications • ie. applications and services are not the same and does not share the same boundaries • Multiple services can be “deployed” to the same UI page (service mashup) • Multiple services can cooperate to fulfill a larger use-case (e.g. a workflow or a business process)
  113. 113. Service Autonomous Component 1..* Is implemented by A Service is the technical authority of a specific Business Capability e.g. Sales, Shipping, Billing Services support business processes. Business processes naturally span multiple services, but there will always be a single service that is the actual authority on the business process. Service vs Autonomous Components
  114. 114. Also known as Microservices Service Autonomous Component 1..* Is implemented by Service vs Autonomous Components Autonomous-Components/Microservices are a division of Services along Transactional boundaries (a transaction stays within the boundary of a Microservice) Microservices are the individually logical deployable units of a Service with their own Endpoints. Could e.g. be the split between Read and Write models (CQRS) - each would be their own Microservice
  115. 115. Services are the corner stone • We talk in terms of Services/business capabilities and the processes/use- cases they support • Autonomous-Components/Microservices are an implementation detail • They are much less stable (which is a good thing – it means they’re easier to replace) • With regards to other Services • subscribe to events from • send commands to (less common) • call operations (in rare occasions)
  116. 116. Services/Bounded Contexts and Aggregates Sales Service PSP ServiceVirtual Banking Service Finance Service Customer customerId … Contract contractId customerId … VBFeeSchedule contractId … PSPFeeSchedule contractId … BillingTemplate contractId …
  117. 117. INPAY Autonomous Component design principles
  118. 118. Commands and Events Events Identifiers Commands
  119. 119. Commands and Events public class RegisterBankCmd extends AbstractCommand { @TargetAggregateIdentifier public final BankId bankId; public final String name; public final Country countryOfOperation; public RegisterBankCmd(BankId bankId, String name, Country countryOfOperation) { Objects.requireNonNull(bankId, "bankId"); Objects.requireNonNull(name, "name"); Objects.requireNonNull(countryOfOperation, "countryOfOperation"); this.bankId = bankId; this.name = name; this.countryOfOperation = countryOfOperation; } }
  120. 120. Commands and Events The generic business event interface includes the name of the topic that subscribers must use public class BankRegistered extends AbstractEvent implements BankEvent { @AggregateIdentifier public final BankId bankId; public final String name; public final Country countryOfOperation; public BankCreated(BankId bankId, String name, Country countryOfOperation) { this.bankId = bankId; this.name = name; this.countryOfOperation = countryOfOperation; } } public interface BankEvent extends Serializable { TopicName TOPIC_NAME = BankingServiceId.ID.topicName("bank-events"); }
  121. 121. CQRS A single model cannot be appropriate for reporting, searching and transactional behavior Greg Young, 2008
  122. 122. Commands, Events and Query Models Read model Read model Events UI Domain modelQuery/Read model ”AcceptOrder” command ”OrderAccepted” event ”Find all Accepted Orders” Query Commands are Imperative: DoStuff Events are Past tense: StuffDone
  123. 123. Event Sourcing Aggregates track their own Domain Events and derive state from them Time 07:39 Time 07:40 Time 07:41 Time 07:45 Time 07:46 Time 07:50
  124. 124. Full CQRS With EventSourcing UI Domain Event Store (can e.g. be a real EventStore DB or a Relational DB) Commands – Change data Commands Events SQL DB Document DB Graph DB UI Data Queries – Ask for data Events Query Build Our single source of truth
  125. 125. Aggregate public class Bank extends InPayEventSourcedAggregate { @AggregateIdentifier private BankId bankId; @EventSourcedMember private Map<BankAccountId, BankAccount> bankAccounts = new HashMap<>(); public Bank(BankId bankId, String name, Country countryOfOperation) { apply(new BankRegistered(bankId, name, countryOfOperation)); } public void addBankAccount(BankAccountId bankAccountId, …) { if (!bankAccounts.containsKey(bankAccountId)) { apply(new BankAccountAdded(bankId, bankAccountId, …)); } } @EventSourcingHandler private void on(BankRegistered e) { bankId = e.getBankId(); } @EventSourcingHandler private void on(BankAccountAdded e) { BankAccount bankAccount = bankAccounts.put(e.getBankAccountId(), new BankAccount(e.getBankId(), e.getBankAccountId(), …)); } }
  126. 126. Service project structure sales_service sales_api sales_contract_ac sales_customer_ac frontend sales_contract_manager_adapters contract adapters sales/modules customer psp_service psp_api psp_fees_ac … frontend psp_contract_manager_adapters fees adapters psp/modules fx Legend: Service/Business-Capability External Event/Command Contracts Autonomous Component Autonomous Component Adapter Angular.js Module Builds into a Java JAR Uses Spring MVC/REST All Java 8 artifacts are built using Gradle
  127. 127. Autonomous Component Library • Can be deployed alone or co-located • Usually deployed together with one or more adapters • Works transparently in a clustered environment • Completely Spring free  • Only depends on our Core infrastructure library • Common types and Id’s • Bus infrastructure • Service lookup • CQRS building blocks (backed by Axon framework)
  128. 128. Client handled subscriptions • Highly resilient pattern for an Event Driven Architecture that’s backed by AC’s that use EventSourcing. • In this model the publisher of the Events is responsible for the durability of all its Events, typically to an EventStore/EventLog. • Each client (subscriber) maintains durable information of the last event it received from each publisher. • When ever the client starts up it makes a subscription to the publisher where it states from which point in time it wants events published. • This effectively means that publisher can remain simple and the client (subscriber) can remain simple and we don’t need additional sophisticated broker infrastructure such as Kafka+ZooKeeper.
  129. 129. Infrastructure 129
  130. 130. Client handled subscriptions Publisher Subscriber A Local storage EventStore Subscriber B Local storage Topic Subscription Topic Subscription TopicSubscriptionHandler TopicSubscriptionHandler EventEvent Event Event EventBus Event Event
  131. 131. psp_fees_ac (deployed on 10.25.26.102) psp_fees_ac (deployed on 10.25.26.101) Bus Bus Bus Bus sales_contract_ac (deployed on 10.25.26.104) sales_contract_ac (deployed on 10.25.26.103) Federated Bus
  132. 132. Distributed Bus Topic Queue Topic Publisher side Topic Subscriber side Queue Sender side Queue Receiver side Local Topic Publisher Local Topic Subscriber Local Queue Sender Local Queue Receiver Distributed per Service EventBus Local Topic Subscriber Local Topic Subscriber Local Queue Sender Distributed Notifications Distributed Broadcast Distributed SingleInstance Task
  133. 133. Applications
  134. 134. AUTONOMOUS-COMPONENTS/ MICROSERVICES ARE LOGICAL DEPLOYABLE UNITS That doesn’t mean they HAVE to be deployed individually. Design for Distribution But take advantage of locality
  135. 135. Logical Architecture Building Blocks
  136. 136. Autonomous Components can be co-deployed together with Application backends contract_manager (Spring Boot fat–jar) sales_contract_ac sales_customer_ac sales_contract_manager_adapters psp_api psp_fees_ac psp_contract_manager_adapters frontend sales_api app libs contract customer fees
  137. 137. Application in code @Configuration @ComponentScan(basePackages = { "com.inpay.contractmanager", "com.inpay.adapters", "com.inpay.itops.spring" }) public class Application extends InpaySpringBootApplication { public Application() { super(); } @Override protected String getApplicationName() { return "ContractManager"; } @Override protected Collection<AutonomousComponent> getAutonomousComponentsHostedInThisApplication() { CurrencyExchangeRateAc currencyExchangeRateAc = new CurrencyExchangeRateAc(); return list( new IDMCoreAc(), new PSPFeeScheduleAc(currencyExchangeRateAc.getCurrencyConverter()), new VBFeeScheduleAc(currencyExchangeRateAc.getCurrencyConverter()), new ContractAc(), new CustomersAc(), currencyExchangeRateAc ); } public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
  138. 138. AC in code public class PSPAgreementAc extends HzBackedAutonomousComponent { public static AutonomousComponentId SERVICE_AC_ID = PSP_SERVICE_ID.ac("psp_agreement_ac"); … public PSPAgreementAc(CurrencyConverter currencyConverter) { this.currencyConverter = currencyConverter; } @Override public void onInitialize(IConfigureACEnvironment acSetup) { acSetup.withAutonomousComponentId(SERVICE_AC_ID).usingServiceDataSource() .withBusConfiguration(cfg -> { cfg.getAxonContext() .subscribeAnnotatedCommandHandler(new TemplateCmdHandler( cfg.getAxonContext().eventSourcedRepository(PSPTemplate.class), currencyConverter)); …. manageLifecycleFor(templateViewRepository = new TemplateViewRepository(cfg, currencyConverter)); }) .runOnBusStartup((bus, axonContext) -> { bus.registerAxonReplayableTopicPublisher(InternalTemplateEvents.TOPIC_NAME, replayFromAggregate(PSPTemplate.class) .dispatchAggregateEventsOfType(InternalTemplateEvents.class)); bus.subscribeTopic(SERVICE_AC_ID.topicSubscriber("ContractEvents"), ExternalContractEvents.TOPIC_NAME, new SalesTopicSubscription(bus)); }); } public TemplateViewRepository getTemplateViewRepository() { return templateViewRepository; } }
  139. 139. AC, autonomy and “shared” service data Service DB DB Autonomous Component Autonomous Component Autonomous Component Autonomous Component DB
  140. 140. 50 shades of inter service AC Autonomy* Endpoint Process Database Storage Shared Shared Shared Shared Own Shared Shared Shared Own Own Shared Shared Own Shared Own Shared Own Own Own Shared Own Own Own Own Lower Autonomy Higher Autonomy * No RPC in use!
  141. 141. Thanks :)

×