Dean Budd - 2015-11-20 08:42:24+1100 - Updated: 2015-11-20 08:51:52+1100
µservice boundaries can be various levels. Some services might encapsulate an entire bounded context (domain driven design), other services might encapsulate a much smaller part.
An example would be splitting a CRUD style bounded context into four µservices, one for each operation. This has the benefit of not just independent deployability but independent scalability.
Your read operation might take most of the traffic and need to be scaled much more-so that an delete operation, etc. Your read operation might even have a very different looking architecture, with caching, etc involved whereas your delete operation might not anything like that at all. Your read operation might require ten nodes, your delete operation might require just one.
When your services are so small it creates a completely new paradigm. You find you hardly ever modify services that are that small i.e if you're adding new functionality then your service is probably doing too much (SRP). Rather, create a new service. If another service isn't doing what you need, sometimes it's simpler to remove it and write a new one that does. It's a whole new game that we're still coming to grips with is all.
Dean Budd - 2015-11-20 08:54:50+1100 - Updated: 2015-11-20 08:59:05+1100
We've recently started breaking a large web application into smaller parts, where individual µservices serve up just one page (or part of a page). This opens the door to massive flexibility. Various parts of the app could be written in different technologies i.e plain HTML or complex MVC style Javascript. Different parts of the web application could have different deployability or scalability requirements e.g the 'landing page' needs to be highly performant and highly available where the 'update address' page could be served by a µservice running on someone's old 486. lol.
For your CRUD example, how do you compensate for the Consistency problem (CAP)? I personally would delineate the service boundaries based on the data aggregate.
Dean Budd - 2015-11-21 07:29:20+1100 - Updated: 2015-11-21 07:39:28+1100
Well, depending on your requirements eventual consistency might not be an issue e.g if someone only ever updates their address once every five years, it probably doesn't matter whether they can't read the new value 1 microsecond after the update. You might want to make your read synchronous but your write asynchronous. This is the kind of flexibility that opens up with this design, meaning you can solve each different problem with a far more flexible toolset.
Dean Budd - 2015-11-21 07:37:13+1100 - Updated: 2015-11-21 07:40:14+1100
You could take your idea a little further and have one microservice act as a gatekeeper to a data aggregate with consistent operations but then decouple yourself from that using even another microservice with asynchronous (messaging) operations. This is the beauty of this new style of architecture. I've used that pattern just recently with two microservices, one with about ten lines of code.
Dean Budd - 2015-11-23 09:15:47+1100 - Updated: 2015-11-23 09:22:07+1100
Na, if you need that kind of stuff just write some of your µservices in Clojure which has very good built-in concurrency support. If you want to real actor stuff, write some other µservices in Erlang.
An example would be splitting a CRUD style bounded context into four µservices, one for each operation. This has the benefit of not just independent deployability but independent scalability.
Your read operation might take most of the traffic and need to be scaled much more-so that an delete operation, etc.
Your read operation might even have a very different looking architecture, with caching, etc involved whereas your delete operation might not anything like that at all. Your read operation might require ten nodes, your delete operation might require just one.
When your services are so small it creates a completely new paradigm. You find you hardly ever modify services that are that small i.e if you're adding new functionality then your service is probably doing too much (SRP). Rather, create a new service. If another service isn't doing what you need, sometimes it's simpler to remove it and write a new one that does. It's a whole new game that we're still coming to grips with is all.
Event driven. Async communication.