Authentication and Authorization in Microservices

Microservices architecture has been gaining a lot of ground as the preferred architecture for implementing solutions, as it provides benefits like scalability, logical and physical separation, small teams managing a part of the functionality, flexibility in technology, etc. But since microservices are distributed the complexity of managing them increases.

One of the key challenges is how to implement authentication and authorization in microservices so that we can manage security and access control.

In this post, we will try to explore a few approaches that are available and see how we should implement them.

There are three approaches that we can follow:

Local Authentication and Authorization (Microservices are responsible for Authentication and Authorization)

      • Pros
        • Different authentication mechanisms can be implemented for each microservice.
        • Authorization can be more fine-grained
      • Cons
        • The code gets bulkier.
        • The probability of each service using different authentication is very low so code gets duplicated.
        • The developer needs to know the permission matrix and should understand what each permission will do.
        • The probability of making mistakes is quite high.

Global Authentication and Authorization (

    • It is an All or Nothing approach if the authorization for a service is there then it is accessible for all else none)

      • Pros
        • Authentication and authorization so there’s no repetition of code.
        • A future change to the authentication mechanism is easy, as there’s only one place to change the code.
        • Microservices’ code is very light and focuses on business logic only.
      • Cons
        • Microservices have no control over what the user can access or not, and finer level permissions cannot be granted.
        • Failure is centralized and will cause everything to stop working.

Global Authentication and Authorization as a part of Microservices

    • Pros
      • Fine-grained object permissions are possible, as microservices can decide what user the will see or not.
      • Global authentication will be easier to manage the lighter the load becomes.
      • Since authorization is controlled by the respective microservice there’s no network latency and it will be faster.
      • No centralized failure for authorization.
    • Cons
      • Slightly more code for developers to write, as they have to focus on permission control.
      • Needs some effort to understand what you can do with each permission.

In my opinion, the third option is the best one, as most of the applications have a common authentication mechanism, thus global authentication makes perfect sense. Microservices can be accessed from multiple applications and clients and they might have different data needs so global authorization becomes a limiting factor on what each application can see. With local authorization, microservices can make sure that the client application is only authorized to see what it needs to see.

My organization implemented the same approach in one of the projects that we were working on recently. We built an authentication service that was mainly responsible for integration with the LDAP system for verifying the user and then contacting the RBAC (Role-Based Access Control) service to populate the permission matrix based on the role the user is playing in the context of the application, e.g. the same user can be a normal user in one of the applications and an admin in another. So we need to understand the context from which the user is coming in and RBAC is the place where we decode the context and populate the relevant set of permissions. The permission matrix was then sent to the microservice as a part of claims in the JWT token. Microservices only apply to those permissions and return what is required to be returned. Please see the below diagram to see how we orchestrate the flow.

Microservice authentication and authorization

Architecture Flow for Authentication and Authorization

Conclusion

The above solution, where authentication is global and microservices control the authorizations of their content based on the permissions that are passed to it, is one of the possible solutions for handling authentication and authorization modules in microservices development. Also, we can enhance this solution by building a sidecar in a service mesh-type architecture, where we offload the authorization to the sidecar.

Top Three Strategies for Moving From a Monolith to Microservices

One of the primary problems facing enterprises is the problem of moving from monolith to microservices. The larger the enterprise, the bigger their monolithic applications become, and it gets harder to refactor them into a microservices architecture.

Everyone seems to agree on the benefits of microservices. We covered this topic at some length in this post. However, not many seem to agree on how to undertake the migration journey. Too often, the decision-making process turns into a chicken-and-egg problem. The bigger the monolith, the bigger the stakeholders’ and management’s footprint becomes. Too much management often leads to decision paralysis and, ultimately, the journey ends up as a mess.

However, many organizations have successfully managed to make this transition. Often, it is a mix of good leadership and a well-defined strategy that determines success or failure.

Good leadership is often not in the hands of an architect or developer undertaking this journey. However, a strategy is. So, let’s look at some strategies that can help in this journey:

Implement New Functionalities as Services

I know it is hard. But if you’ve decided to transition from a monolith to microservices, you have to follow this strategy. Think of the monolithic system as a hole in the ground. To get out of a hole, you don’t dig more. In other words, you don’t add to your problems.

Often, organizations miss this part completely. They think about a grand migration strategy that will take years. However, business requirements come fast. Due to the lack of budget or time, teams end up implementing those requirements into the monolithic application. The grand migration strategy never starts for whatever reason. And, each addition to the monolith makes the goal-post move further ahead.

In order to get around this, stop increasing the size of the monolith. Don’t implement new features in the monolithic code base. Every new feature or functionality should be implemented as services. This, in turn, reduces the growth rate of the monolithic application. In other words, new features implemented as services create inertia towards the migration. It also helps demonstrate the value of the approach and ensures continuous investment.

Separate Presentation Layer From the Backend

This is an extremely powerful strategy to migrate from a monolith to microservices. A typical enterprise application usually has three layers:

  • Presentation logic that consists of modules implementing the web UI. This tier of the system is responsible for handling HTTP requests and generating HTML pages. In any respectable application, this tier has a substantial amount of code.
  • Business logic that consists of modules handling the business rules. Often, this can be quite complex in an enterprise application.
  • Data access logic that consists of modules handling the persistence of data. In other words, it deals with databases.

Usually, there is a clean separation between presentation logic and business logic. The business tier exposes a set of coarse-grained APIs. Basically, these APIs form an API Layer. In other words, this layer acts as a natural border based on which you can split the monolith. This approach is also known as horizontal slicing.

If done successfully, you’ll end up with smaller applications. One application will handle the presentation. The other application will handle the business and data access logic. There are various data management patterns for microservices that can be explored.

There are advantages to this approach:

  • You can develop, deploy, and scale both applications independently. In other words, UI developers can rapidly introduce changes to the interface. They don’t have to worry about the impact on the backend.
  • You will also have a set of well-defined APIs. Also, these APIs will be remotely accessible for use in other microservices.

Extract Business Functionalities Into Services

This is the pinnacle of moving to a microservices architecture. The previous two strategies will take you only so far. Even if you successfully implement them, you’ll still have a very monolithic code base. Basically, they can act only as a spring-board to the real deal.

If you want to make a significant move towards microservices, you need to break apart the monolithic code base. The best way to do this is by breaking up the monolith based on business functionality. Each business functionality is handled by one microservice. Each of these microservices should be independently deployable and scalable. Communication between these services should be implemented using remote API calls or through message brokers.

By using this strategy, over time, the number of business functions implemented as services will grow and your monolith will gradually shrink. This approach is also known as vertical slicing. Basically, you are dividing your domain into vertical slices or functionalities.

Conclusion

Moving from a monolith to microservices is not easy. It requires significant investment and management buy-in. On top of all that, it requires incredible discipline and skill from the team actually developing it. However, the advantages are many.

Often, it is a good idea to start small on this journey. Rather than waiting for a big one-shot move, try to take incremental steps, learn from mistakes, iterate, and try again. Also, don’t try to go for a perfect design from the get-go. Instead, be willing to iterate and improve.

Lastly, remember that microservices is not a destination but a journey. A journey of continuous improvement.

Let me know your thoughts and experiences about this in the comments section below.

How Are Your Microservices Talking

In this piece, which originally appeared here, we’ll look at the challenges of refactoring SOAs to MSAs, in light of different communication types between microservices, and see how pub-sub message transmission — as a managed Apache Kafka Service — can mitigate or even eliminate these challenges.

If you’ve developed or updated any kind of cloud-based application in the last few years, chances are you’ve done so using a Microservices Architecture (MSA), rather than the slightly more dated Service-Oriented Architecture (SOA). So, what’s the difference?

As Jeff Myerson wrote:

“If Uber were built with an SOA, their services might be:GetPaymentsAndDriverInformationAndMappingDataAPIAuthenticateUsersAndDriversAPI

“Whereas, if Uber were built instead with microservices, their APIs might be more like:

SubmitPaymentsService
GetDriverInfoService
GetMappingDataService
AuthenticateUserService
AuthenticateDriverService

“More APIs, smaller sets of responsibilities.”

With smaller sets of responsibilities for each service, it’s easier to isolate functionality. But what are microservices and how do MSAs compare to SOAs and monolithic applications?

What Are Microservices?

Simply put, microservices are a software development method where applications are structured as loosely coupled services. The services themselves are minimal atomic units which together, comprise the entire functionality of the entire app. Whereas in an SOA, a single component service may combine one or several functions, a microservice within an MSA does one thing — only one thing — and does it well.

Microservices can be thought of as minimal units of functionality, can be deployed independently, are reusable, and communicate with each other via various network protocols like HTTP (more on that in a moment).

Today, most cloud-based applications that expose a REST API are built on microservices (or may actually be one themselves). These architectures are called Microservice Architectures, or MSAs.

On the continuum from single-unit, monolithic applications to coarse-grained service-oriented architectures, MSAs offer the finest granularity, with a number of specialized, atomic services supporting the application.

Microservices vs. SOA vs. MonolithicSource: Samarpit Tuli’s Quora Answer: “What’s the difference between SOAs and Microservices?”

Some Challenges

From this, one starts to get a sense of how asynchronous communication at scale could serve as a benefit in the context of apps that pull and combine data from several APIs. Still, while most organizations are considering implementing their applications as MSAs — or already have — the task, especially when refactoring from MSAs or monoliths, is not exactly straightforward.\

For example, 37% of respondents building web apps reported that monitoring was a significant issue in one sample. Why?

Some clues can be seen in some of the challenges cited by those refactoring legacy apps to MSAs — overcoming tight coupling was cited by 28% of respondents, whereas finding where to break up monolithic components was cited by almost as many.

These types of responses suggest a few different, but actually related, conclusions:

  1. Monitoring services built on MSAs is more complicated (as opposed to SOAs or Monolithic apps) because of multiple points of failure (which exist potentially everywhere a service integrates with another).
  2. Tight coupling suggests components and protocols are inflexibly integrated point-to-point in monolithic apps or SOAs (making them difficult to maintain and build functionality around).
  3. Breaking up monolithic apps or large SOA components into atomic, independent, reusable microservices is challenging for exactly those first two reasons.

Also, what sort of problems can one expect when your application scales? We’ll look at these and suggest a solution below. But there’s one question that underlies all of the above concerns: Once we do manage to break up our apps into atomic services, what’s the best way for these services to communicate with each other?

Some Microservices Communication Patterns

In her article “Introduction to Microservices Messaging Protocols,” Sarah Roman provides an excellent breakdown of the taxonomy of communication patterns used by and between microservices:

Synchronous

Synchronous communication is when the sender of the event waits for processing and some kind of reply, and only then proceeds to other tasks. This is typically implemented as REST calls, where the sender submits an HTTP request, and then the service processes this and returns an HTTP response. Synchronous communication suggests tight coupling between services.

Asynchronous

Asynchronous communication means that a service doesn’t need to wait on another to conclude its current task. A sender doesn’t necessarily wait for a response, but either polls for results later or records a callback function or action. This typically is done over message buses like Apache Kafka and/or RabbitMQ. Asynchronous communication actually invokes loose coupling between component services, because there can be no time dependencies between sending events and a receiver acting on them.

Single Receiver

In this case, each request has one sender and one receiver. If there are multiple requests, they should be staggered, because a single receiver cannot receive and process them all at once. Again, this suggests tight coupling between sender and receiver.

Multiple Receivers

As the category indicates, there are multiple receivers processing multiple requests.

We believe that, while each of these methods (in combination) have their purpose within an MSA, the most loosely coupled arrangement of all is when microservices within a distributed application communicate with each other asynchronously, and via multiple receivers. This option implies that there are no strict dependencies between the sender, time of send, protocol, and receiver.

Pub-Sub

The pub-sub communication method is an elaboration on this latter method. The sender merely sends events — whenever there are events to be sent— and each receiver chooses, asynchronously, which events to receive.

Apache Kafka may be one of the more recent evolutions of pub-sub. Apache Kafka works by passing messages via a publish-subscribe model, where software components called producers publish (append) events in time-order to distributed logs called topics (conceptually a category-named data feed to which records are appended).

Consumers are configured to separately subscribe from these topics by offset (the record number in the topic). This latter idea — the notion that consumers simply decide what they will consume — removes the complexity of having to configure complicated routing rules into the producer or other components of the system at the beginning of the pipe.

diagram of apache kafka producers writing to and consumers reading from a topic

We argue that, when asynchronous communication to multiple receivers is required, Apache Kafka is a promising way to go, as it solves the problem of tight-coupling between components and communication, is monitorable, and facilitates breaking up larger components into atomic, granular, independent, reusable services.

Why Apache Kafka?

Routing Rules Configured by Consumer

When the routing rules are configured by the consumer (a feature of pub-sub and Apache Kafka generally), then, as mentioned, there is no need to build additional complexity into the data pipe itself. This makes it possible to decouple components from the message bus (and each other) and develop and test them independently, without worrying about dependencies.

Built-in Support for Asynchronous Messaging

All of the above makes it reasonably simple to decouple components and focus on a specific part of the application. Asynchronous messaging, when used correctly, removes yet another point of complexity by letting your services be ready for events without being synced to them.

High Throughput/Low Latency

It’s easier to have peace of mind about breaking up larger, SOA-type services into smaller, more atomic ones when you don’t have to worry about communication latency issues. Aiven managed Kafka services have been benchmarked and feature the highest throughput and lowest latency of any hosted service in the industry.

Why Managed Apache Kafka?

Apache Kafka was built to leverage the best of what came before while improving on it even more.

However, Apache Kafka can be challenging to set up. There are many options to choose from, and these vary widely depending on whether you are using an open-source, proprietary, free, or paid version (depending on the vendor). What are your future requirements?

If you were choosing a bundled solution, then your choice of version and installation type, for example, may come back to haunt you in the future, depending on the functionality and performance you later decide you need.

These challenges alone may serve as a compelling argument for a managed version. With the deployment, hardware outlay costs and effort and configuration out of your hands, you can focus entirely on the development for which you originally intended your Kafka deployment.

What’s more, managed is monitorable. Are you tracking throughput? You need not worry about where the integration points are in your app to instrument custom logging and monitoring; simply monitor each of your atomic services’ throughput via your provider’s Kafka backend and metrics infrastructure.

Auto-Scaling

What sort of problems can you expect when your application scales? Bottlenecks? Race conditions? A refactoring mess to accommodate for them?

A managed Kafka solution can scale automatically for you when the size of your data stream grows. As such, you needn’t worry when it’s time to refactor your services atomically, and you needn’t force your teams to maintain blob-style, clustered services with complicated dependencies just for the sake of avoiding latency between them.

Centralized, No-Fuss Management

If you’re managing your own cluster, you can expect to be tied down with installs, updates, managing version dependencies, and related issues. A managed solution handles all of that for you, so you can focus on your core business.

High Availability

Apache Kafka is already known for its high availability, so you never have to worry about your services being unable to communicate because a single node supporting your middleware is down.

Kafka’s ability to handle massive amounts of data and scale automatically lets you scale your data processing capabilities as your data load grows. And a managed solution has redundancy built right in.

Wrapping Up

We looked at some common challenges of refactoring from SOAs to MSAs: monitorability, tight coupling of components, and the challenges of breaking up larger monolithic or SOA components into microservices.

We considered different types of communication and looked at how a pub-sub mechanism serves asynchronous message transmission between multiple services. Finally, we examined how a managed Apache Kafka solution may be an excellent candidate for such a use case.q

Questions to Ask Before Choosing Microservices

One of the companies I worked with had over 300 microservices, all set up with CI/CD pipelines, Consul service discovery, and decoupled system integration using messaging and queues. I’m now working with a mid-size company where I’ve introduced a few microservices, but I’ve since then started to wonder: When should I and when shouldn’t I go down this path? I don’t have a definitive answer here, so I’m just going to throw a few questions and for us to discuss.

  • Is my business suitable for more monolithic or distributed systems? Think product portfolio and revenue streams: The more complex your current business model is, the more you are probably leaning towards distributed systems.
  • Will business logic get updated later on? Do I need a centralized logic engine or data mapping engine (e.g. Dell BOOMI)?
  • If distributed systems are the way to go, do I use microservices or modularized applications?
  • How frequently is the data updated? How frequently is the data retrieved? Do I need the data to be eventually consistent or always consistent? This will affect more than just your application structure — it will affect how you implement caching as well.
  • Is service discovery going to be a problem? Will it be a messy mesh of endpoints to manage and maintain?
  • Are my devs comfortable with the structure we are heading to?
  • Is there an integration expert/architect that can lead the project and follow through?
  • What if one of the service endpoints fail? How do I recover? How do I monitor all these effectively?
  • How do I manage security settings and authentication across all the services?

And once you’ve answered all these questions, you probably also want to make a calculation on the cost side — this should include both infrastructure and resource costs (your dev team, your DevOps team, training, and ongoing maintenance).

Let me know what you think!

Microservices: Are They for Me?

Microservices are one of the biggest buzzwords of recent years. However, it turns out that it is a bit like teenage sex: everyone talks about it, but nobody really knows how to do it. What does it take to make good use of this architecture? What conditions do we have to meet so that it’s something more than just an item on your CV? Read the article to find out.

Nothing New Under the Sun

Several years ago, conferences were all about Service Oriented Architecture. In a nutshell, it consists of building large systems with many logically divided services integrated with each other. The idea was to eliminate the main problems related to monolithic architecture. Most SOA implementations were based on, or shifted over time toward, the Enterprise Service Bus. The bus was responsible for communication routing, document mapping, handling different types of endpoints, auditing, and security. The idea was noble, but the versatility of the solution turned out to be a double-edged sword. After some time, the bus turned into another monolith. Centralization, bottlenecks, both in terms of development and efficiency, and a single point of failure contributed to the growing criticism of the solution. I know cases where a 60-80-person team working on the bus turned out to be insufficient and a part of the communication had to be point-to-point so as not to block business projects.

The architecture of microservices, which is a de facto implementation of the SOA style, is based on the conclusions drawn while using the ESB model. The way of communication has changed dramatically. Replaced by point-to-point information exchange, the omnipotent bus is no longer the core of the solution. This is supposed to eliminate bottlenecks and enable independent development of projects.

Micro Is Not So Small

How big is micro? Counting the number of lines of code is one of the most questionable methods of assessing the size of an application. But it will be sufficient for now. The most common answer to the question, “how many lines of code should a statistical microservice have?” is “1000.” I don’t want to act like an oracle and judge whether it’s right or wrong. But let’s resort to math for support (back to the beginning of primary school). Let’s assume that the average size of one monolithic application (developed by a 20-30-person team) is half a million lines of code. If we divide it into components of a thousand lines each, in theory, we will get 500 services. This is not much less than the giants like Netflix or Uber have. Across the whole company. Developed by nearly two thousand engineers. And we have 30. Does it mean that you have to employ additional 1,970 people in order to switch to a new architecture? Or is it better to change the level of granularity?

Assuming that 3-5 people can work on one service, let’s divide our monolith, for example, into 8 applications. On average, each of them will have about 60 thousand lines. And this is getting more realistic. As a programmer, I can easily grasp an application of this size in detail. You can also implement a specific part of the business and effectively develop it with a small Agile team.

But you may start wondering, what is actually wrong with microservices? Why should I trust others? First of all, it is worth noting that their solutions work very well, which may be indicative that their reasoning is right. It is the availability of the platform that is the main reason for choosing this particular granulation. In the case of using synchronous communication between services, a phenomenon referred to as “temporal coupling” takes place. In order to continue processing a business transaction, it is necessary to obtain a response from the second service, which may request a response from the third one and so on. The greater the “synchronous depth of the system,” the smaller its availability.

I Don’t Have Users, Are Microservices the Answer?

There are many myths surrounding microservices. If I were to believe everything I hear about them at conferences, I would probably insist that breaking up monoliths into microservices is the answer to public debt and world hunger. I don’t even have to tell you that it’s nonsense (Or maybe I have to? Don’t blindly believe everything that you hear at conferences!).

What is the difference between microservices and the classical distributed system? Listening to informal discussions, one can conclude that it is an IT equivalent of boasting about the price or size of a car. “How many microservices do you have? Well, we have 400.” Frankly speaking, I’d rather have 40 decent ones than 400 sloppy ones just to have something to brag about in front of my friends. But who am I to tell you. The basic difference between microservices and the classical distributed system boils down to autonomy. The dispersed system, although it implements the process by means of many separate systems, conceptually resembles a monolith. All systems are updated with a single implementation and often do not even support the unavailability of collaborators (applications which they communicate with). This is completely different with microservices. Each service has its own lifecycle. Works on individual applications are carried out independently and implemented without coordination. It is often the case that a service we depend on is not available, because the implementation of a new version is in progress.

Autonomy is one of the best things microservices can offer. It enables truly agile and scalable development of the system. Discussions such as the following are now becoming a thing of the past: “You can’t implement project X now, because project Y is still being tested.” Unfortunately, this independence also makes microservices by far the most difficult architecture I worked with. The need to constantly work in the “design for failure” model and to anticipate any communication problems in advance is what baffles even the best programmers and architects. On the other hand, if the business is not ready to work in such a model and insists on staying in the release model, microservices lose one of their greatest assets. You have to foot the bill, but the problems remain unsolved.

Where Are the Limits?

One of the most challenging tasks when it comes to implementing microservices architecture is to define their limits. The first point of reference is the Bounded Context concept known from Domain Driven Design. In every context, there is usually a domain expert, who is often the business owner of the processes taking place there. As a result, reducing the size of the application to a specific business area which can be managed by one person translates into better organization and consistency than if you need to reconcile different interest groups. Data ownership and stages in the business process should also be considered. If two seemingly disconnected contexts affect the same data, this may mean that the division is artificial. However, it may also be necessary to designate a third independent context to manage data used in other processes.

These are the main criteria for dividing services, but the list is not exhaustive. If one function can be much more effectively implemented in a different technology (e.g. in a different language) than the main service, separating them should be considered. The same applies to scalability. If you know that certain functions will be used very intensively, moving them to a separate component may be a good idea. Security is the third aspect to consider. If the requirements in this area differ significantly from one function to another, putting them into one application may not be the best idea.

TL;DR

What are the basic applicability criteria for microservices? Consider this architecture if:

  • the business you work with is ready to abandon the classic release model.
  • individual business units are able to implement projects autonomously.
  • you need dynamic and asymmetric scalability.

Make sure you leave a comment below.

Breaking a Monolith Into Microservices: Best Practices and Challenges

11397064-pic-microservices-monotlithtomicroservices

You Will Learn

  • What are the important features of microservices architectures?
  • What are the important challenges?
  • How do you breakdown a monolith into microservices?

Let’s start with the basics of a monolithic architecture, understand microservices architecture, and figure out what you should do to migrate from the former to the latter.

Monolithic Architecture

The salient features of monolith applications are:

  • Released, or taken to production, once every few weeks, months, years.
  • Generally, have a wide range of features and functionality.
  • Have a development team of over 50 people working on them.
  • Debugging problems that arise is a huge challenge.
  • It is almost impossible to bring in new technologies and technical processes, midway through the lifetime of such an application.

Monolith applications are typically huge and have millions of lines of code.

A monolithic application would look something like the following:

monolithic application

You have a large application talking to a large database.

Microservices Architecture

In a microservices architecture, instead of building a large application, we build a number of smaller applications, known as microservices.

Here is how you would split up the monolith MovieApplication:

Microservices architecture

As you can see here, the databases are also separated out.

Microservices architecture involves a number of small, well-designed microservices that exchange messages among themselves:Microservices architecture

Microservices Architecture Is Tough

While a microservices architecture looks very easy at a high level, implementing it is no trivial process.

There are a number of important decisions to make for moving to microservices architecture, such as:

  • What are the boundaries of the individual microservices?
  • How small should a microservice be, and what functionality should go into it?
  • What data needs to go into the database to which a particular microservice talks extensively?
  • How should the microservices communicate with each other?

Challenges With Microservices Architecture

The challenges that need to be tackled when setting up a microservices architecture are described below.

Quick Set Up Needed

You cannot spend a month setting up each microservice. You should be able to set up a microservice quickly.

Automation

Because there are a number of smaller components instead of a monolith, there needs to be automation in every activity, such as builds, deployment, monitoring, etc.

Visibility

You have a potentially large number of smaller components to deploy and maintain. This number could be 100 today and 1000 tomorrow. You should be able to monitor and identify problems automatically. You need great visibility around all the components.

Bounded Context

Deciding the boundaries of a microservice is not an easy task. Applying Bounded Context principles from Domain Driven Design is usually a good starting point.

Your understanding of the domain evolves over a period of time. You need to ensure that the microservice boundaries evolve with time.

Configuration Management

You need to maintain configurations for hundreds of components across environments. It would be best to have a configuration management solution.

Dynamic Scale Up and Scale Down

The advantages of a microservices architecture can be realized only if the application can scale up and scale down easily in the cloud.

Pack of Cards

If the microservice at the bottom of a call chain fails, it can have knock-on effects on all the other microservices. Microservices should be fault tolerant by design.

Debugging

When there is a problem that needs investigation, you might need to look into multiple services across different components. Centralized logging and dashboards are essential to make it easy to debug problems.

Consistency

You cannot have a wide range of tools solving the same problem. While it is important to encourage innovation, it is also essential to have decentralized governance around the languages, platforms, technologies, and tools used for implementing, deploying, and monitoring microservices.

Going From Monolith to Microservices Is Not an Easy Switch

You may have noticed that after describing monolithic applications, we directly jumped into the challenges of microservices.

The reason we did not talk about the advantages of microservices first is that you need a reality check when you migrate from one architecture to another. You need to realize this is not something you can do in a few weeks or months.

Getting a microservices architecture right involves a few years of work. It’s not a switch, but a journey.

During that journey, both architectures live side by side.

You would hope that the number of applications using a microservices architecture grows over time.

Ask Why You Are Migrating From Monolith to Microservices

This is the most important question to ask! Don’t use microservices because it is a buzzword. Use it because your business needs it.

Why Are You Migrating from Monolith to Microservices? What Do You Want to Achieve?

  • Do you want to be able to adopt new technologies and processes faster?
  • Do you want faster release cycles for your application?
  • Do you want to scale more easily in the cloud?

You need to be very aware of which of these reasons is the biggest one for your migration.

The approach you use to actually migrate would differ, based on the exact reason for migration.

Let’s look at these approaches in a little more detail.

If Your Reason Is to Adopt New Technologies

Let’s say the reason you’re switching to microservices is the ability they provide to adopt newer technologies. In that case, you can start off with designing microservices for the next set of features you intend to implement. In other words, all the requirements for new feature implementation in the monolithic application are the best candidates to become microservices.

You need to answer questions such as:

  • How do you design the database?
  • How do make sure the communication between the old monolith and the new components is working?

If Your Reason Is to have Faster Release Cycles

Your business may not be happy with the pace at which new features are being released to production. In that scenario, you first need to identify those parts of the application, where there are frequent changes.

Once you do this, you can extract the fast moving parts and create microservices around them.

The idea behind this is that when there is a change, only release the related microservice.

If Your Reason Is to Scale With the Cloud

If the driving force behind the migration is scaling with the cloud, then you need to analyze what needs to be done to put your application in the cloud.

Start with research and proof-of-concept prototypes to understand the dependencies involved. You need to find out which dependencies are important to break and anticipate the problems you may face on making the application cloud-native.

More Than One

Your business might need microservices for more that one of the above reasons. Prioritize them and get started with the most important ones.

Clearly, the path to migration will not be the same for all. However, with whatever microservices that you design in your journey, make sure they address the challenges that we saw earlier, in an effective manner.

Do check out our video on this:

Or you can check it out on YouTube here.

Summary

In this article, we had a good look at the activities involved in moving from a monolith to a microservices architecture. We observed that it is not an easy journey, as the process involved in designing the two kinds of systems is radically different.

The actual journey of your migration will heavily depend upon the exact reason you want to do it. Ultimately, with whatever microservices you come up with, make sure they effectively address the challenges that exist in such a system.

Microservices Introduction (Monolithic vs. Microservice Architecture)

Recently, there has been a lot of fuss about microservices. There are a lot of discussions happening about microservices in almost all the IT companies. Microservices architecture can be easily understood when we compare it with traditional monolithic architecture.

Almost every enterprise application has a similar kind of layered architecture:

  1. Presentation: The user interface.
  2. Business logic: The application’s internal business logic.
  3. Database access: Almost all applications need to access DB, either SQL or NoSQL.
  4. Application integration: Quite often, the application needs integration with other applications. This is usually achieved via web service calls (SOAP or REST), or via messaging.

Even though applications have clear, logically modular architecture, but usually, most of the application is packaged and deployed as a monolith. There are actually some advantages to doing this.

Image title

Advantages of Monolithic Architecture

  1. Development is quite simple.
  2. Testing is very simple. Just launch the application and start end-to-end testing. We can also do test automation using Selenium without any difficulty.
  3. Deploying the monolithic application is straightforward; just copy the packaged application to the server.
  4. Scalability is simple. We just need to have a new instance of the monolithic application and ask the load balancer to distribute load to the new instance as well. However, as the monolithic application grows in size, scalability becomes a serious issue.

Monolithic architecture worked successfully for many decades. In fact, many of the most successful and largest applications were initially developed and deployed as a monolith. Many large-scale enterprise applications of big companies are still being deployed as a monolith. But with the changing market and with the emergence of new technologies, there has been a paradigm shift in the way IT industries work. There are some serious issues with monolithic architecture, which most companies are trying to address these days.

Disadvantages of Monolithic Architecture

  1. Flexibility: Monolithic architecture is not flexible. We can’t use different technologies. The technology stack is decided at the start and followed throughout. Once development matures, sometimes it becomes difficult to upgrade the technology stack versions, let alone incrementally adopt a newer technology.
  2. Reliability: It’s not reliable. If one feature goes down, the entire application might go down.
  3. Development speed: Development is really slow in monolithic architecture. It’s difficult for new team members to understand and modify the code of a large monolithic application. Code quality declines over time. With the increasing size of the code base, the IDE is overloaded and becomes slower. The larger the application, the longer it takes to start up. All these factors have a huge impact on the developers’ productivity.
  4. Building complex applications: It’s difficult to build a complex application because of the limitations in terms of technologies.
  5. Scalability: Monolithic applications are difficult to scale up once they get larger. We can create new instances of the monolith and ask the load balancer to distribute traffic to the new instances, but monolithic architecture can’t scale with an increasing load. Each copy of the application instance will access all of the data, which makes caching less effective and increases memory consumption and I/O traffic. Also, different application components have different resource requirements — one might be CPU intensive while another might memory intensive. With monolithic architecture, we cannot scale each component independently.
  6. Continuous deployment:  Continuous deployment is extremely difficult. Large monolithic applications are actually an obstacle to frequent deployments. In order to update one component, we have to redeploy the entire application.

Because of all the above drawbacks of monolithic applications, microservice architecture is becoming more and more popular day by day. So what is microservice-based architecture?

In short, 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, usually via RESTful web services or messaging. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There’s a bare minimum of centralized management of these services, which may be developed in different programming languages and use different data storage technologies. Microservices are small, independently deployable units which are cloud-enabled.

Image title

How Microservice Architecture Tackles the Drawbacks of Monolithic Architecture

  1.  Flexibility: Microservices architecture is quite flexible. Different microservices can be developed in different technologies. Since a microservice is smaller, the code base is quite less, so it’s not that difficult to upgrade the technology stack versions. Also, we can incrementally adopt a newer technology without much difficulty.
  2. Reliability: Microservices architecture can be very reliable. If one feature goes down, the entire application doesn’t go down. We can fix the issue in the corresponding microservice and immediately deploy it.
  3. Development speed: Development is pretty fast in microservices architecture. Since the volume of code is much less for a microservice, it’s not difficult for new team members to understand and modify the code. They become productive right from the start. Code quality is maintained well. The IDE is much faster. A microservice takes much less time to start up. All these factors considerably increase developers’ productivity.
  4. Building complex applications: With microservice architecture, it’s easy to build complex applications. If the features of the application are analyzed properly, we can break it down into independent components which can be deployed independently. Then, even the independent components can be further broken down into small independent tasks which can be deployed independently as a microservice. Deciding the boundaries of a microservice can be quite challenging. It’s actually an evolutionary process, but once we decide on a microservice, it’s easy to develop, as there are no limitation in technologies.
  5. Scalability: Scalability is a major advantage in microservice architecture. Each microservice can be scaled individually. Since individual microservices are much smaller in size, caching becomes very effective.
  6. Continuous deployment: Continuous deployment becomes easier. In order to update one component, we have to redeploy only that particular microservice.

As I mentioned earlier, microservice architecture can be easily understood when we compare it with traditional monolithic architecture, but prior to microservices, there’s already similar kind of architecture available. Yes, I’m talking about SOA (Service-Oriented Architecture). SOA has been here for two decades. If you have already worked with SOA and are familiar with its concepts, it could be quite confusing to understand the differences between SOA and microservice architecture. In fact, the two have more in common than differences. In my next post on microservices, I will write about SOA, similarities between SOA and microservice architecture, and of course, the differences between them.