Monolithic ArchitectureA monolithic application describes a single-tiered software application in which the user interface and data access code are combined into a single program for a single platform. A monolithic application is self-contained and independent from other computing applications.When developing a server-side application you can start it with a modular hexagonal or layered architecture which consists of different types of components:Presentation: the part responsible for handling HTTP requests and responding with either HTML or JSON/XML (for web services API).Business logic: the application’s business logic.Database access: data access objects responsible for access to the database.Application integration: integration with other services (e.g. via messaging or REST API).Benefits of this Monolithic ArchitectureThe beauty of monolithic code is simplicity. It is simple to develop, test, deploy and to scale horizontally. To test, you can implement end-to-end testing by simply launching the application and testing the UI with Selenium. To deploy, you just have to copy the packaged application to a server. To scale horizontally, you run multiple copies behind a load balancer.Drawbacks/Limitation of Monolithic Code
- The simple approach has a limitation in size and complexity.
- Application is too large and complex to fully understand and make changes fast and correctly.
- The size of the application can slow down the start-up time.
- You must redeploy the entire application with each update and continuous deployment is difficult.
- It is generally unreliable.
Microservices ArchitectureMicroservices is a software architecture that brings together some of the styles used in Service-Oriented Architecture but without the standard dependency on ESB and centralized governance. Each microservice is a small application that has its own hexagonal architecture consisting of business logic along with various adapters. The idea is to split your application into a set of smaller, interconnected services instead of building a single monolithic application. It tackles the problem of complexity of decomposing the application into a set of manageable services which are much faster to develop and much easier to understand and maintain.Building complex applications is inherently difficult. A Monolithic architecture better suits simple, lightweight applications while microservices architecture pattern is the better choice for complex, evolving applications. Seeing all of these, you might be having string thoughts towards switching your monolithic code to micro services. How to achieve this has been explained below:How to Migrate to MicroservicesTo migrate to microservices, it is advisable to refactor (i.e. introducing a behaviour-preserving code transformation). It basically means keeping your external APIs the same while changing the way your code operates or is packaged. Refactoring to microservices would thus imply adding microservices into your application without necessarily changing what it does. You would not add new functionality to your application, but you would change how it is packaged and perhaps how the API is expressed.The 3 basic considerations before refactoring are:
- How is your application packaged and built?
- How does your application code function?
- How does your application interact with back-end data sources when those data sources are structured in different ways?
Step 1: Repackaging the applicationSplit up the EARs: Instead of packaging all of your related WARs in one EAR, split them up into independent WARS.Apply “Container per service”: Apply the “Container per Service” pattern and deploy each WAR in its own Liberty server.Build, deploy and manage independently: Since they are now split, you can then manage each WAR independently through an automated DevOps pipeline.Step 2: Refactoring the codeCase 1: This is a case of Existing REST or JMS services.Case 2: This is a case of Existing SOAP or EJB services.Case 3: This is a case of Simple Servlet/JSP interfaces.Step 3: Refactoring the data: To achieve this, there are a few rules you can follow for the simplest processIsolated islands of data: Begin by looking at the database tables that your code uses. Split the ones that are independent of all other tables or come in a small, isolated “island” of a few tables joined by relationships.Batch data updates: If you have only a few relationships and you decide to move your data into a no SQL database, consider whether you just need to do a batch update into your existing database. A data dump/load approach that runs every few hours may be fine for many cases.Table denormalization: If you have more than a few relationships to other tables, you may be able to refactor (denormalize) your tables.