Architecture is sometimes hard - people keep coming up with new ideas that quickly become the mainstream "way of doing things", and with microservices being the latest trend, it's time to dissect the idea and get to the real root of what's happening.
At the heart of
microservices, we were told we would find ...... ...
Lots of good stuff (TM)!
"Reliability": "Ensures no single point of failure by providing groups of replicated servers that can continue to run in the event of a failure. Restore running applications to a good state after a failure."
These all sound relatively familiar, I think, but the interesting part about these six references is that two are from the microservices literature (blog posts, papers, etc.), two are from the EJB literature from 20 years ago, and two are from Oracle, which is a technology from over 40 years ago. In this industry, we tend to reuse our hype points over and over again.
Regarding the microservices hype, a blog post from one company provides 10 reasons to adopt microservices.
1.They promote big data best practices. Microservices are a natural fit for a data pipeline oriented architecture that fits the way big data is collected, ingested, processed and delivered. Each step in the data pipeline handles a small task in the form of a microservice.
2.They are relatively easy to build and maintain. Their single-purpose design means they can be built and maintained by smaller teams. Each team can be cross-functional, while also focusing on a subset of microservices in the solution.
3.They support higher quality code. Modularizing the overall solution into discrete components helps application development teams focus on a small part at a time. This simplifies the entire coding and testing process.
4.They simplify cross-team coordination. Unlike traditional service-oriented architectures (SOA), which typically involve heavyweight inter-process communication protocols, microservices use event flow technology to enable easier integration.
5.They support real-time processing. At the core of microservices architecture is a publish-subscribe framework that supports real-time data processing to provide immediate output and insight.
6.They facilitate rapid growth. Microservices enable modular architectures for code and data reuse, making it easier to deploy more data-driven use cases and solutions to add business value.
7.They enable more output. Data sets are often presented in different ways to different audiences; microservices simplify the way data is extracted for a variety of end users.
8.Easier to evaluate updates during the application lifecycle. Advanced analytics environments, including those for machine learning, require some way to evaluate existing computational models against newly created ones. AB and multivariate tests in microservices architectures enable users to validate their updated models.
9.They make scale possible. Scalability is not just about the ability to handle more capacity. It is also about the effort involved. Microservices make it easier to identify scaling bottlenecks and then resolve them at the level of each microservice.
10.Many popular tools are available. Various technologies in the big data world (including the open source community) work well in microservice architectures. Apache Hadoop, Apache Spark, NoSQL databases, and many streaming analytics tools are available for microservices.
-
They promote big data best practices. Pipeline and filter architectures have been part of the software landscape since the 1970s, when Unixes came up with several ideas . -
Let each program do one thing well. To do a new job, re-build rather than complicate the old program by adding new "features". -
Expect the output of each program to be the input of another unknown program. Do not obfuscate the output with extraneous information. Strictly avoid columnar or binary input formats. Don't insist on interactive inputs. -
They are relatively easy to build and maintain. See the Unix philosophy above. -
They support higher quality code. If focusing on a small part at a time helps improve quality, then see the Unix philosophy above. -
They simplify cross-team coordination. This is interesting; does it suggest that "Service Oriented Architectures (SOA) ...... often involve heavyweight inter-process communication protocols" - like JSON over HTTP? Or does this mean that all SOAs require a complete collection of SOAP, WSDL, XML Schema, and WS-* specifications? Ironically, microservices are not in any way prevented from using any of these "heavyweight" protocols, and some even suggest using gRPC, a binary protocol more similar to IIOP, from CORBA, which is the predecessor of "heavyweight "protocol" predecessor of ...... A complete collection of SOAP, WSDL, XML Schema and WS-* specifications. -
They support real-time processing. Real-time processing has actually been around for a long time, and while many of these systems use a publish-subscribe or "event bus" model to accomplish it, it requires little to no microservices to do so. -
They facilitate rapid growth. "Reuse Modular Architecture" - How many different things have we counted that sell themselves as "reusable"? Languages have certainly done it (OOP, functional languages, procedural languages), libraries, frameworks ...... Someday I'd like to see something that makes a big deal out of saying "Can it be reused? We don't care." -
They can achieve more output. "Datasets are often presented in different ways to different audiences" - this sounds a lot like the home page of Crystal Reports. -
Easier to evaluate updates during the application lifecycle. Machine learning and advanced analytics environments need to "evaluate existing computational models against newly created models" ...... sounds like a bunch of action words, but there is little substance behind them. -
They make scale possible. How interesting - the same goes for EJBs, transactional middleware processing (Tuxedo-like) and mainframes. -
Many of the popular tools are available. I don't think I have to work very hard to point out that tools are always available for every major hype in our industry - especially after the hype has taken hold for a while. Most readers are not even old enough to remember CASE tools , but perhaps they will remember UML.
But the discerning reader will note that about half of the above ideas have a very common theme - the idea of creating and maintaining small, independent "chunks" of code and data, versioning each other, and using common inputs and outputs to achieve greater system integration. It's like ......
At the heart of microservices, we find ...... ...
Module!
Yes, the low-level "module", a core concept that has been at the heart of most programming languages since the 1970s. (Even earlier, although it was harder to deal with older languages that did not have modules as a first-class core concept.) They are called "assemblies" in the CLR (C#, F#, Visual Basic, etc.), "JARs" or "packages" on the JVM (Java, Kotlin, Clojure, Scala, Groovy, etc.), or from "packages" on the JVM (Java, Kotlin, Clojure, Scala, Groovy, etc.), or dynamic link libraries from your favorite operating system (DLLs on Windows, s or as for so on *nixes, and of course macOS hides "frameworks" in the /Library directory), but At a conceptual level, they are all modules. Each has a different internal format, but each has the same basic purpose: an independently built, managed, versioned
Consider this working definition of a module, quoted from a foundational paper in computer science.
"The clearly defined breakdown of project work ensures that the system is modular. Each task forms a separate and distinct program module. Each module and its inputs and outputs were clearly defined at the time of implementation, and there were no confusing modules with the expected interfaces to other systems. The integrity of the modules is tested independently at checkout; there are few scheduling issues with completing multiple tasks simultaneously before checkout begins. Finally, the system is maintained in a modular fashion; system errors and defects can be traced back to specific system modules, thus limiting the scope of detailed error searches."
This comes from David Parnas' seminal paper "On the Criteria To Be Used in Decomposing Systems into Modules" [6], which was written in 1971 - more than 50 years ago at the time of writing. -more than 50 years ago at the time of this writing.
Well-defined "separate and distinct program modules" cover about half of the benefits of the microservices proposal, and we've been doing this for 50 years.
So why all the hype about microservices?
Because microservices really have nothing to do with microservices, services, or even distributed systems.
At the heart of microservices, we should find ...... ...
Organizational clarity!
Amazon was one of the first companies to openly discuss the concept of microservices, and has not actually pushed the architectural principles as hard as they tried to push the idea of independent development teams, with few obstructionists. Waiting for the DBA team to make architectural changes, and for QA to build to test so they can find bugs? Or are we waiting for the infrastructure team to procure servers? Or is the UX team creating prototypes for demos?
SCHHHLLLUURRRRRRRRPPPPPPpppp...
The sound you hear is the development team gathering ownership of all the dependencies that could (and often do) stop them from moving forward.
-
This means that these teams are a small microcosm of the various parts of the average IT team (analytics, development, design, testing, data management, deployment, administration, etc.).
-
It does mean that teams now either have to be made up of a variety of different skill sets, or we have to require every team member to have a complete skill set (so-called "full-stack developers"), which means that hiring these people becomes more tricky.
-
It also means that teams are now responsible for their own production interruptions, which means that the teams themselves must now take responsibility for being on-call (and the corresponding payroll and legal implications that come with it).
But when all of this is harnessed, it means that each team can build their artwork independently, with no limitations other than the physics of time and the speed of fingers flying across the keyboard.
At the heart of microservices, we often find ......
The Fallacy of Distributed Computing!
For those unfamiliar with these fallacies, they were first introduced by Peter Deutsch in a talk he gave to his peers at Sun in the 80s. They reappeared in the seminal 1994 paper "A Note on Distributed Computing" by Ann Wolrath and Jim Waldo, and they essentially say the same thing. "Getting distributed systems right - performance, reliability, scalability, whatever "right" means - is difficult." (Loose paraphrase)
When we decompose systems into memory modules running on a single operating system node, the cost of passing data across process or library boundaries was negligible even fifty years ago. However, when passing data across network lines - as most microservices do - it adds five to seven orders of magnitude of latency to the communication. This is not something we can "eliminate" by adding more nodes to the network, which actually makes the problem worse.
Yes, some of these problems can be made less significant by hosting microservices on the same machine, usually by loading them into a cluster of virtual machines running containerized images of independent microservices. (e.g., using Docker Compose or Kubernetes to host a collection of Docker containers). However, doing so increases latency between VM process boundaries (because we have to move data up and down the virtual network stack according to the rules of the seven-layer model, even if some of these layers are fully emulated) and still creates reliability issues running on a single node.
To make matters worse, even as we begin to fight the fallacy of distributed computing, we begin to encounter a related, but separate set of problems : The Fallacies of Enterprise [7]
At the heart of microservices, we need ......
Start rethinking what we really need!
Do you need to break down the problem into separate entities? You can do this by accepting standalone processes hosted in Docker containers, or you can do this by accepting standalone modules in your application server that obey standardized API conventions, or a variety of other options. It's not a question of abandoning any already established technology - it can be done using technologies from anywhere in the last 20 years, including servlets, ASP.NET, Ruby, Python, C++, and maybe even quivering Perl. The key is to establish a common architectural backbone with accepted integration and communication conventions, whatever you want or need it to be.
Do you need to reduce the dependencies your development team faces? Then start by looking at those dependencies and working with partners to determine which ones you can bring into the team's wheelhouse. If the organization doesn't want to formally break the "skill-centric" ontology of the org chart (meaning you have a "database" team, an "infrastructure" team, and a "QA" team as peers to the "development" team), then work with senior management to allow at least a "dotted line" reporting structure so that each team has individuals who are now "matrixed" on a team.
But, most importantly, make sure that this team has a clear vision of what they want to build and that they can confidently describe the core of their service/microservice/module to random strangers walking by on the street.
The key is to give the team direction and purpose, give them the autonomy to accomplish their goals, and sound the clarion call to accomplish them.