Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The Crumbling Monolith

The Crumbling Monolith

Identifying and separating orthogonal concerns in your web application to enable development agility, scalability, maintainability, and resilience.

Joe R. Smith

May 19, 2017
Tweet

More Decks by Joe R. Smith

Other Decks in Programming

Transcript

  1. The Crumbling Monolith Iden&fying and separa&ng orthogonal concerns in your

    web applica&on to enable development agility, scalability, maintainability, and resilience Joe R. Smith, Nebraska.Code() 2017
  2. What is a webapp? • Not a sta&c website •

    Rich user interac&on and state • Analogous to mobile or desktop applica&ons, but deployed over the web • Wikipedia is a website • Webapps: Online banking, Webmail, AWS console
  3. What is a monolithic web applica&on? • Tight coupling of

    client, server, and other services over a network, usually server-side web-apps • Tradi&onal synchronous HTTP request/response • User interac&on and state change oXen modeled through successive page loads • Each client session stored on a single server instance (many to 1 client->server rela&onship) • Usually li[le or no client-side state
  4. Assumes end-to-end control • The client-side is treated as an

    extension of the server-side, not (logically) as a separate process • Stop the world state seman&cs • Inten&onally hides the distributed nature of the applica&on
  5. Garden-variety monolith Synchronous network Asynchronous network In-process Web Application Server

    Request Response Client (web browser) Client (web browser) Client (web browser) Render target (DOM) Server process Model Controller Routing Views Auth Session
  6. Synchronous network Asynchronous network In-process Web Application Server Request Response

    Client (web browser) Client (web browser) Client (web browser) Render target (DOM) Server process Model Controller Routing Views Auth Session WS JS AJAX Garden-variety monolith
  7. Illusion of simplicity • Considering these can be hard: •

    concurrent resource access • mul&ple processes / interfaces • dataflow • client and server-side data-modeling and state
  8. • Monoliths maintain the illusion of a single thread of

    execu&on • Easy (if not simple) • e.g., rails new is easy. Up and running in minutes! • Monoliths necessarily are opinionated about their components Illusion of simplicity
  9. Implica&on Bias • Developers and development managers fear being implicated

    in the architecture of systems • Monolithic frameworks largely internalize the applica&on and deployment architecture • Failure is then the framework's fault • and, of course, you used the "industry standard" app framework, database, etc.
  10. Discoun&ng the future • We dispropor&onally value the &me/effort saved

    at the beginning of a project You waste weeks when refusing to waste hours
  11. User Experience • Responsiveness >> Absolute performance • Synchronous request/response

    cycles put app responsiveness at the mercy of network latency and server load (e.g., other users) • What's the mean-&me to "user thinks it's broken"? • Monoliths oXen force tradeoffs between responsiveness and throughput* • Server-rendered UI less responsive (aXer ini&al load)
  12. • Responsiveness and tail latency • Webapp interac&ons consist of

    hundreds or thousands of request/response cycles. • Users no&ce that 1 slow request in 10 or 100 • 90-99th percen&le tail latency s&ll translates into a user experiencing frustra&ng levels of lag • Can you stay sub-100ms? User Experience
  13. User Experience • Intermi[ent server/network failure oXen leads to dispropor&onate

    user anger • Filling out forms and losing work on submit • Even worse for mul&-page workflows • Manual/explicit retry oXen required
  14. Fragility • Tightly coupled client and server means: server failure

    = client failure • Likewise for: • Authen&ca&on mechanism, database, etc failure • Failover/HA, scalability more complex • Poor resilience in the face of intermi[ent connec&vity, high load/thro[ling, etc
  15. Monolith High Availability Web Application Server Request Response Client (web

    browser) Client (web browser) Client (web browser) Render target (DOM) Server process Model Controller Routing Views Auth Session WS JS AJAX
  16. Monolith High Availability Web Application Server Request Response Client (web

    browser) Client (web browser) Client (web browser) Render target (DOM) Server process Model Controller Routing Views Auth Session WS JS AJAX
  17. Monolith Horizontally Scaled Client (web browser) Client (web browser) Client

    (web browser) Render target (DOM) Load balancer w/ client->server affinity Web Application Server Request Response Server process Model Controller Routing Views Auth Session Client (web browser) Client (web browser) Client (web browser) Client (web browser)
  18. Cost • Agility • New feature development is a full-stack

    endeavor • Deployment requires whole-system down&me • Maintainability • The scope of integra&ng upstream updates (e.g., new version of app framework, database library, etc) is oXen much larger • Discourages regular maintenance, bug fixes • Rollback?
  19. What is Simple? • Simple is not complex • Types

    of complexity • Inherent complexity: inherent to the problem • Incidental complexity: accidental, arising from naive or subop&mal implementa&on (you can control this)
  20. What is Simple? • Major source of incidental complexity is

    confla&ng/ combining orthogonal/independent concerns • We'll call this "complec&ng" orthogonal concerns • Complect: literally, "interleave, entwine, braid"; • Antonym: Simplex • Simple Made Easy (Rich Hickey, 2011) • Decomplect: To make simple by separa&ng orthogonal concerns
  21. Microservices • Micro-service architectures are not the opposite of monolithic

    architectures, per se • It's easy to design a micro service architecture that has all of the shortcomings of a monolith • The tradeoffs are not zero-sum: • One, poten&ally, recognizes you're building a distributed system • The other a[empts to hide the fact
  22. Microservices • Don't simply split up a monolith on service

    boundaries defined by the domain or user interac&ons (e.g., billing vs. shipping) • At best you're building several standalone monoliths. • At worst, you're duplica&ng sources of truth and needlessly separa&ng dependencies, over a network.
  23. Microservices • Decomplect along dependency boundaries • Iden&fy dependencies between

    components and ac&ons • Ask how they affect scalability, resilience, etc. • Can they be decoupled by modifying the architecture? • Decomplec&ng reduces architectural constraints
  24. Distributed Systems • Distributed systems follow all the same laws

    of physics that you are subject to and those are your only real limita&ons. Respect them
  25. Time and State • Axioms • Time flows linearly in

    one direc&on • The world exists as a series of discrete, ordered states • The past is immutable • You cannot know the state of another process/ system instantaneously
  26. Time and State • Consequences • There is no such

    thing as sharing current data, only the possibility of sharing consistent data • Current only exists on a single machine, on a single core, within a single thread • Or, you stop the world to emulate this
  27. Time and State • Corollary: There is no such thing

    as stale data if it is part of a historical state (e.g., versioned/ &mestamped). • If consistency is a requirement for some datasource, then you need: • A single Source of Truth • Linearized writes
  28. Client and server Client Webapp Client Webapp Client Webapp App

    State Render target (DOM) Engine Web Application Server Server process Demand API Demand query (e.g., GraphQL) Auth Session View Components Synchronous network Asynchronous network In-process Queue
  29. Client Webapp Client Webapp Client Webapp App State Render target

    (DOM) Engine Web Application Server Server process Demand API Demand query (e.g., GraphQL) Auth Session View Components Responsiveness • Moves presenta&on data and code closer to user • Immediate UI feedback • Decouples client UI responsiveness from server throughput • Op&mis&c client-side updates
  30. Client Webapp Client Webapp Client Webapp App State Render target

    (DOM) Engine Web Application Server Server process Demand API Demand query (e.g., GraphQL) Auth Session View Components Resilience • Resilience to server failure or intermi[ent connec&vity • Client-side data integrity • Retry (implicitly or explicitly with no loss of client-side data) • Stateless sessions • Reconnect to any server • Flexible load balancing • Transparent HA failover
  31. Client Webapp Client Webapp Client Webapp App State Render target

    (DOM) Engine Web Application Server Server process Demand API Demand query (e.g., GraphQL) Auth Session View Components Scalability • Horizontal client scalability at n = number of clients • Less server load • CDN-hosted client • Stateless sessions • Simplifies horizontal scaling • again, removing client/server affinity • Ephemeral webserver instances
  32. Client Webapp Client Webapp Client Webapp App State Render target

    (DOM) Engine Web Application Server Server process Demand API Demand query (e.g., GraphQL) Auth Session View Components Agility • Demand API allows client to define what they get (e.g., GraphQL) • Single query, many resources • Implicit consistency guarantee* • Each client can talk to poten&ally several services
  33. Orthogonal services Synchronous network Asynchronous network In-process Queue Auth Service

    Client Webapp Client Webapp Client Webapp App State Render target (DOM) Engine Web Application Server Server process Demand API View Components Session Get auth-token Other e.g., Analytics Demand query (e.g., GraphQL) w/ Auth token
  34. Auth Service Client Webapp Client Webapp Client Webapp App State

    Render target (DOM) Engine Web Application Server Server process Demand API View Components Session Get auth-token Other e.g., Analytics Demand query (e.g., GraphQL) w/ Auth token Decomplec&ng Auth • Token-based Auth service • If auth goes down, authen&cated users can con&nue using the system • Servers can independently verify a user's authen&ca&on • Stateless • Servers responsible for resource authoriza&on only
  35. Auth Service Client Webapp Client Webapp Client Webapp App State

    Render target (DOM) Engine Web Application Server Server process Demand API View Components Session Get auth-token Other e.g., Analytics Demand query (e.g., GraphQL) w/ Auth token Other services • Auth token can be used to authen&cate against other services, too • e.g., analy&cs service • Separa&ng services separates failure
  36. Dataflow Synchronous network Asynchronous network In-process Queue Auth Service Client

    Webapp Client Webapp Client Webapp App State Render target (DOM) Engine Web Application Server Server process View Components Session API Other e.g., Analytics Events REST API Server-sent event data sideloading Demand API Server-sent event registration
  37. Auth Service Client Webapp Client Webapp Client Webapp App State

    Render target (DOM) Engine Web Application Server Server process View Components Session API Other e.g., Analytics Events REST API Server-sent event data sideloading Demand API Server-sent event registration Propaga&ng change • Upda&ng clients • client -> server data changes pushed to other clients • can be versioned, &ed to a transac&on, etc. • Server Sent Events (SSE) • One-way • Loose coupling • automa&c reconnect to any server
  38. Dataflow + Synchronous network Asynchronous network In-process Queue Data Server

    Web Application Server Web Application Server Auth Service Client Webapp Client Webapp Client Webapp App State Render target (DOM) Engine Web Application Server Server process View Components Session API Other e.g., Analytics Events REST API Server-sent event data sideloading Demand API TX-stream Load balancer
  39. Data Server Web Application Server Web Application Server Auth Service

    Client Webapp Client Webapp Client Webapp App State Render target (DOM) Engine Web Application Server Server process View Components Session API Other e.g., Analytics Events REST API Server-sent event data sideloading Demand API TX-stream Load balancer Dataflow, scaled • Mul&ple webservers • Data server • Source of truth • Webservers have transac&on ledger streamed to them • Relevant clients, regardless of what server+SSE connec&on, get pushed updates
  40. Data Server Web Application Server Web Application Server Auth Service

    Client Webapp Client Webapp Client Webapp App State Render target (DOM) Engine Web Application Server Server process View Components Session API Other e.g., Analytics Events REST API Server-sent event data sideloading Demand API TX-stream Load balancer To infinity? • Dealing with database load • Is consistency important? ACID, in general? • (hint: yeah, probably) • Remember back to "Time and State" axioms • What can we decomplect? • First, what does a database server do?
  41. Tradi&onal rela&onal database • ACID seman&cs • Query, indexing, transac&ons,

    I/O, and storage all colocated • Queries must be performed eagerly, for consistency • i.e., MVCC is transient historical state isola&on only during query • Updates performed in-place • Complects reads and writes
  42. Transience Persistence Sharing Difficult Trivial DistribuIon Difficult Trivial Concurrency Difficult

    Trivial Access PaKern Eager Eager or Lazy Caching Difficult Trivial
  43. The rela&onal database, reimagined Transactor Indexing Trans- actions Transactor Indexing

    Trans- actions Data Segments Storage Server/Service Segment storage Standby Peer App Process Peer Lib Query Cache App Live Index Comm *cache cluster (optional) Data Segments
  44. Transactor Indexing Trans- actions Transactor Indexing Trans- actions Data Segments

    Storage Server/Service Segment storage Standby Peer App Process Peer Lib Query Cache App Live Index Comm *cache cluster (optional) Data Segments Database, reimagined • ACID seman&cs • Query scales with number of web servers • Choice of storage (e.g., AWS Dynamodb) • Lazy queries • Database as a value • Accumulates changes • Decomplects reads and writes
  45. About Me • SoXware Engineer @ Cognitect • Clojure, Datomic

    • We solve *hard* problems • Decomplect things • Polyglot, "Full Stack" • Systems' Architecture / Tech Advisor • Func&onal Programming advocate/enthusiast