What factors are important for microservices? (a.k.a. fine-grained SOA). It’s said that Node.js is an excellent fit for a microservices approach – which lends itself very well to the fashionable container approach – as it has the following:
- Excellent package system (npm)
- Minimal effort to publish new packages (package.json)
- Node.js itself encourages lightweight, narrow-focus services, not big monolith-ish services
- Designed to be async I/O in order to achieve better scalability
This is all very true, and we can add ease of “containerization” of those services. What about those of us who work in the .net world? For years, the perception that the .net world was somewhat behind in certain aspects, such as DDD adoption (or the blissful ignorance of it), microservices, containers (which are coming soon in windows) and so on. However, I think the tooling is improving a lot this year and sweeping changes are coming to the platform with the advent of .net core, the new runtimes, etc. Well, we can have all of this, although we might have to make more of a conscious effort to steer our development practices and inertia towards a more similar approach.
- We have a good package system, nuget, and we also have chocolatey (check out the difference). You can even implement your own nuget feed.
- So that means you could bundle certain things in packages (for example, implement cross-layer concerns, AOP stuff, etc. in nuget packages) and then add them to your nimbler solutions
- The new VS2015 brings great improvements to the web project idea, doing away with the classic solution approach we are so familiar with and taking the .net developer to the folder-based solution structure, as we are used to see in many other languages. With this, there comes semantic versioning, and json files for handling dependencies, the ability to bring grunt.js and gulp.js on board, introduce better minification and uglification into the build process, and so on, so in this sense the .net developer has been brought into the same arena as developers in the .js world.
- Use Web API or REST-ful traditional WCF web services – if you have such legacy services, they can be restified easily (pdf)-, or NancyFX, or ServiceStack
- You can have async as well, of course
So it’s perfectly possible to get the same approach (except the full-stack thing). You can dockerize too those services, if you want. This way you achieve this same “component”-oriented architecture. Don’t miss the “Docker for .net developers” Channel 9 (by Dan Fernandez) series if you want to gain a clearer picture of how Docker and .net applications fit together.Naturally, you get the same drawbacks:
- Deployments get more complicated. No need to argue that a monolithic application could be easier to deploy, although often those deployments are riddled with fears as well. At the same time though, error surface in deployments gets reduced, or more scoped, in the sense that if only one service is causing errors, at least you know where to look, and scope is not as big as in a monolithic application.
- As deployments get more complicated, you certainly need to automate testing and deployment, so depending on your current practices, or skill sets, this might be possible, or downright impossible if a previous effort to bring operations up to date is not done first. So, many companies will find themselves not to be in the right position for this point and the previous one. Especially if there is no culture of DevOps.
- Operations get more complex, hosting, managing, lifecycles, monitoring more systems, more processes, more logs (integrated views needed here) etc.
- Need to consider messaging patterns, need to consider how to handle transactions, if at all, or compensating them, need to consider how to test processes spanning several services that interact together.
- Need to consider sharding and partitioning your database. After all, what use is deploying redundant copies of your services if they’re all going to be talking to the same database? You get a potential bottleneck and a dangerous weakest link in your system. If using databases such as mongoDB, you need to have replica sets, or similar mechanisms in other systems.
Significant challenges lie ahead. Probably it’s safe to assume that not everything is quite mature in this confluence space between microservices, containers, and the usual, and not so easy, concerns of scaling, replication, hosting, clustering, service discovery inside containers, resource and performance (cpu, ram, disk etc) and so on and so forth. Kubernetes is something to watch closely in the near future, now that we can run on Linux too. Containers can have their own security issues, especially if you download images you’re not 100% sure about their provenance.Dealing with failed services / containers. I think that bringing some of the strategies the actor model proposes in the face of errors could be interesting. After all, in a way one can imagine containers to be somewhat like actors, they’re cheap, lightweight (actors are better in this sense), easy to start or to kill which brings me to the point where maybe considering a pure actor model (akka.net -ported from classic Akka- or even Microsoft Orleans) could be a better option. You can have millions of them, ready to work for you behind your API gateways. I think that could be a nice idea, or at least it looks very nice on paper. Surely it is not so easy to implement as it is to dream it. Certainly we’re in for a big sea change