For those who don't yet know Adrian Cockcroft is the chief cloud architect for Netflix, a company that revolutionized cloud architecture and in a cause reaction way started up the DevOps movement. Yep, one thing they don't tell you is that when you transition to an architecture based on visualization, stateliness, and computerization of business features you drive up your costs related to the management and development of tools related to your day to day operations. It really puts Dev into Ops. Gone are the days where you could just put and app in production and forget about it on a day to day basis. Nowadays you need twenty something tools just to run and manage everything.
Well, heck, that's not what I wanted to write about today. As you may have seen I've upped up my software engineering writing and profile these days. I've writing about other stuff lately (mainly on this blog Fighting fitness , with my fiancee, about my wonderful journey into self defense and losing weight) .
The first of January started with a well made plan to work on an project I started a couple of weeks ago. Yeah, I didn't. In exchange I've spent the morning trying to find a formal definition of the architecture model Cockcroft presented in his talk at Dockercon.
I couldn't find it, but instead I found a bunch of articles and resources about the current state of micro-services architectures in the wild.
I've been involved in a government project for the last year or so, changing and modernizing a national VAT system IT infrastructure. As part of the this project we build a service oriented (micro-service based) infrastructure with the goal to reduce the load on the main VAT system and ease the development of supportive business functions (e.g. bounded context) like a separate VAT Portal for Taxpayers or a system for VAT refunds for foreign companies. And we all did that with a fairly conservative .NET stack (its the tax authority, we live conservatively).
During his presentation Cockcroft has shown several architectural graphs of the current Netflix architecture. The looked like nineteen seventy fractals from a weed high math graduate from Berkley, all accompanied by a comment that it is impossible to show an architectural model for Micro-service based architectures.
Micro-services based architecture can generally be tough as :
- Application topology (fractals baby, fractals)
- Data processing and transformation system (Event driven, space and time unbounded ETL)
- Application architecture
and yeah if we are talking about the network topology we have software that can discover where, what and why we have something on our network and draw a pretty picture for us to impress everybody else but for all intent and purposes its completely useless.
But software architecture is not about that. Its about the overreaching model of the system, the pattern we use to think and build our stuff.
When we are designing a standard application we are never doing detailed class designs. Almost never, we do it only for the most critical parts. Instead we layout the building blocks and discuss how are they going to interact and what patterns are we going to use.
So, why should micro-services architecture be different. Cockcroft presented a modeling framework how to describe an micro-services architecture in really simple terms.
On bottom, the deep blue see we have our development. The basic languages (.NET, ASP.NET MVC) and application containers (IIS, Apache Tomcat, Glassfish) we are using to build our stuff.
Next to it we have the Operations what is our main deployment infrastructure (virtualized servers in our local data center, could services like Amazon, Google App Engine or Microsoft Azure) on top of which we are actually deploying our products.
The Datastore is an interesting thing. Which database technologies we are using and their order of importance (e.g. SQL Server as our main bounded context databases, while we are using SQL Lite for less important we don't care if we delete storage).
On top we have our micro-services element, the dev and the ops of DevOps:
- Tooling (basic development and deployment tools - think unit testing, packaging, integration)
- Configuration (with lots of servers, databases, services we need lots and lots of configurations)
- Discovery (with things popping up and dieing all around us in a really chaotic fashion we need to figure out how to discover things)
- Routing (back to the chaos of microservices, we really don't want to hardcoded every url and resource - think load balancing)
- Observability (we need to monitor and log what the hack is going with our process , logs and events and process tracing).
Does this model help us build such an architecture. No. But it helps us see which technologies and areas we need to think about, what we have chosen and how to connect everything with everything else.
We IT people. We developers. We administrators. We engineers, UX experts, Scrum masters and evangelistwe really like our Koolaids. We drink them mouth full and enjoy the bitter test disillusion
The promise of micro-services is the promises of using a different technology for different projects, freedom from repressive and outdated technology stacks, a better and brighter future of easy to understand code.
Microservices as an architecture pattern are good for somethings. But they are not silver bullet, and with the ability to use a different technology stack for different projects is well and good should we really do it.
In the end we are going to need people who are going to maintain all of that, and if we don't have specialist for that specific technology we need either to retrain people or build something from scratch.
I'm a cross platform guy. I'm fluent in .NET, Java, PHP and Python. I've developed software in all those platforms and then some others to my chagrin. But not all people are really happy to learn something new and adapt to a new platform. Most stick to one thing only and live and breathe something they do not need to spend my time to learn about. They can go about their business and develop software with the ye olde technology.
The modeling diagram above is a sketch of a process oriented architectural framework to for building reactive and scalable systems based on micro-services in .NET (with other technologies as needed). Its generally an intellectual exercise based on the architectures of the systems I've built and designed in the past (and currently working on) and somethings I've been thinking about and reading about.
On the left we start with the users. Living, breathing, stinking, eating, thinking, fidgeting human beings. The human animal with all its drawbacks and none of the benefits of a pure machine system (we miss you so much Skynet).
Our users want to buy stuff, like stuff, talk about stuff and look for suitable life companions. And they use and app or go to a web site have something installed on their machine. Lets say we are fairly conservative and have an application.
That application has many, many distinctive submodules which all need to be presented to our users in a very unified manner. But we don't wan to develop, ship and version them together since they are fairly independent. Once a user logs in each UI application is fairly separate from the rest. They can also have different scalability request (one is used more than the other).
So we build them as separate applications, with their own infrastructure and deploy and manage separately. In front of that entire farfallini collection is the Application Context Routing App. Its only goal is to provide a single entry point for everything, a basic context and session discovery mechanism and to route requests (and their state) to specific application contexts and return specific responses from each separate business function application.
On the right most section of the system we have our micro-services silos. Out business domain bounded context. Each micro-service deals with specific business area. In general are not talking about on or two services, but a slew of services specializing for a specific context (Users, Accounting etc).
They each have their own data store and may be either called by Business function Applications or other Microservices.
How do we connect all of them? In the most simplest of terms we use the following two technologies:
- Message queue (for eventing)
- Web API Gateway - for routing micro service calls (and serve as a circuit breaker in case of service failure).
The general idea is that we want our system to be automated as much as possible, self discoverable and self healing and as much de coupled as possible.
In order to achieve that our services will:
- Raise "I'm here events" or "I'm dieing Jim" events trought the event system which will be read by the Web API gateway which will in turn manage the service registry (who is where)
- The web api gateway will queue service calls in case of failures (for important operations) so when our services fail we have a log of all calls made to them and we can execute them as soon as the failing service is up again (e.g. circuit breaker)
- Services need to handle data stored in other services (e.g. have their own local copies) so they need to publish their internal events and react to events published by other microservices.
Does anyone think we are back into the layers end.
- Web UI (Web aps instead of Controllers)
- Domain (Microservices instead of Business logic layer)
- Web api Gatweay, Message Queues and routers as the glue that holds everything together
Its all the same pasta, from the lower layers of computer interactions to our brave new world of microservices and cloud computing.
When building microservices based architectures in the .NET world we need to really reduce the amount of time and configuration we need to do in order to build such a project. NuGET is all well but setting up a ASP.NET MVC Web API project, loading all dependencies, handle all Web.Conf configurations, create all the infrastructure classes we need is really bother.
Luckily our heroes from the Visual Studio and ALM teams come to our rescue. First of all we are not going to rewrite everything from scratch. We need to standardize whenever is possible, but make that standardization optional (we can ignore it when we need it) - call this convention over coding. We are creating a convetion of how we built things.
So if we have a fairly standard way of building our microservices why not create a set of core libraries we are going to load to ease our development effort. I call them Definitions. Definitions of terms and interactions.
Each microservice is going to have:
- Entites and other domain goodies
- A way to publish services and connect to other services (we really do not need twenty way to access or read data from an internal web service)
- A way to publish and to react to events
- A way to interact with the Web API gateway
- A way to access the database (or database groups).
Great, we write those libraries and publish them into a local NuGet Package repository. Next we build a sample Microservice project that works. A hello world project, or event project groups.
And with the greatness that is Visual Studio we create project and item templates. We version those into our source configuration. And whenever we need to create a new project we use such a template.
In the end if we think about service oriented architecture, or application architecture in general its all the same thing just looked from different angles and with different terms to throw around. Each type of system has its own challenges and costs.
The important thing to remember is that systems are built by people and how those poeple think and organize is going to be reflected in the system they've built (Coneways law).