Skip to main content
added 2853 characters in body
Source Link
Arseni Mourzenko
  • 140.8k
  • 32
  • 363
  • 550

when should each be used?

Instead of deciding, right now, what needs to be used for your next project, follow lean and postpone the decision until you have a clear picture that one of the other is a perfect choice for this particular project.

This means that you absolutely need to make the move as painless as possible. And then, the project will grow organically, and eventually become a monolith or a set of microservices.

Example of a correctly managed project:

A team of Java developers start working on a new website. The website is a success and continues to grow, starting to look like a monolith, based on Spring. At a given moment, they need to add a specific feature, which is very close to what was done a year ago by their colleagues. However, their colleagues are Python developers.

They discuss the possibility of exposing their colleagues' work in a form of a REST service. At the same time, five of the Java developers decide to work on a very specific part of the website, which would eventually become a standalone REST service. Microservices framework is set in place.

Two years later, it is decided, for performance and management reasons, to merge the now six different REST services into a single monolith. The one in Python is rewritten in Java, and six months later, the project becomes once more a monolith, with a single code base, single continuous delivery pipeline and easier workflow.

Example of a project going bad:

A website grows organically. Nobody has the skills or the time to think about the overall picture, and while everyone agrees that a monolith doesn't make sense, using SOA is not an option: the management wouldn't allocate any funding for such drastic changes.

The problem here is that it's too painful to move from one architecture to another. With time, technical debt would accumulate, and it will become even more difficult to do the move.

Another example of a project going bad:

A team of developers are asked to start a new project. They all are enthusiastic at using microservices—they have never used them, but they understand that it's fashionable and should be fun.

Two years later, when someone needs to do a simple fix that could have been implemented and pushed to production in a matter of minutes with a monolith, the person needs to spend one month and a half doing meetings with multiple teams, changing the interfaces of the services, and trying to figure out how the delivery of each service should be done in order to avoid impacting other services.

The problem here is that the choice of an architecture was made too early—and appeared to be wrong. If people working on this project are skillful and open-minded, there is chance someone would mention that a monolith could be a better option here, and a move would be performed.

when should each be used?

Instead of deciding, right now, what needs to be used for your next project, follow lean and postpone the decision until you have a clear picture that one of the other is a perfect choice for this particular project.

This means that you absolutely need to make the move as painless as possible. And then, the project will grow organically, and eventually become a monolith or a set of microservices.

Example of a correctly managed project:

A team of Java developers start working on a new website. The website is a success and continues to grow, starting to look like a monolith, based on Spring. At a given moment, they need to add a specific feature, which is very close to what was done a year ago by their colleagues. However, their colleagues are Python developers.

They discuss the possibility of exposing their colleagues' work in a form of a REST service. At the same time, five of the Java developers decide to work on a very specific part of the website, which would eventually become a standalone REST service. Microservices framework is set in place.

Two years later, it is decided, for performance and management reasons, to merge the now six different REST services into a single monolith. The one in Python is rewritten in Java, and six months later, the project becomes once more a monolith, with a single code base, single continuous delivery pipeline and easier workflow.

Example of a project going bad:

A website grows organically. Nobody has the skills or the time to think about the overall picture, and while everyone agrees that a monolith doesn't make sense, using SOA is not an option: the management wouldn't allocate any funding for such drastic changes.

The problem here is that it's too painful to move from one architecture to another. With time, technical debt would accumulate, and it will become even more difficult to do the move.

Another example of a project going bad:

A team of developers are asked to start a new project. They all are enthusiastic at using microservices—they have never used them, but they understand that it's fashionable and should be fun.

Two years later, when someone needs to do a simple fix that could have been implemented and pushed to production in a matter of minutes with a monolith, the person needs to spend one month and a half doing meetings with multiple teams, changing the interfaces of the services, and trying to figure out how the delivery of each service should be done in order to avoid impacting other services.

The problem here is that the choice of an architecture was made too early—and appeared to be wrong. If people working on this project are skillful and open-minded, there is chance someone would mention that a monolith could be a better option here, and a move would be performed.

Source Link
Arseni Mourzenko
  • 140.8k
  • 32
  • 363
  • 550

In addition to the answer by candied_orange, there are two more important aspects: the technical stack choice and the interfacing between the parts of the system.

With microservices, it is not only possible, but easy, by design, to pick different technical stacks for different services. One team can develop a Ruby on Rails service hosted on Linux in-house, while the other team decides to use C# hosted on Windows servers in Microsoft's cloud. And it all works seamlessly—at least until you get to the subject of authentication and authorization.

While different stacks can be used with a monolith, this is not a common practice. Suggest, in a context of a monolith made with Java, to develop a new part of it in Python—the reaction won't be too enthusiastic.

At management level, this means that if the product needs to be developed by teams with very disparate skills and affinities, microservices could be an interesting option. It also means that if the members one team working on one of the microservices decide that they could benefit from moving to a different technology, they can do it, with zero impact on the whole system. The other teams working on other microservices don't even need to be informed of the move—it should be transparent to them. A REST endpoint remains a REST endpoint, no matter what's behind: Python and Flask, or C++ and Crow.

This brings us to the second aspect: the interfacing.

With microservices, most parts of the system communicate, usually, through REST (although other choices are possible). This means that most programmers would if not be experienced in REST, at least they would have a basic idea of what it is, meaning they could be operational fast once they join the team.

With a monolith, interfacing choices could be driven by the primary technology being used to develop the monolith—Java Message Service, Spring, WCF, COM+, you name it. While those things make perfect sense when starting the monolith, they could become a nightmare twenty years later, especially when trying to migrate the monolith to other technologies. Hosting on Linux an app with its parts communicating through COM+ is certainly possible, but not something you would enjoy doing.