4 ms·
Listing the difficulties on microservices is useful, but let's not forget the difficulties encountered in monolithic big applications, which are the reason for
by gbog 12y ago
Listing the difficulties on microservices is useful, but let's not forget the difficulties encountered in monolithic big applications, which are the reason for splitting into smaller pieces.
In the big app 1) a single syntax error breaks everything. 2) simply loading all the app takes a huge part of ram, and tests are very slow. 3) there is a gigantic dependency tree, as when you depend on a module you also depend on every ones of the module dependencies. 4) Almost no one knows everything about the app. 5) it is impossible to split the company into separate services without getting fights about shared code and architecture decision.
- jacquesm 12y agoAnd it is much easier to test a microservice than a monolith. (Going on the assumption that you do spec out the interface to your microservices with some care.)
- ericb 12y agoIf you have a microservice, typically that means a REST API. -Tests for all response codes -Test for all failure modes (timeout, service down) -Load tests both services. -Two sets of deployments to test. -Two healthchecks to test. Seems harder to test, not easier.
- possibilistic 12y agoHTTP is pretty terrible at cancellation, retry, cluster load balancing, in-channel health checks, etc. Some form of RPC is better suited for non-web facing APIs. And yeah, I agree that it's absolutely harder to test. (Integration test especially.) But you gain a lot for the trouble: independent deployability, scalability, dynamic traffic shifting, easy sevice boundaries and ownership (data stores, state, downstream deps, etc.). For a large company, this makes a lot of sense. Edit: microservices are not the easy path.
- jacquesm 12y agoLike with any tool, misapplying is worse than not having it. I think a big problem with microservices is that people that really don't need them think 'neat idea' and start implementing what would be otherwise trivial products using a whole slew of intercommunicating services. They get all the downsides and probably very little if any of the upsides that way. If you don't need it it's best left alone but if you do need it it can help structure a large project in ways that would be otherwise hard to achieve.
- rapind 12y agoThis is very true. I've seen it myself recently, and it can produce a nightmare. I've been detecting a tendency lately to over-engineer everything, especially when it comes to devops.
- ExpiredLink 12y ago> Going on the assumption that you do spec out the interface to your microservices with some care I reckon this is hardly ever done. Microservices, like many other abstractions, usually just proliferate and quickly become a maintenance nightmare.
- parasubvert 12y agoMicroservices are (generally) developed and owned by different teams. In that sense, they proliferate to the number of teams you have. I've also found that multi-team organizations with a strong architecture core will constrain "how" interfaces are designed pretty well (leaving the specifics to the teams). This also requires fast feedback and continuous integration. The old saying "team = product" applies: if your business requires lots of parts independently evolving, you're going to find ways to make them cooperate at the boundaries, or you will be in a mess. Companies like Amazon have made this approach work at speed and scale. Others might fail out of incompetence. Mostly I think people are just looking for ways to operate at better speed and scale than the current enterprise practices.
- jacques_chester 12y ago> The old saying "team = product" applies This is usually introduced as "Conway's Law". We think about it a lot at Pivotal, because we are frequently starting, shuffling, merging and splitting teams while we work on Cloud Foundry.
- parasubvert 12y agoAnd I am newly in the Pivotal field looking to help people adopt Cloud Foundry and microservices :)
- lgas 12y agoI don't disagree but I suspect that proliferation of components within a monolithic app is roughly comparable and leads to similar maintence burdens. If I'm right then the microservice model has one major advantage over the monolithic app model, which is that if things stop depending on a microservice you generally can tell because eg logs are empty or instance utilization is zero or whatever. With components in a monolithic app there are tools in most languages to find dead code but I've not seen them used regularly in many teams (especially startups) and they are often less helpful in that they can tell if code is no longer referred to at all but not if its just in a code path that is no longer executed. My gut feeling is that this leads to dead microservices being garbage collected more reliably than dead code.
- cpks 12y agoIt's a false dichotomy. The split isn't about no abstractions vs. services, but about whether the abstractions should be behind a network boundary. Let's look at these one at a time. 1) A single syntax error will _still_ break everything in a microservices architecture if the service in question is any essential service. In my experience, most services are essential. In a dynamically linked architecture, the failure occurs when you try to pull in the library. In a well-designed dynamically linked architecture, you can opt to not pull in optional components. 2) If you're an idiot and build everything monolithicly. A well-designed non-services architecture has many independent and independently testable libraries. Integration testing does require the whole system, both with and without services. In this case, both the resource usage and startup time is much lower without services. 3) Ditto for services, if you do integration work. Not so for independent libraries, if you do not. 4) Question of where you put the abstractions, not how you make them. 5) Again, question of where you put the abstractions, not how you make them. The key reason for services is isolation, failover, and independent deployability. There are a bunch of programmers out there who were only taught one way to make abstractions (be that services, objects, or what-not), and assume everything else means abstractionless spaghetti code. That's simply not the case. Structured, functional, and other modes of programming have the same quality of abstractions as OO. Likewise for whether you link statically, dynamically, or over a services boundary.
- pron 12y agoNot to mention the big performance hit of marshaling data, and the waste of resource when running separate processes. Another important performance hit has to do with scheduling and multithreading, as crossing IO boundaries (even on the same machine) coalesce all threads into one (and then multiplex the work again on the other end).
- discreteevent 12y agoAlso for 2) the problem of loading everything up front is dealt with by some in process technologies e.g. COM, OSGi. Extremely late binding to statically defined interfaces. You can be productive with that. (more so than microservices in my experience)
- Kiro 12y ago> a single syntax error breaks everything How are microservices usually communicating that avoids this problem?
- ExpiredLink 12y agousually via HTTP
- macNchz 12y agoIn my experience this just results in the service with a 'single syntax error' dumping stack traces while the services that talk to it throw exceptions as their HTTP requests get 500 responses. Noisy.
- possibilistic 12y agoRPC is much better suited for a microservice architecture. Leave HTTP for the leaves. (I wrote a comment about it elsewhere in this discussion).
- ExpiredLink 12y agoRPC is a low level API for which you have to set up and implement many parts that HTTP delivers out of the box. RPC probably not even has a significant performance advantage.
- mcguire 12y agoCould you give a quick exposition of how microservices address difficulties 2-4 (and possibly 1 and 5)?
- possibilistic 12y agoExample: consider an application including the following microservices: "newsletter service" and "email gateway service". The newsletter service doesn't need to load email libraries, handle the protocol, failures, bounces, retries. It doesn't need to maintain state on this. Nor does it necessarily need to know if an email address is opted out. It can concern itself with building newsletter templates, A/B testing, feedback/analytics, scheduling, triggers, etc. Consider how different teams may accumulate specialized knowledge. Now the boundaries of this knowledge are finely delineated. Service responsibilities are clear. As the company and app grows, you can pull stuff out of the newsletter app. You may want analytics and A/B testing as a service. Consider all of the possible service boundaries. If you can group 4-10 tables in a relational database into a cluster, that might constitute a valid service boundary. Does it model a particular business function / flow that can be wrapped up and exposed as a service? Will that grow with company and with changing needs? I don't know how this really helps with RAM. If you're worried about that, you probably shouldn't be considering a microservice. There are operational costs that trump hardware costs.
- mcguire 12y agoBut there's still a dependency tree there: if the email service is down, the newsletter service isn't going to be sending any newsletters to anyone. Likewise, if the DNS service the email service depends on is down. Further, debugging problems becomes more difficult, not less. If a user complains that their newsletters aren't getting sent, you have to track the failure back to the failing service (and the network between them can fail, too), which means involving people from all of the teams in the dependency tree. Naturally, unless the failing service is obviously failing, pinning down responsibility to fix the problem becomes a problem itself, because service responsibilities are never that clear. Microservices do offer more flexibility, while maintaining hard interfaces, and that is worth something. But I don't see how any of the advantages mentioned in the comment I replied to fit in.