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.

O'Reilly SA NYC 2018: Complex event flows in distributed systems

524 views

Published on

Slides from my talk at O'Reilly Software Architecture Conference in New York City on 28th of February 2018. Code from the demo is available: http://github.com/flowing/flowing-retail

Published in: Technology
  • Be the first to comment

O'Reilly SA NYC 2018: Complex event flows in distributed systems

  1. 1. Complex event flows in distributed systems @berndruecker With thoughts from http://flowing.io @berndruecker | @martinschimak
  2. 2. 3 common hypotheses I check today: # Events decrease coupling # Orchestration needs to be avoided # Workflow engines are painful
  3. 3. Berlin, Germany bernd.ruecker@camunda.com @berndruecker Bernd Ruecker Co-founder and Developer Advocate of Camunda
  4. 4. Simplified example: dash button Photo by 0xF2, available under Creative Commons BY-ND 2.0 license. https://www.flickr.com/photos/0xf2/29873149904/
  5. 5. Three steps…
  6. 6. Who is involved? Some bounded contexts… Checkout Payment Inventory Shipment
  7. 7. (Micro-)services Checkout Payment Inventory Shipment
  8. 8. Autonomous (micro-)services Checkout Payment Inventory Shipment Dedicated Application Processes Dedicated infrastructure Dedicated Development Teams
  9. 9. Events decrease coupling
  10. 10. Example Checkout Payment Inventory Shipment The button blinks if we can ship within 24 hours
  11. 11. Request/response: temporal coupling Checkout Payment Inventory Shipment Request Response The button blinks if we can ship within 24 hours
  12. 12. Temporal decoupling with events and read models Checkout Payment Inventory Shipment Good Stored Read Model Good Fetched The button blinks if we can ship within 24 hours *Events are facts about what happened (in the past)
  13. 13. Events can decrease coupling* *e.g. decentral data-management, read models, extract cross-cutting aspects
  14. 14. Peer-to-peer event chains Checkout Payment Inventory Shipment Order placed Payment received Goods shipped Goods fetched
  15. 15. Peer-to-peer event chains Checkout Payment Inventory Shipment Order placed Payment received Goods shipped Goods fetched
  16. 16. The danger is that it's very easy to make nicely decoupled systems with event notification, without realizing that you're losing sight of that larger-scale flow, and thus set yourself up for trouble in future years. https://martinfowler.com/articles/201701-event-driven.html
  17. 17. The danger is that it's very easy to make nicely decoupled systems with event notification, without realizing that you're losing sight of that larger-scale flow, and thus set yourself up for trouble in future years. https://martinfowler.com/articles/201701-event-driven.html
  18. 18. The danger is that it's very easy to make nicely decoupled systems with event notification, without realizing that you're losing sight of that larger-scale flow, and thus set yourself up for trouble in future years. https://martinfowler.com/articles/201701-event-driven.html
  19. 19. Peer-to-peer event chains Checkout Payment Inventory Shipment Order placed Payment received Goods shipped Goods fetched Fetch the goods before the payment
  20. 20. Peer-to-peer event chains Checkout Payment Inventory Shipment Fetch the goods before the payment Goods fetched Order placed Payment received Goods shipped
  21. 21. Peer-to-peer event chains Checkout Payment Inventory Shipment Fetch the goods before the payment Customers can pay via invoice Goods fetched Order placed Payment received Goods shipped …
  22. 22. Photo by born1945, available under Creative Commons BY 2.0 license.
  23. 23. Order Extract the end-to-end responsibility Checkout Payment Inventory Shipment *Commands have an intent about what needs to happen in the future Order placed Payment received Retrieve payment
  24. 24. Commands help to avoid (complex) peer-to-peer event chains
  25. 25. Orchestration needs to be avoided
  26. 26. Smart ESB-like middleware Checkout Payment Inventory Shipment Order Order placed Payment received Good fetched Good shipped
  27. 27. Dumb pipes Checkout Payment Inventory Shipment Order Smart endpoints and dumb pipes Martin Fowler
  28. 28. Danger of god services? Checkout Order A few smart god services tell anemic CRUD services what to do Sam Newmann Payment Inventory Shipment
  29. 29. Danger of god services? Checkout Payment Inventory Shipment Order A few smart god services tell anemic CRUD services what to do Sam Newmann
  30. 30. A god service is only created by bad API design!
  31. 31. Example Order Payment Retrieve Payment
  32. 32. Example Order Payment Credit Card Retrieve Payment
  33. 33. Example Order Payment Credit Card Retrieve Payment Rejected
  34. 34. Example Order Payment Client of dumb endpoints easily become a god services. If the credit card was rejected, the customer can provide new details Credit Card Retrieve Payment Rejected Rejected
  35. 35. Payment failed Who is responsible to deal with problems? Order Payment If the credit card was rejected, the customer can provide new details Credit Card Retrieve Payment Rejected Payment received
  36. 36. Payment failed Who is responsible to deal with problems? Order Payment Clients of smart endpoints remains lean. If the credit card was rejected, the customer can provide new details Credit Card Retrieve Payment Rejected Payment received Smart endpoints are potentially long-running
  37. 37. Photo by Tookapic, available under Creative Commons CC0 1.0 license.
  38. 38. „There was an error while sending your boarding pass“
  39. 39. Check-in Web-UI Me Current situation
  40. 40. Check-in Barcode Generator Web-UI Me Output Mgmt Current situation
  41. 41. Check-in Barcode Generator Web-UI Me Output Mgmt Current situation
  42. 42. Check-in Barcode Generator Web-UI Me Output Mgmt Current situation – the bad part
  43. 43. Check-in Barcode Generator Web-UI Me Output Mgmt Current situation – the bad part Stateful Retry
  44. 44. We are having some technical difficulties and cannot present you your boarding pass right away. But we do actively retry ourselves, so lean back, relax and we will send it on time.
  45. 45. Check-in Barcode Generator Web-UI Me Output Mgmt Possible situation – much better!
  46. 46. Check-in Barcode Generator Web-UI Me Output Mgmt Possible situation – much better! Stateful Retry
  47. 47. Check-in Barcode Generator Web-UI Me Output Mgmt Stateful Retry Possible situation – much better! The failure never leaves this scope!
  48. 48. Persist thing (Entity, Actor, …) State machine or workflow engine Typical concerns DIY = effort, accidental complexity Scheduling, Versioning, operating, visibility, scalability, … Handling State
  49. 49. Workflow engines are painful Complex, proprietary, heavyweight, central, developer adverse, …
  50. 50. Avoid the wrong tools! Death by properties panel Low-code is great! (You can get rid of your developers!) Complex, proprietary, heavyweight, central, developer adverse, …
  51. 51. Workflow engines, state machines It is relevant in modern architectures
  52. 52. CADENCE Silicon valley has recognized Workflow engines, state machines
  53. 53. CADENCE Workflow engines, state machines
  54. 54. CADENCE also at scale Workflow engines, state machines
  55. 55. CADENCE for todays demo Workflow engines, state machines
  56. 56. public static void main(String[] args) { ProcessEngine engine = new StandaloneInMemProcessEngineConfiguration() .buildProcessEngine(); engine.getRepositoryService().createDeployment() // .addModelInstance("flow.bpmn", Bpmn.createExecutableProcess("flow") // .startEvent() .serviceTask("Step1").camundaClass(SysoutDelegate.class) .serviceTask("Step2").camundaClass(SysoutDelegate.class) .endEvent() .done() ).deploy(); engine.getRuntimeService().startProcessInstanceByKey( "flow", Variables.putValue("city", "New York")); } public class SysoutDelegate implements JavaDelegate { public void execute(DelegateExecution execution) throws Exception { System.out.println("Hello " + execution.getVariable("city")); } } What do I mean by „leightweight?“
  57. 57. public static void main(String[] args) { ProcessEngine engine = new StandaloneInMemProcessEngineConfiguration() .buildProcessEngine(); engine.getRepositoryService().createDeployment() // .addModelInstance("flow.bpmn", Bpmn.createExecutableProcess("flow") // .startEvent() .serviceTask("Step1").camundaClass(SysoutDelegate.class) .serviceTask("Step2").camundaClass(SysoutDelegate.class) .endEvent() .done() ).deploy(); engine.getRuntimeService().startProcessInstanceByKey( "flow", Variables.putValue("city", "New York")); } public class SysoutDelegate implements JavaDelegate { public void execute(DelegateExecution execution) throws Exception { System.out.println("Hello " + execution.getVariable("city")); } } Build engine in one line of code (using in- memory H2)
  58. 58. public static void main(String[] args) { ProcessEngine engine = new StandaloneInMemProcessEngineConfiguration() .buildProcessEngine(); engine.getRepositoryService().createDeployment() // .addModelInstance("flow.bpmn", Bpmn.createExecutableProcess("flow") .startEvent() .serviceTask("Step1").camundaClass(SysoutDelegate.class) .serviceTask("Step2").camundaClass(SysoutDelegate.class) .endEvent() .done() ).deploy(); engine.getRuntimeService().startProcessInstanceByKey( "flow", Variables.putValue("city", "New York")); } public class SysoutDelegate implements JavaDelegate { public void execute(DelegateExecution execution) throws Exception { System.out.println("Hello " + execution.getVariable("city")); } } Define flow e.g. in Java DSL
  59. 59. public static void main(String[] args) { ProcessEngine engine = new StandaloneInMemProcessEngineConfiguration() .buildProcessEngine(); engine.getRepositoryService().createDeployment() // .addModelInstance("flow.bpmn", Bpmn.createExecutableProcess("flow") .startEvent() .serviceTask("Step1").camundaClass(SysoutDelegate.class) .serviceTask("Step2").camundaClass(SysoutDelegate.class) .endEvent() .done() ).deploy(); engine.getRuntimeService().startProcessInstanceByKey( "flow", Variables.putValue("city", "New York")); } public class SysoutDelegate implements JavaDelegate { public void execute(DelegateExecution execution) throws Exception { System.out.println("Hello " + execution.getVariable("city")); } } Define flow e.g. in Java DSL
  60. 60. BPMN Business Process Model and Notation ISO Standard
  61. 61. public static void main(String[] args) { ProcessEngine engine = new StandaloneInMemProcessEngineConfiguration() .buildProcessEngine(); engine.getRepositoryService().createDeployment() // .addModelInstance("flow.bpmn", Bpmn.createExecutableProcess("flow") .startEvent() .serviceTask("Step1").camundaClass(SysoutDelegate.class) .serviceTask("Step2").camundaClass(SysoutDelegate.class) .endEvent() .done() ).deploy(); engine.getRuntimeService().startProcessInstanceByKey( "flow", Variables.putValue("city", "New York")); } public class SysoutDelegate implements JavaDelegate { public void execute(DelegateExecution execution) throws Exception { System.out.println("Hello " + execution.getVariable("city")); } } We can attach code…
  62. 62. public static void main(String[] args) { ProcessEngine engine = new StandaloneInMemProcessEngineConfiguration() .buildProcessEngine(); engine.getRepositoryService().createDeployment() // .addModelInstance("flow.bpmn", Bpmn.createExecutableProcess("flow") .startEvent() .serviceTask("Step1").camundaClass(SysoutDelegate.class) .serviceTask("Step2").camundaClass(SysoutDelegate.class) .endEvent() .done() ).deploy(); engine.getRuntimeService().startProcessInstanceByKey( "flow", Variables.putValue("city", "New York")); } public class SysoutDelegate implements JavaDelegate { public void execute(DelegateExecution execution) throws Exception { System.out.println("Hello " + execution.getVariable("city")); } } …that is called when workflow instances pass through
  63. 63. public static void main(String[] args) { ProcessEngine engine = new StandaloneInMemProcessEngineConfiguration() .buildProcessEngine(); engine.getRepositoryService().createDeployment() // .addModelInstance("flow.bpmn", Bpmn.createExecutableProcess("flow") .startEvent() .serviceTask("Step1").camundaClass(SysoutDelegate.class) .serviceTask("Step2").camundaClass(SysoutDelegate.class) .endEvent() .done() ).deploy(); engine.getRuntimeService().startProcessInstanceByKey( "flow", Variables.putValue("city", "New York")); } public class SysoutDelegate implements JavaDelegate { public void execute(DelegateExecution execution) throws Exception { System.out.println("Hello " + execution.getVariable("city")); } } Start instances
  64. 64. Payment Now you have a state machine!
  65. 65. Payment Easy to handle time
  66. 66. Stateful retries Payment Credit Card REST
  67. 67. Fallbacks increase resilience Payment Credit Card REST
  68. 68. Distributed systems
  69. 69. It is impossible to differentiate certain failure scenarios. Independant of communication style! Service Provider Client
  70. 70. Distributed systems introduce complexity you have to tackle! Credit Card Payment REST
  71. 71. Distributed systems introduce complexity you have to tackle! Credit Card Payment REST
  72. 72. Distributed systems
  73. 73. Distributed transaction with compensations*
  74. 74. Living documentation for long-running behaviour
  75. 75. Visual HTML reports for test cases
  76. 76. Proper Operations Visibility + Context
  77. 77. Before mapping processes explicitly with BPMN, the truth was buried in the code and nobody knew what was going on. Jimmy Floyd, 24 Hour Fitnesse „
  78. 78. Workflows live inside service boundaries
  79. 79. Explicit flows help separate domain and infrastructure Infrastructure Aggregates, Domain Events, Domain Services, etc … + the flow Workflow Engine Payment Application Domain
  80. 80. Manigfold architecture options https://blog.bernd-ruecker.com/architecture-options-to-run-a-workflow-engine-6c2419902d91
  81. 81. Manigfold architecture options https://blog.bernd-ruecker.com/architecture-options-to-run-a-workflow-engine-6c2419902d91
  82. 82. Manigfold architecture options https://blog.bernd-ruecker.com/architecture-options-to-run-a-workflow-engine-6c2419902d91
  83. 83. Manigfold architecture options https://blog.bernd-ruecker.com/architecture-options-to-run-a-workflow-engine-6c2419902d91
  84. 84. … Manigfold architecture options https://blog.bernd-ruecker.com/architecture-options-to-run-a-workflow-engine-6c2419902d91
  85. 85. Lightweight workflow engines are great – don‘t DIY* *e.g. enabling potentially long-running services, solving hard developer problems, can run decentralized
  86. 86. Zalando Sales-Order and Order-Fulfillment via Camunda for every order worldwide Orders Q2-2017: 22,2 Mio. Sales 2016: 3,6 Mrd. EUR Growth 2016: 23%
  87. 87. Code example & live demo InventoryPaymentOrder ShippingCheckout Monitor https://github.com/flowing/flowing-retail/ Human Tasks H2 H2
  88. 88. # Events decrease coupling: sometimes read-models, but no complex peer-to-peer event chains! # Orchestration needs to be avoided: sometimes no ESB, smart endpoints/dumb pipes, important capabilities need a home # Workflow engines are painful: some of them lightweight engines are easy to use and can run decentralized, they solve hard developer problems, don‘t DIY
  89. 89. Thank you! Meet me at Meet the experts Now!
  90. 90. bernd.ruecker@camunda.com @berndruecker https://bernd-ruecker.com https://blog.bernd-ruecker.com https://github.com/flowing https://www.infoq.com/articles/ events-workflow-automation With thoughts from http://flowing.io @berndruecker | @martinschimak Contact: Slides: Blog: Code: https://www.infoworld.com/article/3254777/ application-development/ 3-common-pitfalls-of-microservices- integrationand-how-to-avoid-them.html

×