Huh? I always thought that the point of microservices was that you can scale the parts that need to be scaled.
For example, I have a main server that serves all client requests. I separate and deploy functions that require heavy processing away from the main server so they can be scaled efficiently. But to the client, it only needs to know that the main server exists.
Microservices are for scaling the number of teams of developers, not performance. Each service you add will add latency and required resources, compared to it just being a function call instead of a http request.
Granted, there are a few cpu-heavy processes that do benefit to being split out, like image/video re/encoding, but if you're just doing "normal" stuff, it's faster, easier to maintain and cheaper to just have a function call instead of a "service" call.
Our team write everything in the main server except tasks that choke up the main server. For example, we have a need to process many CSV files from users. We put this processing on Lambda and it can scale to hundreds of Lambdas at a time. Scaling our main server would be very uneconomical.
Latency is not a problem because these services usually live in the same datacenter and the latency is very little compared to the processing time.
That sounds exactly what I'm describing? What you're doing is not "microservices" (the pattern where most processes are split out, not just "heavy" processes), but splitting out heavy processes when needed, rather than by default.
Scaling businesses, yes. All inter-team communication becoming API contracts enables autonomy in each team. As long as you stick to the contract you can deploy when you want, make the changes you want, etc. without having to bog yourself down in endless meetings with other teams to ensure your changes won't break theirs. In a small organization this may not matter, but in a large organization you might not even know who to talk to, so it becomes a practical necessity to have clearer boundaries between teams in order to keep more people manageable.
What you describe sounds more like Service Oriented Architecture (SOA). SOA is one way – some might say the best way – to keep the aforementioned boundaries strict, so it does often go hand in hand with microservices. But technically you could achieve microservices using shared libraries or even logically separated areas in the same codebase. Of course, the more opportunity you give someone to break the boundaries, the more likely they will which is why especially the last one is bound to fall down in practice.
You could have build-time-enforced restrictions on interdependencies if you wanted to do an SOA-like thing without the runtime overhead, if you wanted to. The real issue is that "logically separated areas in the same codebase" doesn't solve the release-management part of the problem. If you have a monolith, then each team can autonomously control how their code behaves at head, but they all have to conform to the centrally-dictated schedule for when those changes roll out in production. Often this doesn't matter, but sometimes it does, and then you have to have lots of meetings again.
Shared libraries are somewhat better about this, assuming that it's reasonably cheap to restart instances of the monolith, but some kinds of rollout strategies work better if you can divert which release to use at the request level rather than the instance level. Also, in a lot of languages, the tooling surrounding shared libraries just isn't as good.
Microservices can be a result of an agile process. I “invented” microservices multiple times just as a coping mechanism because my teams kept going off in different directions at different paces. And, I needed some way to keep things cohesive.
Interesting, I assume this fixed the issue because you guys could just agree on interfaces and communication standards and then mock each others services until ready?
The worst WTF code I have ever seen in my 30+ years career is a 20+ years old micro-services system. More than 150 (!) services creating a level of incomprehensible complexity and crazy failure scenarios that is breath taking to watch. Imagine the worst spaghetti system possible but distributed! I feel very lucky to just be an eye witness and not having to actually work on the project.
Seriously if you don’t know how to write a well structured easy to maintain monolith (using API’s and libraries to clearly separate components) then the worst thing you can do is to choose micro-services. You go from having N problems to having N^M distributed problems with a whole bunch of added failure scenarios you now have to deal with. Crazy!
And it gets even more WTF when different services are written in different programming languages, using different build tools, with service teams not coordinating their development plans or protocols etc.
14 comments
[ 2.1 ms ] story [ 47.5 ms ] threadFor example, I have a main server that serves all client requests. I separate and deploy functions that require heavy processing away from the main server so they can be scaled efficiently. But to the client, it only needs to know that the main server exists.
Granted, there are a few cpu-heavy processes that do benefit to being split out, like image/video re/encoding, but if you're just doing "normal" stuff, it's faster, easier to maintain and cheaper to just have a function call instead of a "service" call.
Our team write everything in the main server except tasks that choke up the main server. For example, we have a need to process many CSV files from users. We put this processing on Lambda and it can scale to hundreds of Lambdas at a time. Scaling our main server would be very uneconomical.
Latency is not a problem because these services usually live in the same datacenter and the latency is very little compared to the processing time.
https://blog.appsignal.com/2020/04/08/the-citadel-architectu...
What you describe sounds more like Service Oriented Architecture (SOA). SOA is one way – some might say the best way – to keep the aforementioned boundaries strict, so it does often go hand in hand with microservices. But technically you could achieve microservices using shared libraries or even logically separated areas in the same codebase. Of course, the more opportunity you give someone to break the boundaries, the more likely they will which is why especially the last one is bound to fall down in practice.
Shared libraries are somewhat better about this, assuming that it's reasonably cheap to restart instances of the monolith, but some kinds of rollout strategies work better if you can divert which release to use at the request level rather than the instance level. Also, in a lot of languages, the tooling surrounding shared libraries just isn't as good.
Seriously if you don’t know how to write a well structured easy to maintain monolith (using API’s and libraries to clearly separate components) then the worst thing you can do is to choose micro-services. You go from having N problems to having N^M distributed problems with a whole bunch of added failure scenarios you now have to deal with. Crazy!
And it gets even more WTF when different services are written in different programming languages, using different build tools, with service teams not coordinating their development plans or protocols etc.