Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
This post was edited and submitted for review 1 year ago and failed to reopen the post:
Opinion-based Update the question so it can be answered with facts and citations by editing this post.
Improve this question
What are advantages and disadvantages of microservices and monolithic architecture?
When to chose microservice architecture or monolithic architecture?
This is a very important question because a few people get lured by all the buzz around microservices, and there are tradeoffs to consider. So, what are the benefits and challenges of microservices (when compared with the monolithic model)?
Benefits
Deployability: more agility to roll out new versions of a service due to shorter build+test+deploy cycles. Also, flexibility to employ service-specific security, replication, persistence, and monitoring configurations.
Reliability: a microservice fault affects that microservice alone and its consumers, whereas in the monolithic model a service fault may bring down the entire monolith.
Availability: rolling out a new version of a microservice requires little downtime, whereas rolling out a new version of a service in the monolith requires a typically slower restart of the entire monolith.
Scalability: each microservice can be scaled independently using pools, clusters, grids. The deployment characteristics make microservices a great match for the elasticity of the cloud.
Modifiability: more flexibility to use new frameworks, libraries, datasources, and other resources. Also, microservices are loosely-coupled, modular components only accessible via their contracts, and hence less prone to turn into a big ball of mud.
Management: the application development effort is divided across teams that are smaller and work more independently.
Design autonomy: the team has freedom to employ different technologies, frameworks, and patterns to design and implement each microservice, and can change and redeploy each microservice independently
Challenges
Deployability: there are far more deployment units, so there are more complex jobs, scripts, transfer areas, and config files to oversee for deployment. (For that reason, continuous delivery and DevOps are highly desirable for microservice projects.)
Performance: services more likely need to communicate over the network, whereas services within the monolith may benefit from local calls. (For that reason, the design should avoid "chatty" microservices.)
Modifiability: changes to the contract are more likely to impact consumers deployed elsewhere, whereas in the monolithic model consumers are more likely to be within the monolith and will be rolled out in lockstep with the service. Also, mechanisms to improve autonomy, such as eventual consistency and asynchronous calls, add complexity to microservices.
Testability: integration tests are harder to setup and run because they may span different microservices on different runtime environments.
Management: the effort to manage operations increases because there are more runtime components, log files, and point-to-point interactions to oversee.
Memory use: several classes and libraries are often replicated in each microservice bundle and the overall memory footprint increases.
Runtime autonomy: in the monolith the overall business logic is collocated. With microservices the logic is spread across microservices. So, all else being equal, it's more likely that a microservice will interact with other microservices over the network--that interaction decreases autonomy. If the interaction between microservices involves changing data, the need for a transactional boundary further compromises autonomy. The good news is that to avoid runtime autonomy issues, we can employ techniques such as eventual consistency, event-driven architecture, CQRS, cache (data replication), and aligning microservices with DDD bounded contexts. These techniques are not inherent to microservices, but have been suggested by virtually every author I've read.
Once we understand these tradeoffs, there's one more thing we need to know to answer the other question: which is better, microservices or monolith? We need to know the non-functional requirements (quality attribute requirements) of the application. Once you understand how important is performance vs scalability, for example, you can weigh the tradeoffs and make an educated design decision.
While I'm relatively new to the microservices world, I'll try to answer your question as complete as possible.
When you use the microservices architecture, you will have increased decoupling and separation of concerns. Since you are litteraly splitting up your application.
This results into that your codebase will be easier to manage (each application is independent of the other applications to stay up and running). Therefore, if you do this right, it will be easier in the future to add new features to your application. Whereas with a monolithic architecture, it might become a very hard thing to do if your application is big (and you can assume at some point in time it will be).
Also deploying the application is easier, since you are building the independent microservices separately and deploying them on separate servers. This means that you can build and deploy services whenever you like without having to rebuild the rest of your application.
Since the different services are small and deployed separately, it's obvious easier to scale them, with the advantage that you can scale specific services of your application (with a monolithic you scale the complete "thing", even if it's just a specific part within the application that is getting an excessive load).
However, for applications that are not intended to become too big to manage in the future. It is better to keep it at the monolithic architecture. Since the microservices architecture has some serious difficulties involved. I stated that it is easier to deploy microservices, but this is only true in comparison with big monoliths. Using microservices you have the added complexity of distributing the services to different servers at different locations and you need to find a way to manage all of that. Building microservices will help you in the long-run if your application gets big, but for smaller applications, it is just easier to stay monolithic.
#Luxo is spot on. I'd just like to offer a slight variation and bring about the organizational perspective of it. Not only does microservices allow the applications to be decoupled but it may also help on an organizational level. The organization for example would be able to divide into multiple teams where each may develop on a set of microservices that the team may provide.
For example, in larger shops like Amazon, you might have a personalization team, ecommerce team, infrastructure services team, etc. If you'd like to get into microservices, Amazon is a very good example of it. Jeff Bezos made it a mandate for teams to communicate to another team's services if they needed access to a shared functionality. See here for a brief description.
In addition, engineers from Etsy and Netflix also had a small debate back in the day of microservices vs monolith on Twitter. The debate is a little less technical but can offer a few insights as well.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
After doing rigorous research and analysis I finally arrived to a point which is confusing me "Is Microservice a design pattern or architecture".
Some say it's a pattern evolved as a solution to monolithic applications and hence design pattern
And some confirms no doubt it's an architecture which speaks about their development, management, scalability, autonomous & full stack.
Any thoughts or suggestions I welcome to get myself clarified.
Microservices can be best described as an architectural style. Beside architectural decisions the style also includes organizational and process relevant considerations.
The architectural elements include:
Componentizing by business concern.
Strict decoupling in terms of persistence.
Well defined interfacing and communication.
Aim for smaller service sizes.
The organizational elements include:
Team organization around components (Conway's Law).
Team size limitations (two-pizza team).
The process relevant elements include:
Less centralized governance.
Smaller, more frequent releases.
Higher degree of freedom for technology decisions.
Product oriented development (agile, MVP, lean, etc).
For more details I recommend reading the articles from Martin Fowler.
I would describe it as a software architectural style that require functional decomposition of an application.
Usually, it involves a monolithic application is broken down into multiple smaller services, each deployed in its own archive, and then composed as a single application using standard lightweight communication, such as REST over HTTP or some async communication (of course, at some point micro services are written from scratch).
The term “micro” in microservices is no indication of the line of code in the service, it only indicates the scope is limited to a single functionality.
Each service is fully autonomous and full-stack. Thus changing a service implementation has no impact to other services as they communicate using well-defined interfaces. There are several advantages of such an application, but its not a free lunch and requires a significant effort in NoOps.
It's important to focus on that that each service must have the properties of:
Single purpose — each service should focus on one single purpose and do it well.
Loose coupling — services know little about each other. A change to one service should not require changing the others. Communication between services should happen only through public service interfaces.
High cohesion — each service encapsulates all related behaviors and data together. If we need to build a new feature, all the changes should be localized to just one single service.
I’ve been doing a lot of googling regarding managing dependencies between microservices. We’re trying to move away from big monolithic app into micro-services in order to scale organizationally and be able to develop faster and with multiple teams working in parallel.
However, as we’re trying to functionally partition the monolith into the microservices, we see how intertwined business logic and data really is. This was not a problem when we were sitting on top of one big DB and were able to do big relational joins. But with microservices, this becomes a problem.
One solution is to make microservice-A go to 5-10 other microservices to get necessary data (this is equivalent of DB view with join). Another solution is to make microservice-A listen to events from 5-10 other services and populate local storage with relevant into (this is an equivalent of materialized view). Either way, microservice-A is coupled with 5-10 other services, and if new info is needed in microservice-A, the some of the services that it depends upon might will need to be release prior to microservice-A. Please note that microservice-A is itself depended upon by other services. Bottom line, we end up with DISTRIBUTED dependency hell.
Many articles advocate for second solution – i.e. something along the lines of Event Sourcing, Choreography, etc.
I would appreciate any shared experiences, recommendations and insights.
Philometor.
While not technically an "answer", I can definitely share some of my observations and experiences. Your question concerning services calling other services for database operations reminded me of a project where an architect sold senior management on the idea of "decoupling" persistence from the rest of the applications by implementing hundreds of REST interfaces in what essentially was a distributed DAO pattern in front of a very large enterprise database. The project ended up exactly the way I predicted - a dismal failure.
Microservices aren't about turning a monolithic application into a distributed monolithic application. In my example project above, the monolith was turned into a stove-piped, fragile, chaotic mess, with the coupling only moved to service contracts instead of Java class method signatures, and with a performance hit so bad the application was unusable. Last I heard they are still running their original monolith.
Microservices should be more of a vertical partitioning of your application and not a horizontal one. In my opinion it's better to think in terms of business function partitioning rather than "converting" an existing monolith. There's no rule that determines how big a microservice must be, but it should be big enough to do one complete synchronous function without needing to directly depend on outside services (as much as possible) to complete its work. If a microservice performs a complex business function that affects 50 tables, so be it! It owns those many tables. Ideally if a service goes down, it should affect only that business functionality it's responsible for, and not directly affect other services. As you can see, this thinking is the complete opposite from that which produced the distributed mess in my project example.
Not only do you need to ensure that the motivation behind replacing monoliths with microservices is sound, but also you need to step outside the monolith and revisit the actual business and begin partitioning that instead. Like everything else, baby steps are the way to go. Start with one small complete business function, and convert that into a single microservice instead of trying to replace a monolith all at once.
I have a question about microservice implementation. right now I am using an api gateway to process all get request to my individual services and using kafka to handle asynchronous post put and delete request. Is this a good way of handling of handling request in a microservice architecture?
Your question is too unspecific to give a good answer. What is a good architecture totally depends on the details of your use cases. Are you serving web pages, streaming media, amass data for analysis, or something completely different? We would also need to know what are you requirements in terms of concurrency, consistency and scalability? What are the constraints for budget/size of development teams, ease of development, dev skills, etc?
For example the decisions you have taken may be considered good if you have strong requirements for a highly scalable input of large data sets and very frequent data collection as well as the team to support it. But it may be considered bad if you have a small team only and are trying to get a quick and cheap MVP for a new service that has limited scalability requirements (because the complexity of the solution slows down your development unnecessarily).
It may be good because the development team is familiar with those technologies and can effectively develop with those. Or it may be bad because your team does not know anything about those and the investment in learning those will not be justifiable by long term gains.
Don't forget that one of the ideas of the microservices architectural style is that each service can be owned by a distinct team that makes its own decisions about what technology to use for implementation (for whatever reason: ease of development, business reasons etc). So in other words the microservices style embraces the old wisdom architecture follows organization.
Here a link to a recommended further read.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I'm learning Spring Framework. So I want to build the application which architecture will be good enough. For example my application will be some kind of a social network. I'm using Spring Boot container for this web application.
Is this architecture is correct? I mean scalability, future code support, etc. What are advantages and disadvantages? I want to use REST api and microservices. 1 page = 1 controller = 1 service.
1 service, 1 controller, 1 page is not a good thing to limit yourself to. You'll find a page may use a whole bunch of different services. Imagine if your facebook profile was one controller. It would be gigantically large, impossible to maintain. Just break downs things as logically as you can. Sometimes it may make sense to have a page which uses multiple controllers, sometimes you could have a controller which handles multiple pages so you don't have 30 really small controllers. I would say if you have a complex page you'll need multiple controllers, if you have allot of very simple pages one controller may handle many of them.
Can I also suggest you don't break things up when you don't need to. All your micro services your planing can just be components in your application. Otherwise you will find you have a massive overhead of maintaining code which just forwards and receives HTTP requests. This could also cost you an extremely valuable tool: Transactions! You will lose transactions, and this could lead to inconsistencies in maintaining data. Keep in mind your just one person. I have been trying to finish a webapp I have been working on which is 95% done and I'm spending 8 hours a day after work, working on it till 2am. Do your self a favor and don't create more work for yourself.
I agree with most points of Snickers3192's answer. Microservices is not something you should plan up front, your application should exist first, a monolith is fine for the beginning. Martin Fowler has written a good piece about the Microservices yes or no question. Once your app grows and you see the need for either parts of your application being scaled separately or teams needing to be able to develop independently, then you've got a business case for Microservices (and as you'll see from Fowler's article, you must also be ready to support such an architecture). Right now it's overengineering.
That said: If you start with a monolith and plan to evolve to Microservices later, then you need to pay attention to your dependency tree. Different parts of your application will need to access each other, and that's fine, but make sure you don't introduce circular dependencies, otherwise extracting Microservices later will be a nightmare. Ideally, you can identify service interfaces that you will use, and you implement them locally now, but may later implement them by calling a Rest API.
The pattern you suggest (1 service for 1 controller) maps to the Backends for Frontends pattern, which can be a good idea, depending on how complex your web site is. If you have many UI components that are shared between controllers, then you'll probably want to embrace another approach, e.g. Big Pipe. But it does make sense to have one controller that bundles everything a given page needs to know and delegates it to the upstream services, independent of whether all of this is on the same machine or in a Microservice architecture.
Lastly: if you do go with Microservices, pay attention to resilience. Use a circuit breaker like Hystrix or an event-driven architecture, otherwise one dying service can take down the entire architecture.
To anyone with real world experience breaking a monolith into separate modules and services.
I am asking this question having already read the MonolithFirst blog entry by Martin Fowler. When taking a monolith and breaking it into microservices the "size" element of the equation is the one that I ponder over the most. Specifically, how to approach breaking a monolith application (we're talking 2001: A Space Oddessy; as in it is that old and that large) into micro services without getting overly fine grained or staying too monolithic. The end goal is creating separate modules that can be upgraded indepenently and scaled independently.
What are some recommended best practices based on personal experience of breaking a monolith into microservices?
The rule of thumb is breaking the monolith based on bounded context . The most common way of defining the bounded context is using BU ( Business Unit) . For example the module which does actual payment is mostly a separate BU .
The second thing to consider is the overhead micro-services bring. You should analyse the hardware , monitoring , infra pieces before completely breaking the service. What I have seen is people taking smaller microservices out of monolith instead of going and writing say 10 new service and depreciating the monolith.
My advice will be have an incremental approach . Take the first BU which is being worked upon out of monolith. This will also give a goos learning curve for the whole team.
You should clearly distinguish sub-domain areas (bounded contexts) from you domain.
Usually (if everything is fine with your architecture) you already have some separate components in your monolith application which responsible for each sub-domain. These components interact with each other in one process
(in monolith application) and you should to think about how to put them into separate processes. Of course you need to produce a lot of refactoring when moving one by one parts of the monolith to microservices.
Always remember that every microservice is responsible for some sub-domain.
I strongly recommend you to learn Domain Driven Design.
Domain-Driven Design: Tackling Complexity in the Heart of Software by Eric Evans
Implementing Domain-Driven Design by Vaughn Vernon
Also learn CQRS pattern
At the beginning you also should decide how your micservices will interact with each other.
There are several options:
Direct calls from one service to another
Send messages through some dispatcher service
which abstracts the client service from the knowledge where the called (destination) services are located.
This approach is similar to how proxy server like NGINX works.
Interact through some messaging bus (middleware), like RabbitMQ
You can combine these options, for example Query requests can be processed through Dispatcher Service, Commands and Events through message bus.
From my experience the biggest problem will be to go away from a single database,
which monolith applications is usually used.
In addition some good practices:
Put each microservice in own repository - this isolates from the ability to directly use the code of one micro service in another.
You also get faster checkouts and builds of each microservice on CI.
Interactions with any service should occur only through its public contracts.
It is necessary to aspire that each microservice has its own database
Example of the sub-domains (bounded contexts) for some Tourism Industry application.
Each bounded context can be serviced by a microservice.
We also started our journey some time back and i started writing a blog series for exactly the same thing: https://dzone.com/articles/how-i-started-my-journey-in-micro-services-and-how
Basically what i understood is to break my problem in diff. microservices, i need a design framework which Domain Driven Design gives(Domain Driven Design Distilled Book by Vaugh Vernon).
Then to implement the design (using CQRS and Event Sourcing and ...) i need a framework which provides all the above support.
I found Lagom good for this.(Eventuate , Spring Microservices are some other choices).
Sample Microservices Domain analysis using Domain Driven Design by Microsoft: https://learn.microsoft.com/en-us/azure/architecture/microservices/domain-analysis
One more analysis is: http://cqrs.nu/tutorial/cs/01-design
After reading on Domain Driven Design i think lagom and above links will help you to build a end to end application. If still any doubts , please raise :)