Hello everyone!<p>We have been working at my company for a few months decoupling our 5 years old monolith to a bunch of 'micro' services (we are starting to drop the 'micro' part...) and I am totally confused...<p>What kind of utopian code needs to have the monolith for a kinda smooth transition to services? Let me elaborate<p>Our code is a f<i>?_ing mess. Domain objects using injected services, business logic in aspects, the most coupled tests that you have ever seen (really), defining constants at the very end of the class (f</i>ck this particular piece of code!) and so on. It looks like the code has been written without any kind of affection by the 'gurus' who now are Big Data experts or Data Science (duh!) in their new roles (never our fault!).<p>We were aware of all of this but we didn't imagine how much it would impact our architecture migration (noobs!) So now we have our classic huge monolithic and a bunch of services (5 in production and 8 WIP).<p>Developers don't want to spend any time in the monolith because it sucks, we are expecting to have more and more (and more) services so the system's administrator and operations guys are close to explode, due to the highly coupling the entire system needs to be deployed at the same time which we solved using green blue deployment but it sucks.<p>All the code problems now become code and infrastructure problems. What was a highly coupled code, now is a highly coupled infrastructure. We had only one scalling problem to solve (the monolith) and now we have N problems.<p>I knew that the migration was going to be frustrating, but not this much... The ammount of technical and non-technical problemas it's too damn high!<p>Beware of micro/small/any service architecture! All your coupling problems are going to shine!
If you can't roll a service out independent of some other process, you don't have a service based architecture, you have an even worse monolith. You are blaming other people for problems, you yourself (or your team) are introducing.<p>Pulling out the code is not what is important typically in these sorts of migrations, what is important are:<p>1 - getting product definition about when/where you can loosen your consistency constraints on your data.<p>2 - building specified protocols between components that can support backwards/forwards compatibility.<p>If you continue to need strong consistency and can't support backwards/forwards schema changes in your shared data, you cannot build a service based system and would be better off improving your monolith.<p>PS: There isn't anything wrong with monolithic designs (cause that word doesn't really mean anything) for a huge swath of the technical world. If your team wasn't able to develop a good monolith it is incredibly unlikely they will be able to develop a good service based system.
In my experience, the code monolith doesn't need to be utopian/pristine in order to refactor to microservices, but it does need one thing: each (potential) microsevice MUST own it's own datastore.<p>If I have a widgets service, and it shares a datastore with my foobar service, things become very tricky to refactor. Furthermore, if every update to the widgets table requires an update to the foobar table, the unnecessary complexity is still there.<p>So before decoupling to microservices, I would try to refactor the monolith such that each future-service is storing its own data in a silo. This usually requires non-trivial changes to the way your apis are being consumed, and thats where the real work comes in. It also takes embracing some data design patterns that folks might be uncomfortable with (redundancy, inconsistency, etc). But once you jump those hurdles, you're usually good to go.<p>Hope that helps. It's not easy, by any means, but it is worth it (IMHO). But oh, yes, you're definitely going to need a strong devops/ops team to keep a suite of microservices running. Containerizing each service (such that the ops people don't have to maintain N different server types) is a good first step towards making their lives easier.
Cutting your project up and putting the pieces on different hosts and calling them microservices doesn't make it true.<p>Some links that wil hopefully be helpful:<p>- <a href="http://www.infoq.com/presentations/scale-gilt" rel="nofollow">http://www.infoq.com/presentations/scale-gilt</a><p>- <a href="https://www.datawire.io/microservices-stories/" rel="nofollow">https://www.datawire.io/microservices-stories/</a><p>- <a href="http://shop.oreilly.com/product/0636920033158.do" rel="nofollow">http://shop.oreilly.com/product/0636920033158.do</a>
Your system needs to be designed, not just merely torn into (micro- or
otherwise) services. Microservices approach is not a silver bullet that
magically untangles all the mess. And microservices can be tangled as much as
a monolith, barring difficulties with shared memory, so no clear gain here
either.