microservices

What is a Microservices 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, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a base minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.”
- James Lewis and Martin Fowler

From this definition, we understand that microservices are small, independently deployable services that work together. These services are focused on doing one thing well (Single Responsibility Principle). In this style, you break down your larger system into multiple microservices that will interact with each other to accomplish the larger goal. There is no standard model for a microservices architecture but most share some notable properties.

microservices architecture

First, they are autonomous. Microservices are typically created by componentizing the software, a component being a unit of software that is independently replaceable and upgradeable. This is especially important as more applications are being deployed to the cloud where load demands can increase dramatically. All communication happens via lightweight networking calls (APIs). The aim is to be as decoupled and as cohesive as possible.

Microservices do not need a standard technology stack. While traditionally large software applications standardize on a single technology stack, when you split your software into independent services you can choose your technology stack for each service. For example, you can use C/C++ for real-time services, Java for the GUI, and Node.js for reporting. You should remember that there will be overhead for having different technology stacks for each service.

You need to design your services to handle the failure of other services; they need to be resilient. This is a side-effect of making the software individual components. You need to consider how a failure of a single service will affect the overall user experience. As a consequence of this, each service should fail as quickly as possible and restore itself automatically, if possible.

Scaling is one of the big advantages of microservices and one of the reasons it is so popular. Since each service (feature) does not depend on the other services, they can be deployed separately. You can now distribute the services across servers and replicate them as load demands increase. Compare this to traditional development that must scale the entire application as demands increase.

Different microservices can be owned by different teams. Teams are cross-functional, which means that they contain the full range of skills for the development of the service. The development team builds the software and owns the product for its lifetime. An example of this is Amazon’s philosophy "You build it, you run it." The advantage is that the development team now has special insight into how users are using their service and can tailor future development to their needs. Teams can also be organized around business capabilities but you will need to watch out for Conway’s Law where the design tends to mimic the organizational structure (see our blog post Overcoming Conway’s Law: Protecting Design from Organization).

Finally, because of the componentization of the software there is a lot of opportunity for reuse of functionality. In the microservices architecture, as you are making the software individual components you should also be designing them so that many different programs can reuse the functionality. This does take significant effort and awareness to be done correctly but can also lead to increases in quality and productivity (for more information see “Effects of Reuse on Quality, Productivity and Economics" by Wayne C. Lim).

To summarize, microservices: are autonomous, using services to componentize the software; use decentralized governance; are designed to handle service interruptions; are easily scalable; focus on products not projects; are typically organized around business capabilities; and promote software reuse. To learn more see our whitepaper "Developing a Microservices Architecture."

Four Reasons to Refactor your Code

1. Maintenance is easier


Legacy code architecture erodes over time and becomes difficult to maintain. Legacy code bugs are harder to find and fix. Testing any changes in legacy code takes longer. Even small changes can inadvertently break the application because over time the design has been extended to accommodate new features and the code has become increasingly coupled. Refactoring code allows you to improve the architecture, reduce the coupling, and help the development team understand the intended design of the system. A clean architecture makes the design understandable and easier to manage and change.

Read our other blog on Reasons NOT to Refactor.

2. Make the Design Modular

Split up large applications into components. For instance, monolithic applications can be split up into microservices. In embedded systems, interfaces are created to allow drivers to be written to support a variety of hardware devices. These drivers serve to encapsulate the logic for interacting with different hardware devices. Also, most large applications can often be layered into separate layers such as the business logic and the user interface, which can itself be split up into various pages, forms, dialogs and other components. Modularity simplifies the design and is probably the most effective way to increase team productivity.

Check out our blog on a New Way to Think About Software Design.

3. Refactoring is often the cheaper option

When faced with new requirements that appear not to fit into the current design, it is often tempting to propose a complete rewrite. However, a rewrite can be expensive and highly risky. When a rewrite of a project fails it leaves in its wake a dispirited organization with no product to take to market. Before starting a rewrite, do a what-if exercise on the current application to see what would need to change to support the new requirements. Often large parts of an application can be salvaged while other parts are refactored, thereby reducing risk and saving considerable time and effort.

4. Your development team is happier

A design that is easy to understand reduces stress on the team. A modular design allows different team members to improve different components of the project at the same time without breaking each other’s code.