What are the Downsides of a Microservice based solution

A Microservice based solution has the following downsides:

  1. Distributing the application adds complexity for developers when they are designing and building the services and in testing and exception handling. It also adds latency to the system.
  2. Without a Microservice-oriented infrastructure, An application that has dozens of Microservices types and needs high scalability means a high degree of deployment complexity for IT operations and management.
  3. Atomic transactions between multiple Microservices usually are not possible. The business requirements must embrace eventual consistency between multiple Microservices.
  4. Increased global resource needs (total memory, drives, and network resources for all the servers or hosts). The higher degree of granularity and distributed services requires more global resources. However, given the low cost of resources in general and the benefit of being able to scale out just certain areas of the application compared to long-term costs when evolving monolithic applications, the increased use of resources is usually a good tradeoff for large, long-term applications.
  5. When the application is large, with dozens of Microservices, there are challenges and limitations if the application requires direct client-to-Microservice communications. When designing and building a complex application based on Microservices, you might consider the use of multiple API Gateways instead of the simpler direct client‑to‑Microservice communication approach.
  6. Deciding how to partition an end-to-end application into multiple Microservices is challenging. As You need to identify areas of the application that are decoupled from the other areas and that have a low number of hard dependencies. Ideally, each service should have only a small set of responsibilities. This is like the single responsibility principle (SRP) applied to classes, which states that a class should only have one reason to change. 

 

 

Advertisements

Choosing a Platform for a new microservice

Microservices endorses using different technologies to build components of a solution or a system. You can have components based on Java or Scala with Spring or C# & .Net etc. But if you are going to build a new microservice which platform should you use? Most developer’s or architects would choose based on their background if they came from Java they choose Java or .net if they are from .net. This kind of reminds me of an old Dilbert comic in it Dilbert tells the marketing manager that he can draw a fish on the screen. It sounds to me like most architects choose a platform because they are familiar with not because of its merits. I am working on devising a decision tree to select which platform is more suitable for a microservices. So far if you are building a microservice to interact with Hadoop/Spark or Kafka Java/Scala/Spring is the platform to go, though there are lots of libraries that makes it easy to develop such microservices in .Net. I am still working on this but thought I should share it. Let me know your thoughts and why would you choose a platform over the other?

Java Scala /Spring MVC

  • Pros:

    • Respected in the business
    • Widespread
    • Constrained coding style might lead to easier to read code
    • Better ecosystem for libraries and tools
  • Cons:
    • Verbose, both with the language and framework
    • Does not have as good support for threading and asynchrony as C# has with async/await

C#/ASP.NET Core

  • Pros:
    • Asynchronous -oriented
    • Better generics, and integration with LINQ
    • Better IDE integration, and configuration setup
    • Quicker to get things up and running in
    • Able to be component oriented as well as MVC
    • Availability of other programming styles than OOP, including functional.
    • More low-level constructs allowing optimization
  • Cons:
    • Newer, slightly buggy
    • Not as battle-tested as Java
    • Heavy IDE (although you can use Visual Studio Code, too)

Microservices, TOGAF, Solution Blueprint and API Design


While providing microservices architecture consulting services, I found it necessary to extract the Interface Design from the Application Architecture. The Interface Design is usually part of the application architecture. However, the Interface design both UI and API are of extreme importance and value to the solution and to the organization offerings, it requires having a sperate section of its own. With the emergence of Microservices and many companies offering their services through APIs to allow clients to hock in and utilize their services. Or as business/marketing people refer to “Monetizing the API”. I think it is paramount to get the interface design more attention and specifically the API design. That is why I defined this new Interface Architecture phase in my customized TOGAF offering to the organization.

Architecture Type

Description

Business Architecture

The business strategy, governance, organization, and key business processes.

Interface Architecture

A blueprint for the individual application interfaces both User Interface and Application Programming Interface and their relationships to the core business processes of the organization.

Application Architecture

A blueprint for the individual application components to be deployed, their interactions, and their relationships to the core business processes of the organization.

Data Architecture

The structure of the application logical and physical data assets and data management resources.

Technology Architecture

The logical software and hardware capabilities that are required to support the deployment of business, data, and application services. This includes IT infrastructure, middleware, networks, communications, processing, and standards.

 

I would like to know your thoughts on this, and how did you handle the API design in the Solution Architecture Blueprint.

Enterprise Architecture and Domain Driven Design – Build Custom Business Logic as Microservice or part of the COTS Application?

As enterprise Architects, depending on the organization we are adopting readymade software applications (or COTS) and tailoring or customization of the software to the needs of the organization. The tailoring can involve UI changes, workflows changes, integrations with other systems in the organization and sometimes business logic added or modified. The UI changes usually must happen on the COTS (Component of the Shelf) application and so are workflows unless you are building a UI façade for this application. I saw one organization did build a completely different Web App to provide its employees access to work shift schedules as the Time and Attendance system could not handle the access by the hundreds of thousands of employees and save on licensing and infrastructure costs. This leaves us with Integrations and business logic. In this installment. I will address Business Logic.

Should we build the custom Business Logic as Microservice or part of the COTS Application?

Aha, this is a tough decision. I prefer to put all customizations out of the software package somewhere else. Would it be in Microservices or built as part of the ESB. I want to have the freedom to have the business logic as platform independent as possible. By moving the custom business logic out in webservices implemented by Microservices or part of the ESB I accomplish that. There are political aspects to this issue too? First the COTS vendor wants to have all the business logic customization in its application for the following reasons:

  1. The vendor wants to increase the $$$ from the custom development services they will provide.
  2. The vendor can enrich its application offerings and business logic by taking this customized business logic and generalizing it in future releasee.
  3. The more customizations and business logic embedded in the vendor logic the harder for the organization to switch to another competitor as they will the cost of customizations from scratch would add up.

The delivery department would prefer not to take ownership of new software components, especially if the organization does not have many software developers and depends on consulting companies.

My argument is that, all software be it ERP system like Dynamics AX or Time and Attendance systems is generic and the vendor offer it to your organization and your competitors. What differentiates your organization from your competitors is the custom process and business logic your organization uses. If you let the vendor build these customizations in their software then you end up subsidizing your competitor upgrade, and maybe giving them your edge. That is why I tend to recommend extracting any custom business logic new or modified and building it outside the COTS. Sometimes this is not possible due to the CTOS platform limitations or due to organizational standards. But whenever is possible extract any custom business logic outside of the COTS

Let me know your thoughts on that.

Microservices Simplified

In this blog, I will share my thoughts on how to architect complex software using microservices architecture, so that it’s flexible, scalable, and a competitive piece of software. I’ll start off first by introducing microservices, and what was before microservices, why microsoervices are so successful and useful now, and the design principles that are associated with microservices architecture.

What Is a Service?

A service is a piece of software which basically provides functionality to other components of software within your system. It basically provides a service to other pieces of software. The other pieces of software could be anything from a website to a mobile app or a desktop app, or even another service. The service basically provides functionality to these applications. And the communication between the software components and the service normally happen using some kind of communication protocol. A system which uses a service or multiple services in this fashion is known to have a service-oriented architecture, and this is normally abbreviated as SOA, or SOA, and the main idea behind SOA is, instead of building all the functionality in one big application, I instead use a service to provide a subset or just one functionality to the application, and this allows me to have many applications use the same cod, and in the future I can have newer or different types of systems connecting to the same service, reusing that functionality, and as a software architecture, SOA has been successful. It allows us to scale and to reuse functionality. A key characteristic of service-oriented architecture is the idea of having standardized contracts or interfaces. When a client application called the service, it called the service by calling a method. The signature of that method normally doesn’t change when the service changes, so you can upgrade a service without having to upgrade the clients, as long as the contract and the interface, i.e., the signature of the method doesn’t change. Also a service is stateless, so when a request comes in from a website to our service, that instance of the service does not have to remember the previous request from that specific customer, that specific client, it basically has all the information from the request that it needs in order to retrieve all the data associated with previous requests within the service. The microservices architecture is basically an improved version of service-oriented architecture, or in other terms SOA done the right way. Microsoervices Architecture shares all the key characteristics of the service-oriented architecture, of scalability, reusability, and standardized contracts and interface for backwards compatibility, and the idea of having a service that’s stateless.

Microservices Introduction

The microservices architecture is basically service-oriented architecture done well. Microservices basically introduce a new set of additional design principles to size a service correctly. Because there was no guidance in the past on how to size a service and what to include in a service, traditional service-oriented architecture resulted in monolithic large services, and because of the size of the service, these services became inefficient to scale up and change in an allowable way. Smaller services, i.e., microservices, basically provide services which are more efficiently scalable, which are flexible, and which can provide high performance in the areas where performance is required. An application which is based on microservices architecture is normally an application which is powered by multiple microservices, and each one of these microservices will provide a set of functions, a set or related functions, to a specific part of the application. Because the microservice normally has a single focus, it does one thing and it does it well. Microservice architecture also uses lightweight communication mechanism between clients and services and service to service. The communication mechanism has to be lightweight and quick, because when you carry out a transaction within a microservices architectured system, the transaction will be a distributed transaction which is completed by multiple services, therefore the services need to communicate to each other in a quick and efficient way over the network. The application interface for a microservice, also needs to be technology agnostic. This basically means the service needs to use an open communication protocol so that it does not dictate the technology that the client application needs to use. And by using open communication protocols, for example, like HTTP REST, we could easily have a .NET client application which talks to a Java-based microservice. In a monolithic service, you’re also likely to have a central database in order to share data between applications and services. In microservices architecture, each microservice has its own data storage. Another key characteristic of a microservice is that it is independently changeable. I can upgrade, enhance or fix a specific microservice without changing any of the clients or any of the other services within the system. And because microservices are independently changeable, they also need to be independently deployable. By modifying one microservice, I should be able to then deploy that change within my system independently from everything else without deploying anything else. We’ve already mentioned the fact that when you make a transaction within a microservices architectured system, the transaction is most likely to be completed by multiple services, multiple services which are distributed, and therefore, your transaction is also a distributed transaction. And because a microservices architectured system has so many moving parts, there’s a need for centralized tooling for management of the microservices. You need a tool, which will help you manage and see the health of your system because there are so many moving parts.

One of the reasons for the microservices architecture now is the need to respond to change quickly. The software market is really competitive nowadays. If your product can’t provide a feature that’s in demand, it will lose market share very quickly, and this is where microservices can split a large system into parts so we can upgrade and enhance individual parts in line with the market needs. So not only do we need to change parts of our system quickly, we also need to change them in a reliable way in order to keep the market happy, and microservices provides this reliability by having your system in many parts, so if one part of the system breaks it won’t break the entire system.

There is also a need for business domain-driven design. The architecture of our application needs to match the organization structure, or the structure of the business functions within the organization. Another reason why microservices architecture is now possible is because we now have automated test tools. We’ve already seen that in a microservices architecture transactions are distributed, and therefore, a transaction will be processed by several services before it’s complete. Therefore, the integration between those services needs to be tested, and testing these microservices together manually might be quite a complex task, but the good news is these automated tests automatically test the integration between our microservices, and this is why microservices architecture is now possible, because we have automated test tools which test integration between services. Release and deployment of microservices can also be complex, but we also have tools, centralized tools, which can carry out this function.

Another reason for the need to adopt microservices architecture is the need to adopt new technology. Because our system is now in several moving parts, we can easily change one part, i.e., a microservice from one technology stack to another technology stack in order to get a competitive edge. Another advancement in technology which makes microservices possible is the asynchronous communication technology. In our microservices architecture when we use distributed transactions, the distributed transaction might use several services in order to complete. Using asynchronous communication, the distributed transaction does not have to wait for individual services to complete their tasks before it’s complete.

The key benefits of the microservices Architecture

  1. Microservices have shorter development times. Because the system is split up into smaller moving parts, you can work on a moving part individually, you can have teams working on different parts concurrently, and because microservices are small in size and they have a single focus, the team have less to worry about in terms of scope. They know the one thing they’re working on has a certain scope, and there’s no need to worry about the entire system as long as they honor the contracts between the services.
  2. More reliable and faster Deployment. Because theservices are loosely coupled, developers can rework, change, and deploy individual components without deploying or affecting the entire system, and therefore, deployment is more reliable and faster. Shorter development times and reliable and faster deployment also enable frequent updates. As we’ve already briefly mentioned, frequent updates can give you a competitive edge in the marketplace. The microservices architecture also allows us to decouple changeable parts. For example, if we know our UI for our system, our user interface for our system, changes quite often, if it uses the microservices architecture, the UI is most likely decoupled from all the services in the background, and therefore you can change it independently from all the services.
  3. Enhanced Security. Microservices architecture also increases security. In a monolithic system you might have one central database with one system accessing that database, and therefore, all you need to do is hack that one system in order to gain access to the data. In the microservices architecture, each microservice has its own database, and each microservice can also have its own security mechanism, therefore, making the data distributed and making the data even more secure.
  4. Increased uptime, because when it comes to upgrading the system you will probably deploy one microservice at a time without affecting the rest of the system. And because the system is split up into business domains and business functions, when a problem arises we can probably quickly identify which service is responsible for that specific business function, and therefore resolve the problem within that microservice.
  5. Highly scalable, and better performance. When there’s a specific part of the system which is in demand, we can just scale that specific part up, instead of scaling the whole system up.
  6. Better support for distributed teams. We can give the ownership of a microservice to a particular development team so that there’s better ownership and knowledge about the microservice. Microservices allow us to use the right technology for specific parts in the system, and because each microservice is separate from the other microservice, they don’t share databases, and they have their own code base, you can easily have microservices being worked on concurrently by distributed teams. In the section of the module we’ll start looking at the design principles that enable microservices and enable these benefits that we get from microservices.

Microservices Design Principles

High Cohesion

Basically, the microservices content and functionality in terms of input and output must be coherent. It basically must have a single focus, and the thing it does it should do well within that single focus. The idea of a microservice having a single focus or a single responsibility is actually taken from the SOLID coding principles, and the single responsibility principle basically states that a class can only change for one reason, and this same principle is applied to microservices. It’s a useful principle because it allows us to control the size of the service, and we will not accidentally create a monolithic service by attaching other behaviors into the microservice which are not actually related. Because the high cohesion principle controls the size of the microservice and the scope of the contents of the microservice, the microservice is easily rewriteable as we are likely to have less of an attachment to a smaller code base, and obviously there will be fewer lines of code to rewrite because the microservice will be so small. And overall, if all our microservices have high cohesion, it makes our overall system highly scalable, flexible, and reliable. The system is more scalable because we can scale up individual microservices, which represent a specific business function or business domain which is in demand, instead of scaling up the whole system, and at the same time the system is more flexible because we can change and upgrade or change the functionality of specific business functions or business domains within our system, and then we have reliability because overall we are changing specific small parts within the system without affecting other parts within the system.

Autonomous

Microservices should also be autonomous. Autonomous meana a microservice should not be subject to change because of an external system it interacts with or an external system that interacts with it. There should be loose coupling between the microservices and between the microservices and the clients that use the microservices. A microservice should also be stateless. There should be no need to remember previous interactions that clients might have had with this service or other service instances in order to carry out the current request. And because microservices honor contracts and interfaces to other services and clients, they should be independently changeable and independently deployable. They should just slot back into the system after a change or enhancement, even though it has a newer version than any of the other components within the system. This also ensures our service is always backwards compatible. Having clear defined contracts between services also means that microservices can be concurrently developed by several teams, because there’s a clear definition of the input and output of a microservice. Separate teams can work on separate microservices, as long as they honor the contracts, development should go okay.

Business Domain Centric

A microservice should also be a business domain centric, and this means a service should represent a business function. The overall idea is to have a microservice represent a business function or a business domain, i.e., a part of the organization, because this helps scope the service and control the size of the service. This is an idea which is taken from domain driven design. You basically define a bounded context, which basically contains all the functionality which is related to a specific part of the business to a business domain or a business function, and you define the bounded context by defining boundaries and seams within the code. You basically highlight the areas where related functionality exists. There will be times when code relates to two different bounded contexts, and this is where we need to shuffle the code around so that the code ends up in the right place where it makes sense and it belongs in terms of business function or business domain. We need to aim for high cohesion, remember, making our microservices business domain centric, or to make our microservices responsive to business change. So as the business changes or the organization changes or functions within the business change, our microservices can change in the same way because our system is broken up into individual parts which are business domain centric. We can also change those parts which relate to specific parts in the organization which are changing.

Resilience

Microservices are resiliant. They embrace failure when it happens. Failure might be in the form of another service not responding to your service, or it might be a connection line to another system which has gone down, or it might be a third party system which fails to respond. Whatever the type of failure, our microservice needs to embrace that failure by degrading the functionality within our microservice or by using default functionality. An example of degrading functionality might be a scenario where we have a user interface microservice which basically draws an HTML page for available orders and promotions, but for whatever reason the promotion’s microservice is down and fails to respond, so our user interface microservice basically chooses to degrade that functionality, and it chooses not to display the promotions on the page. Another way of making microservices more resilient is by having multiple instances of microservices so they register themselves as they start up, and if any of them fail they deregister themselves, so our system or our load balancers, etc., are only ever aware of fully functioning microservices. We also need to be aware that there are different types of failures. So, for example, there might be exceptions or errors within a microservice, there might be delays in replying to a request, and there might also be complete unavailability of a microservice, and this is where we need to work out if we did need to degrade functionality or if we need to default functionality. Failures are also not just limited to the software itself. You might have network failures, and remember we’re using distributed transactions here where one transaction might go across the network and use several services before it actually completes, and therefore, again, we need to make our microservices resilient to network delays or unavailability. We also need to ensure that when our microservices are called and the input they receive as part of that request, that we can validate that input, and this might be input from services or from clients. We need to ensure that our microservices are resilient and can validate incoming data, and they don’t basically fall over because they’ve received something in an incorrect format.

Observable

We need a way to be able to observe our system’s health in terms of system status, in terms of logs, i.e., activity currently happening in the system and errors that are currently happening in the system. And this type of monitoring and logging needs to be centralized so that there is one place where we need to go to in order to view this information regarding the system’s health, and we need this level of monitoring and logging in a centralized place because we now have distributed transactions. In order for a transaction to complete, it must go across the network and use several services, therefore, knowing the health of the system is vital, and this kind of data will also be useful for quick problem solving because the whole system is distributed and there’s a lot going on. We need a quick way of working out where a potential problem possibly lies.

Automation

Automation in the form of tools, for example, tools to reduce testing. Automated testing will reduce the amount of time required for manual regression testing, and the time taken to test integration between services and clients, and also the time taken to set up test environments. Remember, in a microservices architecture our system is made up of several moving parts, and therefore testing can be quite complex, and this is where we need testing tools to automate some of that testing. We need tools, automated testing tools which give us quick feedback, so as soon as I change the microservice and check that we have called into our control system. As well as automation tools to help with testing, we need automation tools to help with deployment, a tool which basically provides a pipeline to deployment. It gives our microservice a deployment ready status, so when you check a change in, the tests pass, and then the deployment status is at ready, and then the tool knows that this build of the microservice is now ready for deployment. So not only does this tool provide a pipeline with a status for each deployable build of a microservice, it also provides a way of actually physically moving the build to the target machine or the target cloud system, so the physical deployment of the software will be all automatic, and therefore it will be reliable because it’s preconfigured with a target where the software needs to go, and it will be configured and tested once, and therefore it should work every time. The idea of using automation tools for deployment falls under a category called continuous deployment.