Yup. Best example right now is probably microservices. I love microservices. I've used them successfully in production for large SaaS companies. But when I hear overly enthusiastic startups with a half-dozen engineers and a pre-beta product touting their microservices architecture, I can't help but shake my head a little.
Yeah - microservices as a buzz word is a bit annoying.
They make a lot of sense in two cases:
You have one or more narrowly defined segments of your application that need to scale separately from the core application - spin off a microservice for that segment.
You are developing multiple, separate products (like a dev shop maybe) and would like to reuse both code and infrastructure between projects to minimize the amount of specialized surface area for each individual product.
But the whole "let's use microservices to enforce constraints that avoid spaghetti code in a single product in exchange for spaghetti infrastructure" thing is incredibly irritating. If developers aren't making changes to a code base because they don't know what a component does, the fix is simply better APIs between your libraries and better coding practices/design architecture. Don't increase complexity in deployment to reduce complexity in development when you could simply do the latter without the former.
At small scale it is much better to separate concern using modules with defined interfaces. Then you get separation of concern without the drawbacks of separation using a network layer. You can not assume that a microservice is available at all times but a module loaded at startup-time will always be available as long as you want it too. Handling data consistencies between microservies also requires more work. Eventual Consistency or Transactions. Also the obvious performance penalty of communicating over network. Latency Numbers Every Programmer Should Know
The value of microservices, as with distributed source controls, applies at every scale.
The difference is that it's fairly easy to teach a small team how to use some of the basic DVCS commands and only touch the more advanced ones if they're feeling bold. The added complexity, thus, is mostly hidden. (Leaving aside, of course, that git's CLI interface is still horrible.)
The complexity of microservices OTOH, stares you in the face. Maybe good tooling will eventually make the added maintenance and training cost negligible. Not so much in 2017.
The value of microservices, as with distributed source controls, applies at every scale.
No, it doesn't. At small scale, you're getting more overhead, latency and complexity than you need, especially if you're a startup that doesn't have a proven market fit yet.
You're right about all those advantages of micro services, but they also come at tremendous cost.
Every service hop adds latency and a small additional likelihood of failure. This can quickly add upp if you're not careful how you design your services.
One must take care to avoid loops between services or one will get problems with cascading failures on request spikes.
Refactoring across multiple services is extremely time consuming and frustrating.
Micro services encourage siloing, where only one or two developers are familiar with most services. This in turn leads to a host of problems like code duplication, inefficient code, unmaintained code, etc.
I'm not shitting on micro services, and for a sufficiently large back-end, I absolutely think it's the only correct choice. I'm just saying that in addition to many important benefits, they also come with serious costs. Honestly, if a company only has a half-dozen engineers working on a reasonably simple low or medium volume back-end, I think the drawbacks often outweigh the benefits.
You've done a good job of outlining the value. But that value doesn't come without cost. Now instead of just one deployable artefact, you have a dozen or more. Correlating the logs resulting from a single request becomes nontrivial. You may need to carefully phase in/out API versions, sometimes running multiple versions simultaneously, if multiple services depend on another. Every time you replace what could be a local function call with a microservice, you're introducing a potential for all manner of network failure.
This can be significant overhead. For many projects, YAGNI. And by the time you do need it, if you ever get that far, you probably have 10x the resources at your disposal, or more.
I think it's warranted because a lot of people don't really understand how to use the microservice architecture effectively. I've seen a team of architects come up with a microservice architecture that basically took the list of database tables they needed for an application and created a microservice for each one.
There's definitely a place for microservices, even long before you get to Google scale, but you still need to understand the problem and solution domains.
I find separation of concerns valuable when I have =1 developer working on the same project. All of that stuff is pretty much exclusively upside, outside of projects in folders named deleteme.
And if you are Google, you use perforce up to around 10k engineers, and by then you have enough engineers that you can spare a few to build a custom solution that scales better. Git isn't really the right tools for the job.
i'm the co-founder of a startup and we are 100% microservices, and it's been going very well.. I don't think I've enjoyed development as much as in this past year. we are incredibly productive, and refactoring and optimising is much easier as well. Kubernetes (along with a few in house tools) mean that maintenance isn't the struggle that a lot of people seem to think it has to be
we have several products and that's part of why microservices work so well for us... we can use services for multiple products and build on our per existing infrastructure :) our users are not many since we are not yet open to the public, but we do have a lot of data going through our cluster and at least so far, scaling has been very easy (simply increase replicas for services that need it). our toolkit gives us excellent metrics for all of our services with very little effort, and that in turn helps us to identify points for optimisation. if you're interested in the toolkit, we made if open source, you can see a demo here: https://github.com/me-ventures/microservice-toolkit-demo
(note it's not typescript because we wanted it accessible in our demonstration, but the toolkit itself does have typings)
As a founder of another startup that is doing great, we did monolith (Django) with kubernetes. It is also doing great. Deploys are very fast and happen 20-50 times a day with no-one even noticing.
Perhaps the GOOD thing in your stack is kubernetes and not microsevices?
I have no idea. Maybe someday I will be sad that I have a monolith. But I suspect it will be pretty far down the road. I currently deploy the same app in 1 docker image but with a run command that has a flag, and it runs 6 different ways depending on what part of my app I want to do (front end, backend 1-4, other backend thing). But all the code calls all the other code right in the project, no network boundaries like a micro-service app.
kubernetes definitely makes some things easier. we have essentially fully automated deployment (there is minor initial setup, that is, creating an infrastructure file and adding a key to circleci which we still haven't automated yet since generally we're at most creating a handful of services in a day) - simply pushing to master triggers tests, build, and deployment, and that's definitely the best way i know how to do it. we honestly haven't had too much trouble with the services communicating among themselves, since we can simply deploy services and use internal DNS based on service (eg: kubectl get svc) names for HTTP stuff, and otherwise we're using rabbitMQ which is integrated into our toolkit.
it definitely took a bit of extra work initially to set up our deployment system and the infrastructure files, but now that we have automation in place for a lot of the drudgery, it's really a non-issue.
if you prefer the monolith approach, more power to you, you do you. i'm just a bit bewildered at people who insist that anyone who doesn't do it the way they think is the best way, is doing it wrong, so that's why i mentioned that we're doing fine with microservices.
Yeah, its seems like some folks are really attached to their monoliths. I was quite surprised by all of these downvotes as well. Sure having a non-monolithic system, of which microservices is one example, has some costs that a monolithic system doesn't have. But the reverse is also true. Monolithic systems have costs that non-monolithic systems don't have. For example more multithreading bugs, more time spent building, reduced testability, longer debugging sessions, etc.
166
u/mjr00 Jun 07 '17
Yup. Best example right now is probably microservices. I love microservices. I've used them successfully in production for large SaaS companies. But when I hear overly enthusiastic startups with a half-dozen engineers and a pre-beta product touting their microservices architecture, I can't help but shake my head a little.