Local development environments were a bit more tedious in certain cases, but that was the only issue I recall.
Local development environments were a bit more tedious in certain cases, but that was the only issue I recall.
gRPC might be better, but supposedly so was SOAP, CORBA, DCOM, XMLRPC, and finally REST.
There are other ways to do it as well where the socket connection is only authed once.
At another company that was acquired by Amazon, the "user service" team (so again this is a microservice that exposes a single table of a database, this time with a two-pizza team dedicated entirely to that microservice) told us that we couldn't just query the user service when we wanted to render a page containing a username given a user id, because that was too many queries. Product demands from a VP dictated that we didn't have time to set up our own caching layer for their service (is this the responsibility of every team other than theirs?), so we shipped the feature with the usernames saved in our own DB, and now when users change their usernames the old name will appear in the pages for our feature, depending on when the pages were created.
These days I think that's actually where everything should start off. With a good implementation of this you can transition relatively painlessly to a distributed system, and in the initial phases the simplicity of the build/test/deploy cycle massively lowers the overhead compared to a microservices approach while the strong isolation of domain logic gives you the ability to reason about changes to your domain not affecting other areas of the system.
Having worked in both small companies with terrible monoliths, small companies with terrible microservices, big companies with terrible monoliths and big companies with semi-decent microservices, and then implementing a modular monolith myself, I've seen enough to know that it's a solid, solid starting point. Most companies are pretty small, and the difference between an engineering org of 40 engineers trying microservices vs an engineering org of 4000 engineers doing microservices is on such a different level that people who haven't experienced both likely can't appreciate the data point that they're missing.
I love the strong isolation that microservices provide, and they can be super beneficial, but done at the wrong scale, the wrong level of technical maturity, or the wrong time and they're a huge drag. By the same token a monolith that grows too large for too long is equally a drag, but it's one that's exponentially more tolerable in an engineering org of 40 engineers than it is an engineering org of 4000 engineers. The key thing isn't which architecture you pick, it's the ability to be able to transition and adapt at the right point in time. Modular monoliths buy you this opportunity at a fraction of the price and for much less risk.
My previous employer was a small engineering org of around 40 engineers with a monolith of below average quality, trying to go in a microservices direction and not really having that pan out a great deal due to being unable to spare the engineering bandwidth to invest enough in managing the complexity while still having to deal with the monolith.
My current employer is an engineering org of around 4000 engineers that one two headed monolith that makes up the original product (web app + api share some code and are monoliths in their own right) and also very successfully uses microservices for everything else and there is a lot of them.
At my previous employer dealing with the monolith was fine even though the code was rather horrid, and we would release twice a week. The "microservices" I wound up building/working on there were not worth the overhead / complexity added at all and we would have been far, far, far better off investing in cleaning up the monolith to make it safer/easier to work in.
At my current employer dealing with the monolith is not fine. You have to book releases in a calendar, it's scary, it's giant, and despite multiple releases of it per day, there are so many other teams that book releases for it that you have to queue up to get your turn and it's done that way for safety. Yes, we also use feature flagging too. It's also vastly more difficult to know/find who you have to communicate with about changes to the monoliths because unlike a tiny engineering org, that information simply doesn't fit in your head. Here, the microservices we own are awesome in comparison. They are small code bases that are easy to reason about, our organization invested a massive amount in the technical maturity needed to operate, maintain, and be able to handle the complexity, and we have continuous deployment pipelines that mean we can safely release multiple times per day and when PRs are merged they are shipped all the way through to production in around 15 minutes.
So, when you say "more complex and slower" you have to ask yourself "than what?" There is no "one is better than the other", there is only "every tool is the right tool for some job" and "every tool is also the wrong tool for almost any other job it was not designed for" and your job is to understand exactly what tool your specific situation actually calls for.
This is why I like modular monoliths as a starting point, as they're essentially a multi-tool. A half-way compromise which is not as easy to use as a full-blown dedicated tool, but is versatile enough that if it's the only tool you have and you have no idea what job you're going to need to do, then you've probably made an adequate choice regardless of what the situation calls for in the end. And if you outgrow your multi-tool, you can much more easily swap it out for a set of it's dedicated equivalents.
It's also worth noting that microservices are more secure and reliable as well, since there's no vulnerable component that has access to all of the secrets nor a bunch of components that ought to be non-critical but actually are critical because anything can bring down the entire application for all other components (e.g., someone makes a sync call in some leaf component that breaks the event loop for the whole application, with failures cascading across your replicas).
This is not inherently true. Whether it's true or not is down to your implementation. You can most certainly have reliability and security problems while doing microservices.
Obviously I didn't claim "you cannot have reliability or security problems while doing microservices".
Likewise. When I see people complaining about microservices, more often what I see is actually poorly thought-through strawmen aimed at distributed systems, which boil down to "having to do network requests is bad".
I wonder why attacking the "microservices" buzzword gets these people on rage mode but the sight of a web app calling a dozen APIs somehow doesn't make them bat an eye.
Specifically, I think the strong boundaries between components better facilitates maintainability--as with dynamic typing, the absence of rails allows people to more easily make bad decisions. In the case of monoliths, this usually looks like an inexperienced developer (especially at the bequest of an unscrupulous manager who swears that we will definitely not do this again and will fix in a subsequent release) taking a dependency on another system's private internals. In other words, I assert that given a good architect and an average team, a microservice architecture will be less complex than a monolith despite marshaling data over a network. In order to have a well-engineered monolith, you need good architects and a good team (no unscrupulous managers who are empowered to compromise the architecture in the name of expedience).
> no guaranteed data consistency, no global commit guarantees
You don't get these for free with monoliths either. I've seen a lot of monoliths choc full of race conditions which don't manifest during development (small contrived test cases running on unburdened systems). Paradoxically, because microservices have to marshal data over a network, these consistency issues are more likely to appear. Moreover, people who work on microservices are more likely to think about race conditions precisely because the system is distributed (indeed, the architects think about this stuff when they lay out the interfaces).