Mini-Book: Migrating to Cloud-Native Application Architectures

migrating_to_cloud“Migrating to Cloud-Native Application Architectures” by Matt Stine
  • “Why are frequent deployment important? If you can deploy hundreds of times per day, you can recover from mistakes almost instantly. If you can recover from mistakes almost instantly, you can take on more risk. If you can take on more risk, you can try wild experiments–the results might turn into your next competitive advantage.”
  • “Provisioning a new application enviroment by makign a call to a cloud service API is faster than a form-based manual process by several orders magnitude. Deploying code to that new environment via another API call adds more speed. Adding self-service and hooks to team’s continuous integration/build server environments adds even more speed.”
  • How to go fast and safe
    • Visibility: “We need the ability to measure everything, establish a profile for “what’s normal,” detect deviations from the norm (including absolute values and rate of change), and identify the components contributing tot hose deviations.”
    • Fault isolation: “By composing systems from microservices, we can limit the scope of a failure in any one microservice to just that microservice, but only if combined with fault tolerance.”
    • Fault tolerance: “A software circult breaker works very similarly to an electrical circult breaker: it prevents cascading failure by opening the the circuit between the omponent it protects and the remainder of the failing system. It can provide a graceful fallback behavior, such as a default set of product recommendations, while the circuit is open.”
    • Automated recovery: “Some failures are easy to identify: they present the same easily detectable pattern every tme they occur. Take the example of a service health check, which usually has a binary answer: healthy or unhealthy, up or down. Many times we’ll take the same course of action every time we encounter failures like these. In the case of the failed health check, we’ll often simly restart or redeploy the service in question. Cloud-native applications architectures don’t wait for manual intervention in these situations. Instead they employ automated detection and recovery. In other words, they let a computer wear the pager instead of a human.”
  • See: https://12factor.net/
  • 12 factors
    • Codebase: “Each deployable app is tracked as one codebase tracked in revision control.”
    • Depencies: “An app explicitly declares and isolates dependencies via appropriate tooling (e.g., Maven, Bundler, NPM) rather than depending on implicitly realized dependencies in its deployment environment.
    • Config: “Configuration, or anything that is likely to different between depployment environments (e.g., development, staging, production) is injected via operating system-level environment variables.”
    • Backing services: “Backing services, such as database or message brokers, are treated as attached resources and consumed identically across all environments.”
    • Build, release, run: “The stages of building a deployable app artifact, combining that artifact with configurtion, and starting one or more processes from that artifact/configuration combination, are strictly separated.”
    • Processes: “The app executes as one or more stateless processes (e.g.e master/workers) that share nothing. Any necessary state is externalized to the backing services (cache, object store, etc.).”
    • Port binding: “The app is self-contained and ports and/all services via port binding (including HTTP).”
    • Concurrency: “Concurrency is usually accomplished by scaling out app processes horizontally (through processes may also multiplex work via internally managed threads if desired).”
    • Disposability: “Robustness is maximized via processes that start up quickly and shut down gracefully. These aspects allow for rapid elastic scaling, deployment of changes, and recovery from crashes.”
    • Dev/prod parity: “Continuous delivery and deployment are enabled by keeping development, staging, and production environments as similar as possible.”
    • Logs: “Rather than managing logfiles, treat logs as event sterams, allowing the execution environment to collect, aggregate, index, and analyze the events via centralized services.”
    • Admin processes: “Administrative or managements tasks, such as database migrations, are executed as one-off processes in enviroments identical to the app’s long-runnning processes.”
  • “However, rather than placing all of the developers in a single sandbox, we can create a parallel work streams by buidling more sandboxes through bounded contexts.”
  • See also: https://sdtimes.com/agile/analyst-watch-water-scrum-fall-is-the-reality-of-agile/
  • “Enterprises normally adopt centralized governance structures around application architecture and data management, with committees responsible for maintaining guidelines and standards, as well as approving individual deigns and changes.”
  • “These structures are created with the belief that they will result in higher quality, lower costs, or both. However, these structures rarely result in the quality improvements or cost savings desired, and further prvent the speed of delivery sought from cloud-native application architectures. Just as monolithic application architectures can create bottlenecks which limit the speed of technical innovation, monolithic governance structures can do the same.”
  • See also: https://www.thoughtworks.com/radar/techniques/inverse-conway-maneuver
  • “Rather than building an architecture that matches thir org chart, they determine the architecture they want and restructure their organization to match that architecture.”
  • “So, as part of the shift to a DevOps culture, teams are organized as cross-functional, business capability teams that develop products rather than projects. Products are long-lived efforts that continue until they no longer provide value to the business. (You’re done when your code is no longer in production!) All the roles necessary to build, test, deliver, and operate the service delivering a business capability are present on a team, which doesn’t hand off code to other parts of the organization. these teams are often organized as ‘two-pizza teams’ (http://bitly/bezos-interview), meaning that the team is too big if it cannot be fed with two pizzas.”
  • “The platform operations team operates the self-service agile infrastructure platform leveraged by the busienss capability teams. This team typically includes the traditional system, network, and stroage administrator roles.”
  • “Just as the business capability teams collaborate with one another around defined API contracts, the platform operations team presents an API contract for the platform. Rather than queuing up requests fro application environments and data services to be provisioned, business capability teams are able to take the leaner approach of building automated release pipeline that provision environments and services on-demand.”
  • “The principles founded in Domain-Driven Deisgn (DDD), by Eric Evans (Addison-Wesley), argue that our succes is largely governed by the quality of our domain model (and the ubiquitous language that underpins it). For a domain model to be effective, it must also be internally consistent–we should not find terms or concepts with inconsistent definitions within the same model.”
  • “Bounded context allow you to keep inconsistent definition of a single concept across the organization, as long as they are defined consistently within the contexts themselves.”
  • “So we begin by identifying the segments of the domain model that can be made internally consistent. We draw fixed boundaries around these segments, which become our bounded contexts. We’re then able to align business capability teams with these contexts, and those teams build microservices providing those capabilities.”
  • “We couple bounded contexts with the database per service pattern, where each microservice encapsulates, governs, and protects it own domain model and persistent store. In the database per service pattern, only one application service is allowed to gain access to logical data store, which could exist as a single schema within a multi-tenant cluster or a dedicated physical database. Any external access to the coencepts is made through a well-defined business contract implemented as an API (often REST but potentially any protocol).”
  • “However, data must often be recomposed via event-driven teniques in order to ask cross-context questions. Techniques such as command query responsiblity segregation (CQRS) (http://bit.ly/fowler-cqrs) and event sourcing (http://bit.ly/fowler-es), beyond the scope of this report, are often helpful when synchronizing similar concepts across contexts.”
  • “Cloud-native architectures, such as microservices, tend to prefer choreography, akin to dancers in a ballet. Rather than placign the smarts in the integration mechanism, they are placed in the end-points, akin to the dumb pipes and smart filters of the Unix architecture. When cirsumstances on stage differe from the original plan, there’s no conductor present to tell the dancers what to do. Instead, they simply adapt. In the same way, services adapt to changing circumstances in the environment via patterns such as client-side load balancing and circuit breakers.”
  • “…the team decided that the best approach to deal with the architecture change would not be to split the Mothership immediately, but rather to not add anything new to it. All of our new features were built as microservices…” –Phil Calacado, SoundCloud
  • “Domain-Driven Design (DDD), by Eric Evans (Addison-Wesley), discusses the idea of an anti-corruption layer. Its purpose is to allow the integration of two systems without allowing the domain model of one system to corrupt the domain model of the other. As you build new functionality into microservices, you don’t want these new services to become tightly coupled with the monolith by giving them deep knowledge of the monolith’s internals. The anti-corruption layer is a way of creating API contracts that make the monolith look like other microservices.”
  • Client side routing/load blaancing : Ribbon http://bit.ly/ribbon-netflix
  • fault-tolerance: “Mike Nygard documented several patterns that can help in his book Release It! (Pragmatic programmers), including:”
    • Circuit breakers: “Circuit breakers insolate a service from its dependencies by preventing remote calls when a dependency is determined to be unhealthy, just as electrical circuit breakers protects home from burning down due to excessive use of power.”
    • Bulkheads: “Bulkheads partition a service in order to confine errors and prevent the entire service from failing due to failure in one area.”
  • “Netflix has produced a very powerful library for fault tolerance in Hystrix (http://bit.ly/hystrix) that employs these patterns and more.”
  • “These metrics are emited as an event stream which can be aggregated by another Netflix OSS project called Turbine (http://bit.ly/netflix-turbine).”
  • “The API Gateway (http://bit.ly/api-gateway) pattern is targeted at shift the burden of these requirements from the device developer to the server-side. API gateways are simply a special class of microservices that meet the need of a single client application (such as specific iPhone app), and provide it with a signel entry point to the backend. They access tens (or hundreds) of microservices concurrently with each request, aggregating the responses and transforming them to meet the client application’s needs. They also perform protocol translation (e.g. HTTP to AMQP) when necessary.”
  • “In this discussion we’ll stick with Java and give an example from RxJava (http://bit.ly/rxjava-git), a JVM implementation of Reactive Extensions (http://reactivex.io/) born at Netflix. Composing multiple work or data streams concurently can be a challenge using onely the primitives offered by the Java language, and RxJava is among a family of technologies (also including Reactor (http://reactor.github.io/) trgeted at relieving this complexity.”
  • “For more information, the reader is invited to read ‘Testing Strategies in a Microservice Architecture’ (http://bit.ly/fowler-microtest) by Toby Clemson and continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation by Jez Humble and David Farley (Addison-Wesley).”

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s