Architecture is abstract until operationalized.
Here’s a thought experiment. Take a computer, install a mainstream operating system on it, along with various software (databases, application servers, web servers, etc.). Once everything works properly, unplug the computer and place it in a closet for a year. After the year has elapsed, retrieve it from its haven, plug it into both power and Internet, and boot it. What’s the first thing (or, rather, first set of things) that will happen? 47 Software Updates available! New Virus definitions!! Office needs to shut down all browsers to update itself!!! Even though nothing changed inside the closet, the whole universe continued its relentless pace. Nothing in the software universe is static.
Software architects have the responsibility to elucidate decisions about how systems fit together, often by creating diagrams, with varying degrees of pomp. Diagrams have a vague air of certainty around them, a wafting aroma of mathematics. Thus, architects often fall into the trap of envisioning software architecture as an equation they must solve. Much of the commercial tooling sold to software architects reinforces the mathematical illustion of certainty with boxes, lines, and arrows–graphs don’t lie! While useful, these diagrams offer a two dimensional view, a snapshot of an ideal world, but we live in a four dimensional world. To flesh out that 2D diagram, you must put specifics to it. The ORM
label on the 2D diagram becomes Hibernate v4.2.17
, evolving into a three dimensional view of the world. When you have a plan on how to put that into production and upgrade it to the inevitable Hibernate v4.3.0.1
in six months, you’ve graduated to a four dimensional world. Too many architects fail to realize that a static picture of architetcure has a short shelf life. The software universe exists in a state of constant flux, it is dynamic rather than static. Architecture isn’t an equation but rather a snapshot of an ongoing process.
Continuous Delivery and the DevOps movement illustrated the pitfalls of ignoring the effort required to implement an architecture and keep it current. There is nothing wrong with modeling architecture and capturing those efforts, but the implementation is only the first step. Architecture is abstract until operationalized. In other words, you can’t really judge the long-term viability of any architecture until you’ve not only implemented it but also upgraded it. And perhaps even enabled it to withstand unusual occurrences.
Here’s a concrete example, based on real client experiences. Architects for an airline created a services-based architecture with a canonical Customer
service, encapsulating everything known about customers. This is a natural instinct of software design, the DRY (Don’t Repeat Yourself) principle, Single Source of Truth, and other good (but abstract) ideas. Then, a volcano erupted in Iceland, disrupting air travel drastically. Customers of the airline flooded the support center with calls, asking if the disaster would affect their flight. And people holding tickets in unaffected parts of the world couldn’t board their planes (because, of course, ticket lookups involved Customer
). While the architecture made logical sense, it fell over during extraordinary circumstances. While it might seem wasteful or perhaps even lead to duplication (gasp!), having multiple customer services (one to handle customer issues, one to handle boarding) would have served the business better. Only by thinking about the operational aspects of architecture can you build more robust systems, which is one of the goals of microservice architectures.
Microservice architecture is the first post-DevOps revolution architecture, highlighting the realization that architecture and DevOps must mesh, making operational concerns a first-class citizen in architectural design. Traditionally, change is the most feared thing for software architecture. Martin Fowler wrote an article entitled Who Needs an Architect? highlighting several historical definitions of architecture, some of which say that “architecture is the set of design decisions that must be made early in a project”. Because the architectural elements present scaffolding that everything else must rely upon, changes to architecture are typically time consuming and difficult. Some portion of that difficulty is caused by ignoring the operational aspects of architecture. Microservice architectures assume constant evolutionary change, making it less expensive and error prone, even in extraordinary situations. A good example of designing for robustness comes from one of the reference microservice architectures, NetFlix. Many operations groups treat their deployments as fragile, delicate things. Netflix tries to disrupt their ecosystem with tools like the Simian Army, designed to stress their architecture in imaginative ways.
You don’t have to go all the way to an exotic microservices architecture to see benefits from this perspective shift. A good example of the empowering effects of good operational control on architecture is the continuous delivery practice of decoupling deployment from release. One of the scariest events for traditional monoliths is Going Live, because you must make all the changes work all at once: database, code, configuration, integration, etc. If you are accustomed to this Big Bang world, a practice like continuous deployment sounds insane: how can you manage all that change all the time? The secret is to separate deployment from feature release. Feature Toggles are a common continuous delivery practice to allow in-flight feature definitions in trunk-based development. Toggle libraries like Togglz allow you to control feature exposition at runtime via a filter servlet. Thus, you can deploy a component into your ecosystem that includes toggled off code, which allows you to make sure (via monitoring) that the deployed component hasn’t had any ill effects on the ecosystem. At the selected time, you can enable the feature, continuing to monitor to make sure nothing is awry. If something does go wrong, turn the feature back off while you determine a fix. By decoupling deployment from release, we separate the operational concerns from the developers and users.
Microservices happens to be the first architecture to fully embrace DevOps, but it won’t be the last. The operational concerns of architecture will continue to impact our design and decisions, which I consider part of the maturation process for software architecture.