Microservices are getting more and more attention and companies often consider them as the solution to reach agility and faster time to market. However, in many of the discussions there is a lot of confusion and lack of understanding the basic principles of microservices. Most importantly, one must distinguish between the style of deploying an application with the architectural style of the application.
The definition of microservices the industry has agreed on goes back to James Lewis and Martin Fowler: “ the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API.” Or in other words you decompose your application into isolated services basically creating a service oriented architecture. In this sense a microservice is a unit offering services and potentially using other services. Leaving the deployment and communication aside, a microservice is an isolated module that communicates with other modules/microservices through service APIs.
The essence of microservices is modularity. But developing microservices is not the only way to use modules for building applications. While microservices give you isolation through isolated deployments, other technologies exist allowing you to assemble an application out of isolated modules running inside a single process. The most famous technology for this is OSGi, the Dynamic Module System for Java. It allows to develop independent modules declaring their requirements and capabilities. The capabilities are usually services used by other modules and the requirements are exactly the services a module uses from other modules. OSGi provides you an in-process service oriented approach with clear isolation between the modules. Such an approach is usually referred to as a modular application. This is in contrast to a monolithic application where there are no clear boundaries between the different code parts running within the same application.
The challenge is to create an application assembled out of independent modules, this is true for a modular application as well as for a microservices based solution. Only by creating cohesive modules, you will succeed in developing a microservice based solution. Interestingly, the field is reporting that very often approaches to create a microservice based solution on a green field fails. In contrast approaches where a modular application is used as a starting point and afterwards eventually transformed into microservices has a much higher chance of success. The advantage of starting with a modular application is reduced complexity in contrast to starting with microservices directly.
It seems that often people who advocate microservices claim that everything else which is not using microservices is monolithic by nature. However, this is confusing the architectural style of an application (modular vs monolith) with the style of deployment. With technologies like OSGi you have a modular application which is deployed as a single unit. But clearly the application is not monolithic. With microservices you deploy the parts individually but apart from that there is no difference to an OSGi application when it comes to modularity.
An application deployed as a single unit can of course be modular in its nature. By using OSGi and leveraging modules and services as defined by the industry standard allows you to build your application in an architectural style that is very close to microservices. The modules can be developed separately by different teams, each team focusing on a specific business capability. The modules are loosely coupled and only communicate through OSGi services. As OSGi is a dynamic system, the modules are designed for failure from the start and must handle situations like a service being not available or unreachable. The modules can have completely different development lifecycles and can be updated and enhanced independently. As explained above an application deployed as a single unit can in fact be modular. By using OSGi and leveraging modules and services as defined by this industry standard allows you to build your application in an architectural style that is very close to microservices. The modules can be developed separately by different teams, each team focusing on a specific business capability. The modules are loosely coupled and only communicate through OSGi services. As OSGi is a dynamic system, the modules are designed for failure from the start and must handle situations like a service being not available or unreachable. The modules can have completely different development lifecycles and can be updated and enhanced independently.
In fact, the only differences between an OSGi application and a microservice architecture are service communication and deployment. Within an OSGi supplication the communication between the modules is in process and not remote avoiding all the additional challenges of network communication. The automation and orchestration is way simpler and less error prone. Thanks to OSGi you can reduce time to market, develop new features as new modules and simply deploy them to an existing application.
That’s why we sometimes refer to an OSGi application as “microservices in a box”. You get all the benefits like strong module boundaries and independent deployments but avoid the additional costs of distribution and especially operational complexity. On the other hand, an often heard argument for microservices is better scalability of individual modules in combination with improved resource utilization. The advantage here is that you can independently and dynamically scale up and down the individual microservices based on load. While this is true if you only consider the microservice in isolation, however the operational infrastructure and know-how you need to have a successful microservice architecture scaling exactly as you need is often overlooked.
In addition, you need to know your bottlenecks in advance and design them as separate microscopes. By using OSGi one can defer this decision about deployment topologies until the need for scaling individual modules arises. By leveraging OSGi and services, you can easily move an OSGi service into a different process and utilize OSGi Remote Services. The application code itself does not need to be changed at all, you simple change the way of deploying your application from a single deployment to several based on your needs. And you can do this split up at any time, even dynamic at run-time would be possible. With OSGi it is possible to defer the decision of your deployment time to a later point of time and you can easily adjust.
If you want to get into utilizing microservices the prerequisite is modularity — there is no short cut here. The best approach of developing a modular application is OSGi. We picked OSGi as the base for Experience Manager exactly for that reason: modularity. We can independently develop the various features, create well defined contracts between the various parts and can postpone the decision about deployment style and service communication at a later time. This allowed us to scale up development to hundreds of developers while keeping teams independent of others. Well defined APIs and service interface build the foundation of Experience Manager. Thanks to OSGi it is already possible to check the consistency of the modules and inspect its dependencies. This way you can control the cohesion of your modules. Semantic versioning defines rules on how to adjust the version of your Java API based on the change you make. With the OSGi tooling you can already check at build time whether you made an incompatible change and which clients of your module are affected by the change. In summary modularity, OSGi and the available tooling gives us a development style which is equal if not superior to the microservices development style.
On the other hand, if you want to develop a new microservice to be used by Experience Manager or any other OSGi application, start by defining your Java service API. Implement the functionality and deploy this as a separate OSGi based application including the required modules. Simply use OSGi remote services to publish these services remotely. In Experience Manager or your OSGi application import the module containing the service API and use remote services to make your new service available. Your code running in Experience Manager just uses plain Java interfaces and method calls, but runs as a separate process which can be scaled independently. At any point in time you can change your deployment setup and simply add the implementation modules directly to Experience Manager if that provides benefits.
To recap, microservices is about modularity. OSGi is the best technology for modularity. Experience Manager is built using OSGi in a modular way. This gives you all the flexibility and prerequisites for using and providing microservices with Experience Manager.