A pattern language for microservices
microservices.io
microservices.io
Although I am working on one platform like that right now (see https://github.com/1backend/1backend) the reason I started it was more the fact that I could not easily deploy a custom tiny service and call it easily.
We have solved both problem with 1Backend: launching a new service is as easy as creating a git repo on GitHub, and calling them is just like calling a library with the autogenerated clients.
That being said, until a project like 1Backend matures, anyone who starts their startup on a microservices architecture instead of a simple monolitic one is out of their skull.*
I have personally watched millions and millions of dollars burnt on building on such platform while our competitor (Uber) became one of the biggest unicorns the world has ever seen.
Don't be that startup! We managed to screw it up with 100+ million dollars in funding, which was (is) extremely exceptional in Europe. Of course the tech was only part of the reason for failure, still: there are better way of spending money than chasing bugs across hundreds of services and building instrumentation.
*Edit: this sentence of mine was very unfortunately worded and said the exact opposite of what I meant. Hopefully the tons of upvotes I got was because that the upvoters correctly inferred from the context that I advice you to start with a monolith, and not with microservices. Thanks.
- if you need to scale the number of teams working on the same product you need to introduce microservices to make the teams work independently from each other.
- if you need to scale the (monolith) service and it is too expensive to just scale it n times. microservices can help because you can scale each microservice independently.
- that's said the overhead is real. There have been quite a few publications and advocates (like Randy Shoup) that staying monolith is fine until you have pain that a microservice architecture can ease.
All those reasons are very fine ones - but it's still a dangerous move to go microservice style. You have to know what you are doing, and in our buzzword driven industry that's not the case usually.
Little insidious time wasters will creep into your work flow and they will lurk there eat away dollars and you won't even notice.
I constantly switch back and forth between working on monolithic and microservice apps and for the majority of companies sticking to a monolith until the pain points you mentioned become unbearable is the good call.
Even then, just break down your apps to bigger sized services, and stop when the pain goes away. Microservices is a catchy name but if anything micro is the poison there.
What do you consider as the most important things that people are do wrong?
Also, could you enumerate the time-wasters? Off hand, besides occasionally having to re-consolidate the architecture, I can’t think of many. It would be good to know how much the time-wasters cost in contrast to the alternatives.
You can do that by several different ways. Overall, if one wants a "one size fits all" answer to how to break code into teams, it is by breaking the code into libraries, not services. Services are a niche tech here, to be considered when the others won't suffice.
> if you need to scale the (monolith) service and it is too expensive to just scale it n times.
Again, nearly every time this happens, the correct answer is to refactor the monolith so replicating it scales. Services are only for those cases where this won't suffice.
I don't think I disagree with how you think. But I do think your comment is easily misunderstood and harmful without those qualifiers.
2) agreed ! thanks for adding the qualifiers !
If you release a new version 1.1.0 of a library you have to update and redeploy all applications that use this library.
Most of the hatred towards microservices is probably better directed at REST, which is a good paradigm for serving documents to web browsers but is overcomplicated for microservices. RPC is a good alternative, and gRPC is a good implementation of it.
[1] My phone autocorrected this to “deplorable”, which is also a good adjective for a monolithic web application that contains lots of libraries and is only deployable as one artifact.
If you understand binary compatibility you can deploy a library without deploying its client applications/libraries (they would need to be restarted, however).
In fact, this is one of the very reasons people invented shared libraries! It's why, for example, Linux distros are based on shared libraries: one can update large swaths of the system by updating a single package.
If your languages don't support this then it would be very unfortunate indeed.
It sounds like you're saying that a single micro service maps to a team. Do you think each team should manage many micro services and how many do you think each team should manage?
I'm generally interested but having been the guy on dev teams to handle most of the configuration management stuff I've not really been willing to listen to micro service advocates.
Depending on runtime environments/architectures the CM costs sound prohibitive at best.
This meant, for example, that my team, had our whale, an audio transcoding service, an automated transcription service, a post-phone-call messaging service, and several data integrations.
If you need a whole team to do nothing but maintain a service, it seems to me like you built it to do too much.
it also depends on your infrastructure to manage services. if setting up, managing, deploying and monitoring a service is cheap it can make sense.
The nature of software for managing humans is that it's very fuzzy, fashion/tend driven, diverse.
E.g a recent trend is for companies to try and reduce the number of undesirable applicants they get for jobs (since in a big e.g retailer, saying no to a candidate is likely also saying no to a customer).
So customer now needs to inject an e.g culture fit quiz into the candidate experience, which only unlocks the apply button once the candidate has "passed".
This kind of tweaking and evolvement is not possible within a monolith, so good APIs allowing vendors of the customer's choice to inject functionality are essential.
That functionality can then be injected in the form of a small app that does one thing and does it well, has it's own database, i.e has many of the characteristics of what people think of as microservices.
To Martin Fowler:
> In short, the microservice architectural style [1] is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.
Assembling HR ecosystems from separate apps certainly meets all of the points above.
From what I'm seeing, the microservices style is commonly being used for much smaller services a la Unix, typically for reuse across an org. Introduces too many issues around SPOF, orchestration and queuing, versioning, discoverability. I think Lambda is the correct evolution for making that work (if nothing else let AWS figure out stuff like failover, deployment, and the standards for fabric between functions).
That's not the way the industry works.
Some exciting, specialised startup develops some kind of cool UI blended with some psych validated content, and manages to get it installed at a couple of large reference clients, and then finally manages to draw a link between the quiz results that candidates achieve, and their ultimate chances of successful employment (maybe just getting hired - maybe their on the job performance after X months).
The customer is buying into this package of leading edge stuff. They don't want their existing vendor to have some junior developer hack something up and put it behind a feature flag. They want the new shiny stuff, and they want it from the new shiny vendor.
The code behind such a quiz is usually trivial - the intellectual property not so much.
"Monolith First", Martin Fowler
If you have a monolith or two you can easily do one off tasks manually and forget about them forever, with microservices it's all about automation.
There are many possible benefits of microservices, few of which outweigh the massive costs for many (dare I say most) startups.
I agree in general the tools are lacking but if you use AWS,GCP, or w/e you get a huge boost on the tooling.
I hate this phraseology, and IMO it's a telltale sign of a new or inexperienced professional developer (another variation: "replace jet engine while in flight"). All non-greenfield development forbids breaking the existing system in order to make changes. This is a daunting responsibility, but it's inherent and assumed, so only college kids who have never had to maintain a running system before talk about it like it's noteworthy.
If someone needs a microservice architecture to support team growth, it just means they don't know how to manage a team, and have to let every dev or pair of devs have their own little kingdom.
I see the point of microservices for cases where you want to use different tech stack for one part of system or need special scalability. I don't see the point in going that route to only have separation between components or being able to split work.
If you are afraid that you won't get the monolith architecture right, you should be afraid of the same thing with microservices.
Funny that you picked this example given that Uber itself is known for heavily using and popularising microservices: http://highscalability.com/blog/2016/10/12/lessons-learned-f....
I don't think you can apply the lessons from a startup burning billions per year in many other places...
Services work well when you have one or two services per team, the problem space is divided in the right places and the teams provide a service to each others, not code.
When you see more services than developers it's often a bad sign.
We have services that were built and are in the background because they are effectively finished (for now.)
An example would be a service that handles a third party integration. It might get a commit a month once it's built.
From my limited perspective, I look at two warning signs: Do changes require changes to more than two services on a regular basis? Ideally, the majority of changes are limited to one service. If you're propagating changes up a stack, it is going to be a slow change. (The whole point of microservices is that once set up, you can move faster, right?)
If your microservice code is significantly harder to manage than your monolith, you've factored it wrong. Which means you shouldn't find yourself constantly working on 6 or 7 different services at once. If so, try a different decomposition.
Saying one team per service is like saying "a team should only handle one or two classes".
I'm working on a project called Lightbus which I'm hoping will find a use for applications which sit somewhere between microservice & monolithic:
https://github.com/adamcharnock/lightbus
I'm aware that this has all been done before to an extent, so I'm trying not to reinvent the wheel and learn from the past. Advice, critique, or encouragement is very welcome indeed.
Don't be fooled into believing that microservices are popular based on technical merit. As the parent noted, this will just make things harder by trying to micro-ize a startup. Microservices are a thing primarily for their political convenience and dynamic, and they're just dressed up as a technical thing.
[Sideline: most of our technical fads are this way. Err on the side of "letting developers feel important and special while requiring as little effort as possible". Cloud servers are this way because it makes Unix greybeards transparent, and the brogrammer won't have to feel inadequate next to him/her, OR worry about esoteric command-line incantations. Document databases are this way for the same reasons, but replace esoteric command-line incantations with esoteric SQL aggregates (or any useful schema development at all, actually) and greybeards with DBAs. Rinse and repeat for every major development fad.]
Microservices are popular due to Conway's Law [0]. They give an out to people who would rather avoid the difficulties of interfacing, deliberating, and collaborating with other people in their organization. They don't have to decide on a common language, they don't have to decide on a common style, they don't have to do anything; they can go run amok, treating the company codebase as their personal playground, under cover of "super cool new-wavy best practices". "Google is doing it. You want to be like Google, right?"
There are potential good designs that would qualify as "microservice architectures", but I've seen them only rarely. What I see more often is what I like to call "brittle-services": dozens of tiny, fragile, interdependent units that are virtually impossible to debug, instrument, or reason about cohesively.
At $DAY_JOB, we have tons of these; if one service starts to slack off, there is a giant waterfall -- ahem -- of failures that cascades across everything else. The software has been structured this way for purely political reasons, even though no one would be willing to admit it.
Like everything else important, good software design boils down to designers with substantial experience, good judgment, and the authority and respect to see their designs faithfully implemented. Unfortunately for the hoi polloi, it can't be generalized into a formula or paradigm like "use microservices", but it seems in any field, there are many posers eager to try.
You sound extremely bitter, and extremely pompous with your "all the other devs are just dumb, I'm the only one who can see through the hype" attitude; especially your comment about younger developers.
> good software design boils down to designers with substantial experience, good judgment, and the authority and respect to see their designs faithfully implemented.
Like this - projecting much?
Microservice architecture is a tool. It isn't a replacement for you or your job. It isn't a replacement for communication. There is a recognition that Conway's law is a serious problem in orgs as they scale - microservices (in part) attempt to deal with this.
There are many other benefits. It makes things like DDD easier, since your domains and services can be tied closely together.
It makes scaling at a finer grained level easier - a problem a lot of companies may run into as they scale from a few customers to many. I've certainly run into this problem at a company that was moving from distributed monoliths to microservices.
It has downsides - a more complicated rollout / deployment structure, less shared knowledge of services, and others.
Acting like it's only hype or just 'those darn young devs' makes you sound really silly, especially as someone who's seen Microservices both fail miserably and turn things around completely (in a positive way) for companies.
You say it comes down to experienced developers making good decisions - can you not see that Microservices are designed to help with that? The way you break apart your services, their domains, the 'bounded context', etc is all a tool to help you build things well.
I didn't say anything about "younger developers". Which comment are you referring to specifically?
Also, I hardly think I'm the only one who can see through the hype. Check out the rest of this thread. Most of the replies, including the parent post to which I was replying, could be characterized as anti-microservice.
Tech fads are rarely about good developers. They're normally about non-developer technical managers and/or bad developers, who are sometimes more self-aware than they appear at first glance and are consciously seeking diversions. Good inexperienced devs may be taken in by the first fad or two, but they generally come to realize that it's same shit, different day within a few years, and their skill level limits the direct damage (though their adherence to the fad may set the stage for additional indirect damage).
It was not my intent to offend or accuse anyone by criticizing this particular tech fad, and I'm sorry that you appear to have taken it personally.
---
I don't think we disagree about "microservice architecture" as a tool. Like all tools, it needs skilled practitioners to be used well. "Microservice architecture" is a bad descriptive term for a tool because it's too broad to have much specific meaning, but I accept that some people could use it to describe something decent, which I've already stated.
As my post said, however, I was discussing "microservice architecture" as a fad, which, let's be honest, is the case across the vast majority of cases in which the term "microservice architecture" is used.
People who aren't blindly chasing buzzwords are more likely to think of their architecture as a holistic entity built from a variety of useful and specific components rather than a zipped-up incarnation of a single $HOT_TREND, and are thus more likely to describe it descriptively, e.g., "we try to employ a reasonable separation of concerns", "we have a handful of independent services on the back-end", etc.
These things show a thoughtful, specific consideration of principles rather than literalist word-thought, and it's a good guideline (but, like all guidelines, imperfect!) for whether or not someone has processed what they're discussing or whether they're mindlessly mimicking the people they consider authoritative/influential.
It was not my intent to offend reasonable, thoughtful engineers who have implemented what they call "a microservice architecture". I meant only to indicate that this terminology is a red flag for a tech fad, under which many unreasonable, thoughtless "engineers" are seeking cover.
My personal recommendation would be to consider the terminology lost and not develop a new buzzword to replace it, as that will surely become lost too (see also: "SOA"/"service-oriented architecture", the previous incarnation).
By spitting up your application you basically throw away everything a database gives you as far as ordering and atomicity. And you end up building a giant distributed database yourself.
Stay away from microservices. I've seen people try to make it work multiple times, the overhead for failure scenarios, lack of distributed transactions, and eventual consistency multiply the size of the codebase
Rather, look at these patterns as solutions for problems that worked for other people, and try to adapt that to your own situation. You're almost certainly going to come up with something more simple and reliable in the process.
100-1000x better performance, 10x reduction in machines used, ~100x reduction in number of processes, >100x improvement in reliability, deployment changed from "oh my god" to "copy this jar here", output improved, quality improved, development times improved etc.
https://link.springer.com/chapter/10.1007/978-1-4614-9299-3_...
There can be good reasons for microservices. There rarely are. The Fred George piece that (I think) introduced micro services as a distinct concept specifically pointed out that they must be independent, that is, if one of the services fails you don't get that one service and that's it. Almost all real-world instances either fudge this or just blatantly disregard it.
Isn't an erlang actor basically a microservice, or perhaps nanoservice? Is the difference simply that the Erlang runtime takes care of logistical issues like addressing, marshalling, and deployment that are big time sinks in a "normal" microservice architecture?
http://blog.encapsule.org/early-encapsule-project-history/20...
(Example: https://www.youtube.com/watch?v=QjJaFG63Hlo)
I'm not saying that message-passing is magic and transparently solves all the problems associated with distributed computing, but conceptually it's different from RPC. In fact, it's kind of the opposite of RPC. Keep in mind that Smalltalk 72 was developed in the same environment (Xerox Park labs) that gave us Ethernet and developed large parts of the conceptual framework underpinning our modern networking.
That, before OOP turned into the ConfigurationParserSecureProviderCollectorGeneratorFactoryFactoryFactory disaster.
Alan Kay on RPC: "The people who liked objects as non-data were smaller in number, and included myself, Carl Hewitt, Dave Reed and a few others – pretty much all of this group were from the ARPA community and were involved in one way or another with the design of ARPAnet->Internet in which the basic unit of computation was a whole computer. But just to show how stubbornly an idea can hang on, all through the seventies and eighties, there were many people who tried to get by with “Remote Procedure Call” instead of thinking about objects and messages. Sic transit gloria mundi."
Source: http://mythz.servicestack.net/blog/2013/02/27/the-deep-insig...
I think it's naive to design and implement something without the assumption that it will turn into such a disaster. The average skill level of the average person is much lower than anyone reading HN is going to assume.
Instead of releasing pure, useful things that require good judgment to implement, we need to think very lowly of users and make something that is brutally difficult to break, destroy, or corrupt. It will still get broken, destroyed, and corrupted, but we need to build things under the assumption that virtually everyone is going to do it wrong, because they are.
It would be fun to see a development environment designed under that principle, v. the academic "everyone is going to use this judiciously" paradigm that we see governing much of it. Maybe cloud computing and serverless functions is a prototype?
Makes me feel like this is about content marketing more than about defining a standard.
Preparing to scale may be good, but those technical choices tend to add their own complexities (as random example, see the Saga pattern [1]). Need to think if you should be building platform that can manage 10M active users or is it more important to add features that get you the first 100.
Couple of days ago there was a discussion on HN about Instagram. Somebody pointed out why they went with Python instead of something more suitable for large codebase. This seems to be quite common theme - companies who made it big facing growing pains because of doing things "quick and dirty". This led me thinking if this "let's get it running and worry about growth later" thinking is the reason why they outperformed their competition.
[1] https://blog.bradfieldcs.com/you-are-not-google-84912cf44afb
This looks like a great set of templates for setting the tone and expectations on a project. Will definitely use.
Most people don't work at a company like Netflix though.
Later the idea was promoted in software, https://en.wikipedia.org/wiki/Design_Patterns
I've seen a lot of horrible designs bundled with visio diagrams made by "architects" and good designs described in a txt file made by system engineers.
I think the biggest conflict here is scale of the services involved. For smaller scale - which is what most people are familiar with - monolithic architecture can offer distinct advantages. At scale though? Monoliths have been relentlessly excised for years because of all the very real scaling and maintenance problems that go with them.
I wouldn't be surprised that Google, Microsoft, Amazon, Facebook, Apple, etc. use microservices heavily.
But I think it's more, the scale of the companies, rather than the scale of the services. When you've got a lot of developers—thousands or tens of thousands, on hundreds of teams—having independent microservices is surely the way to go.
But, when you're a small company, with ~10 developers? It's not.
Microservices is the new snake oil :D Now downvote me into oblivion :)
Downvotes definitely won't be coming from me :-)
I think you'd be surprised how much the problems of those "some major tech companies (Google etc.)" don't match the problems of up to medium companies, which make the vast majority of technology use in total.
I've got pretty extensive experience with the Google stack. At Google's scale, there's really no other way to solve the problem. However, there are very real costs to all those process boundaries that make you move much slower. When I started there (2009), the common wisdom was that if you were trying to launch a new product, you absolutely did not want to pay those costs unless you absolutely had to; go start with a single binary that interfaces with BigTable/AppEngine/SSTables and see where it grows from there. When I finished there (2014), the common wisdom was "don't launch a new product".
Google can afford to not launch new products (or see all their new products fail) because when adding a new feature to an existing product can make $100M+, that's a lot more economically sound than taking a risk on something new. Your startup cannot afford to not launch a new product. Don't follow Google.