Also, I don't agree with:
> Since these components are doing different things, there is little chance that there would be a performance benefit
Complementary workloads should not be a problem. It would actually make thrifty usage of the hardware.
The only reason I see for breaking the app this way would be to enforce low coupling.
- build v1 in the monolith
- do users like v1?
- if so, does v1 use too much of the monolith?
- improve the implementation within the monolith
- does it still use too much of the monolith? Break it out into its own stack
I believe there are only two stacks:
- ad serving, where literally lower latency is more money and thus benefits from optimizations not realistic within the monolith,
- and "everything else".
DHH of Basecamp also argued recently [2] that Monoliths can make sense although I noted at the time that, with a team size of about 12 engineers, that isn't much larger than the two-pizza team sizes you see promoted for microservices functions.
[1] http://martinfowler.com/bliki/MonolithFirst.html [2] https://m.signalvnoise.com/the-majestic-monolith-29166d02222...
Which is a big deal...
Microservices enable easier code re-use and division of labor across teams, especially when persistent data is involved. It is a technical solution to a people/economic problem and not the other way around. At a high level, I think of all the popular APIs powering the web (Stripe, Google Analytics, Twilio, Intercom, etc.) and how they enable developers to do their work more efficiently.
"Buy vs build" was mentioned as a promising attack on accidental complexity in "No Silver Bullet". If you design your microservices in a way that they're usable in different contexts and don't build at all when a paid or open source solution is available, you will boost your productivity.
In fact, the application was already written this way and it was never enforced. This makes no sense to enforce if it wasn't already broken.
Discussions on this topic are typically mired by a lack of conceptual clarity†. Are we describing a monolith in terms of the process model, or the deployment model?
In context of scale-up/scale-out concerns, we would be considering the deployment model.
In context of loose-coupling and extensibility, we would be considering the process model. Postgres is a classic example. [1]
[edit: note above are not mutually exclusive.]
Naturally, an increase in the number of moving parts places additional orthogonal demands in terms of operational integrity. As with any upward clicks of complexity, the decisions should be informed by valid‡ requirements and facts.
Ok, done with my mini rant /g. As to your query, in certain cases a monolith is indeed worthy of love.
[1]: http://raghavt.blogspot.com/2011/04/postgresql-90-architectu...
† Not a surprise in a field celebrating its unique brand of "senior engineers with 3 years of experience"...
‡ No, hype cycles are not valid architectural and/or business requirements.
http://blog.cleancoder.com/uncle-bob/2014/09/19/MicroService...
http://blog.cleancoder.com/uncle-bob/2014/10/01/CleanMicrose...
I'm stealing this. Fantastic way to highlight motivation for certain techs.
Here's a piece I wrote for Codeship breaking down the problem and how Heroku can seriously insulate you from the complexity of microservices. https://blog.codeship.com/exploring-microservices-architectu...
This allows me to scale the API to handle load independent of the app itself, since that's just static assets, it doesn't need it as much.
On the other had, if I was running multiple threads that all cached data from the same data store, it is quite likely that scaling up threads in the same JVM would have a massive advantage over splitting them into multiple JVMs.
Also, in the comments I admit that over 10K applications on 1K machines, it's probably better 99% of the time not to use 10K JVMs. There would be a huge CPU/Memory overhead....
> Complementary workloads should not be a problem. It would actually make thrifty usage of the hardware.
The argument continued "there is little chance that there would be a performance benefit from being in the same JVM". Splitting the two components out into separate containers doesn't preclude running them on the same hardware. But it does give you the option of running them on separate hardware, which may allow for even more efficient overall hardware usage.
* the L1, L2, L3 cache friendliness
* the inlinings that JITs can provide
* the temp variable eliminations that JITs can provide
* the ability to do zero copies
You would add:
* the overhead of the full http stack, if this is done in REST
* the network latency, if this is on separate hardware
If you care about latency, just forget splitting it. Worst cases could be going from nanoseconds to milliseconds.
If you care about throughput, it could help in offloading; but don't expect 2 to be split into 2 x 1. You would be closer to 2 x 1.5.
AWS is supposed to give us soon some new shiny X1 instance types. Before scaling forces you to split, there is plenty of room for pretty beefy monoliths with 2TB of ram and 100 vCPUs.
For some future optimization?
[1]: http://stackoverflow.com/questions/1636238/difference-betwee...
[2]: https://jaxenter.com/introducing-the-java-ee-web-profile-103...
aside/ Sun Microsystems really blew it on the pedagogical front. Hopefully future tech leaders will reflect on SMI's failure to take advantage of (imo) 20+ years visionary head start in design & architecture.
Docker has fast become my world: from local development and detailing of dev setups through to deployment of apps using ElasticBeanstalk's single-container Docker pattern.
The dev setup piece is seeming the most valuable currently. That you can land in a project that I've been in and issue `docker-compose build`, `docker-compose up` and have a fully functioning development server without the need of installing a half dozen dependencies locally really does feel like a positive.
As a devopsy-leaning person the "single binary" deployment it lends toward is beautiful too. Pragmatism always though: for many of our services the network IO impact is undesirable, so we use go (statically linked binaries) on bare metal for those.
http://stackoverflow.com/questions/21889053/what-is-the-runt...
If you have multiple applications, I'd definitely put each one in a container to beef security up.
This now has me wondering if I am a bit more drunk on the container koolaid than I may have thought!
The two main business values I have found from splitting something up is 1. independent scaling and 2. independent development teams. Other than that most is preference and philosophy. You can get to the right answer for the wrong reasons, it doesn't mean you were right.... :-(
I know the last advice goes against the common wisdom, but in my experience this is so.
"Multiple copies" meaning "more than 2", excluding master-slave configuration.
But at this stage, containerization is practically begging to be done, becoming a pressing need. If you have to ask the question, it is probably too early for that. :)
Amen. Treat your software as the sum of it's parts rather than a bunch of parts that will do.
For example, if a component can communicate over Unix sockets, then one can put it into own container with networking disabled. Similarly one can selectively choose which part of filesystem is accessible with read or read-write access.
From the microservice perspective a single service is supposed to be a vertically integrated set of functionality all the way from data to the UI, instead of horizontally segmenting API services and UI. Horizontal segmentation doesn't give the same team-scaling benefits since it still takes significant inter-team coordination to deliver functionality.
So the example is really a single "service" that just happens to include multiple processes.
Also Containers will some day have their place but at the moment they are just not ready for 70 % of the workload. it put's just too much complexity on your system. Also Microservices add a lot of complexity, too, which is easy too handle if your team has a certain size, but without prober tooling, management services it's really really hard to do it.
Never!
Use Go and build a single static binary that does everything and fck this fancy container technology , that split this into that, sandboxes it and and other security sht.
Disclaimer: I don't work at Google, RedHat, DHL or anything remotely associated with Go, Containers , shipping.