5 ms·
As Chris says, in practice microservices are not really much different than using service objects, or Akka actors: They are just a form of enforced encapsulatio
by hibikir 12y ago
As Chris says, in practice microservices are not really much different than using service objects, or Akka actors: They are just a form of enforced encapsulation, which is just happens to bring the advantages and disadvantages of always going over a network.
The disadvantages of always paying for network costs are extremely steep, so the minute you care about latency, either because there's a user on one side, or because every second you wait is more money thrown the way of AWS, making everything a microservice quickly becomes a bad tradeoff for most applications. All the real advantages of microservices only start to pay off at scales that you'll only reach in a few handful of companies.
I am thinking of a small startup, that had a big proponent of microservices as the tech lead, which boldly went all in with this architecture, before any of the real advantages of microservices ever came into play. WHen they went to production the first time, they saw everything was slow, and quickly started to colocate said microservices in the same machines, and made them talk to each other directly, without serialization. In other words, they reimplemented EJB local interfaces. At some point in this process, the microservices champion left.
So now they have hundreds of little faux services, and instead of a monolith, they have to worry about what happens when someone wants to change the contract of one of those services. A ball of yarn, by a different name. Instead of wondering whether the code will compile if they make a change, they wonder whether it will run, in practice.
It sounds to me like they are not in any better a shape than if they had built a monolith anyway, other than the fact that their employees can now claim they have microservice experience.
If we go back to basics, maintainability comes down to getting lucky with your selection of abstractions, and trying to minimize coupling. If your abstractions are wrong, your modularization will be either incorrect or just lacking overall, and no architectural pattern will save you.
- bullines 12y agoHow would the Service Objects approach work with Z-axis scaling?
- eeperson 12y agoWhat do you mean by z-axis scaling?
- q4814 12y agoI'm guessing it's a joke. Y=vertical scaling, X=horizontal scaling, Z=? scaling
- bullines 12y agoX-axis scaling: running multiple identical copies of an application behind a load balancer Y-axis scaling: splitting the application with functional decomposition (a server for account info, another for catalog, etc.) Z-axis scaling: each server runs an identical copy of the application (like X-asis) but each server is responsible for only a subset of the data - some other component of the system is responsible for routing each request to the appropriate server (Ex: sharding)
- alexchamberlain 12y agoWhy not just call it sharding? There's enough jargon as it is!
- sciurus 12y agoBecause when you treat those three aspects of scaling as dimensions of a cube, you can visualize what it means to scale on different axes. See this diagram http://akfpartners.com/techblog/wp-content/uploads/2008/05/app_cube.png http://akfpartners.com/techblog/wp-content/uploads/2008/05/a... taken from http://akfpartners.com/techblog/2008/05/08/splitting-applications-or-services-for-scale/ http://akfpartners.com/techblog/2008/05/08/splitting-applica.... For in-depth discussion, see the book The Art of Scalability. http://theartofscalability.com/ http://theartofscalability.com/
- bkeroack 12y agoYou get to sound smart when you compel people to ask what jargon-word X means.
- nl 12y ago(now that I understand Z-axis scaling means sharding: whoever thought up that term was on something)... There's no real problem with sharding using service objects: you parameterize them to determine what shard they are serving. There are issues with replacing one if it goes down, or adding in a new one, or hot shards vs unused ones, but these are all familiar with any kind of sharding.
- jshen 12y agoI agree with the bulk of your comment, and want to add one thing you didn't mention. Micro services allow you to scale the size of your engineering team. We started with a monolith at my company and as the engineering team grew from 5 to ~50 we started pulling out independent pieces and making them services that a team of ~5 could own, and it has worked out well.
- aantix 12y agoWhy do you have to fully decouple if it's not necessary. Create a gem(s), and call it a day.
- jshen 12y agoYeah, i have asked myself this, and have repeatedly tried it. Somehow it usually doesn't work out as well. With gems it's still a bit too easy to dig into a gem and fiddle with it to get something done quickly when in a hurry breaking the encapsulation. Maybe there are other reasons as well. Also, with a big org I like having the ability to use different languages and technologies in some small services. Is functional programming all the rage? Well we can experiment with it on this little service need to build without much risk. Another thing I like is that other teams can leverage my micro service regardless of the languages we are using. With libraries, everyone has to use the same language.
- yummyfajitas 12y agoYou can do the exact same thing with service objects. You can probably also get away with smaller teams, since most teams don't need to worry about devops.
- kyllo 12y agoBut doesn't that just put you right back into RPC-land, where you don't even know whether a method call is local or over the network, because the interface is the same? And if you take the suggested alternative of wrapping the return values in 'Future', then your interface just changed, so now the code that calls your service all needs to be rewritten. It's pretty well established that service calls are either local or remote, and the service interface should show the difference between the two, but that means means that changing a service from local to remote is always going to break its clients. That's a pain point, but it's probably better than making every service call remote by default which is what a microservices architecture does.
- alexchamberlain 12y agoService architecture should reflect good code architecture. One example of this is hierarchical design: if service A calls service B, B should not call A. There's some extraordinary use cases for violating this within a component, but I haven't seen a good use case for violating this at a library or service level.
- DanielBMarkham 12y agoMaybe I'm wrong, but I think you're missing it. Microservices, at least how I understand them, is just functional programming at the O/S level. Where they are located, how they talk to each other, and so forth? That all becomes SysOps stuff. That's good and bad. It's really bad if you don't stay on top of it and don't refactor. You can make the same mess you made in your big monolithic POS, just spread out everywhere. But to state it that way misses the point. The point is to actively keep the number of microservices small, have tests for each one for compilation, deployment, and production. You should never deploy something that doesn't work in the ecosystem. The development environment should prevent it. You should also have a very good grasp on data flow between microservices and latency issues. Monitoring that should be part of your daily work. You don't just do microservices because they're cool. You do them because they separate concerns in such a way to be both scalable and configurable without having to touch the IDE. With good safety protocol in place, this decrease both risk and complexity. Without good protocols in place, you'll make a mess no matter what tool you're using. Look at it this way (put your FP hat on): any program takes input, runs it through some functions, and produces output. If you were debugging, you'd set up breakpoints along the inputs and outputs to chase down errors. Then you'd walk the data flow to see what was going on. Microservices allow you to do this without touching the code. You would think that this increases network and system instability. It can, but when done well, you get the same thing you had with the big monolithic thing -- only in smaller pieces that you can change and reason about without introducing one of the thousand stupid coding errors that get introduced any time we open the project up and touch it. Plus you get hot-swapping, easy testing, auto-scaling, and ease of programming. In the modern VM/hosted world, this is a pretty good trade-off.
- JackMorgan 12y agoAt my current company, we've been breaking microservices out from the megalith whenever we need scaling. While it makes it a pain to install, that pain made it possible to meet some very steep performance goals. Going from importing a few hundred rows a minute to tens of thousands, etc.