The author | wang shu
What are microservices
Microservices is an architectural style in which a large complex software application consists of one or more microservices. Each microservice in the system can be deployed independently, and each microservice is loosely coupled. Each microservice is only focused on completing one task and doing it well. In all cases, each task represents a small business capability. The concept of micro service from March 2014 Martin Fowler wrote an article “Microservices” (http://martinfowler.com/articles/microservices.html).
Although there is no precise definition of the “microservices” architectural style, it has some common features, such as organizing services around business capabilities, automated deployment, intelligent endpoints, and “decentralized” control of language and data. The thinking about microservices architecture comes from comparing it to the overall application.
Typically, as a company evolves (organically) as its business needs grow, systems are organized in a monolithic architecture up front. Because the monolithic architecture approach is the easiest and most efficient way to start building software. But over the years (or even months), it becomes increasingly difficult to add new functionality to an existing monolithic software system due to its internal coupling.
A single piece of software
Enterprise applications, because they serve many business requirements, have specific software applications that provide many functions, and it is common practice to stack these functions in a single monolithic application. For example, ERP, CRM, and other various software systems are planned to be built into wholes with hundreds of functions. Once deployed, such pitted applications can be a nightmare after a nightmare in troubleshooting, scaling, and upgrade scenarios.
Service-oriented Architecture (SOA) aims to overcome these limitations by introducing the concept of “services”, aggregates and groupings drawn from similar functions provided by applications. Thus, with SOA, software applications are designed as a composition of “coarse-grained” services. However, the scope of services in SOA is very wide, which leads to complex and large services with a host of operations (functions) and extremely complex message formats and standards (such as THE WS * standard).
In most cases, services in an SOA are independent of each other, except that they are deployed in the same runtime with all other services (just consider multiple Web applications that will be deployed to the same Tomcat instance). Similar to monolithic software applications, these services have a habit of accumulating work over time. Figure 1 is a good example of a monolithic architecture, showing a retail software application that includes multiple services, all of which can be deployed to the same application.
After all this talk, are you a little confused? I’ve summarized some of the highlights, and here are some of the features of applications based on a single fast software architecture:
-
Monolithic applications are designed, developed, and deployed as a single unit.
-
The complexity of monolithic applications makes maintenance, upgrades, and new features difficult.
-
It is difficult to practice agile development and delivery methods with monolithic architectures.
-
If you want to update a part, you will most likely have to redeploy the entire application.
-
In the case of conflicting scale requirements, if you want to do A single point of expansion, you need to be prepared to multiply resources and even start from scratch (for example, if you want to give service A more CPU, service B may have to redo, or maybe two or three times more memory).
-
Reliability: An unstable service can slow down overall application performance.
-
Difficult to innovate: It is very difficult to adopt new technologies and frameworks because all functionality must be built on a uniform technology/framework.
Microservices-oriented architecture
Microservices-oriented architectures have some characteristics. Medium to large companies of any size that want to keep their IT systems resilient and ready to scale will be looking for these attributes.
Why is microservices-oriented architecture better
Microservices Architecture (MSA) is based on the development of monolithic applications as a set of small and independent services that are independently developed, deployed, and run in their own space. In most definitions of microservice architecture, it is generally interpreted as the process of isolating a large number of available services into a single set of services.
But microservice-oriented architecture is not the holy grail of unengineering. Resilience, composability, and flexibility are key principles of microservice-oriented architecture design. If you don’t, you’ll lose a perfect solution and end up with a lot of problems when a monolithic application is split across multiple machines.
Deficiency in
There are also some problems with micro-services.
-
Network latency: Due to the distributed nature of microservices, network latency is inevitable
-
O&m burden: More servers also means more maintenance work
-
Final consistency: In a system with high transactional requirements, each node may have inconsistent data at some point in time, considering implementation limitations
Key design Principles
In general, we can determine the design principles:
-
Single Responsibility Principle (SRP) : Providing a limited and focused business scope for microservices helps us meet agility in developing and delivering services.
-
In the design phase of microservices, we should find the boundaries of each service and align them with business capabilities (also known as bounded environments in domain-driven design).
-
Microservices are designed to ensure the silky stability of agile/independent development and deployment services.
-
Our focus should be on the scope of microservices, not making them “smaller.” The size of the service should refer to the size of the scope required to facilitate a given business capability.
-
Unlike services in SOA, a given microservice should have few operations/functions and a simple message format.
-
Over time, it is good practice to start with relatively broad service boundaries and refactor to smaller service boundaries (based on business requirements).
Key benefits
Now let’s look at a few key benefits.
The elastic
Wikipedia defines resilience as the ability of a system to handle change. My understanding of resilience is the ability to recover gracefully from abnormal conditions or periods of stress after a problem has been resolved without affecting system performance.
This may seem simple, but when building microservices-oriented software, the source of the problem is magnified by the distributed nature of the system, and it is sometimes difficult to prevent all exceptions.
Resilience is the ability to gracefully bounce back from mistakes. But it also introduces a new complexity to the system: If a microservice fails, can we prevent the system from failing on a regular basis? Ideally, we should build services in such a way that we degrade only the service response rather than allow the system to fail routinely, even though this is not easy.
scalability
Scalability is a common problem in today’s companies. Typically, these issues do not cover every level or every subsystem of the application. Often, only individual subsystems or services will be obvious to the rest of the application, and failure to handle capacity issues can cause the entire application to fail.
The following diagram illustrates how to extend the microservice (to two mail services) without affecting the rest of the system:
Diversity of technology
The software world comes out with updated systems every few months. The rhythm of new languages coming into the industry as a de facto standard for certain kinds of systems comes to a halt.
-
Golang: It’s a current trend because it combines powerful performance with elegant and concise syntax, and anyone with experience in a programming language can learn it in a matter of days.
-
Java: Since the release of Sping Boot, it has become an attractive technology stack for writing agile services.
-
DJango: Is a powerful Python framework for writing microservices, much like Ruby on Raile.
-
Node.js: Takes advantage of the famous JavaScript and creates a new server-side technology stack that changes the way engineers write new software.
So what are the problems with combining the technology stacks of these languages? To be fair, this is an advantage: we can choose the right tools to do the job. As long as the technology to be integrated is standardized, a microservices-oriented architecture can do this for you.
The following figure shows how microservices hide the data access logic, and the two services share the same communication point for data access, thus decoupling nicely from each other:
Node.js is not a good language for parallel tasks. For microservices that are under pressure, a more suitable language for development, such as Erlang, can be used to manage concurrency in a more elegant way.
replaceability
Replaceability is the ability to replace a component of a system without affecting the behavior of the system. When we talk about software, replaceability often goes hand in hand with low coupling. The internal logic cannot be exposed to the calling service when the microservice is written. The service implementation is transparent to the client, and the client only needs to understand the interface.
independence
All services should be independent and interact through interfaces. With the exception of protocol validation interfaces, different teams of engineers can develop services without communication.
Easy to deploy
Microservices should be easy to deploy for the following reasons:
-
Less business logic, resulting in easier deployment.
-
Microservices are autonomous units of work, so upgrading a service is a locally manageable problem for complex systems. No need to redeploy the entire system.
-
The infrastructure and configuration in the microservices architecture should be as automated as possible (such as Docker to deploy microservices).
SOA vs. microservices
Microservice Oriented Architecture (SOA) and microservice architecture are very imaginative. So what is the difference between them?
Microservices are fine-grained SOA components. In other words, a single SOA component can be split into multiple microservices that, through collaboration, provide the same level of functionality as the original SOA component, as shown below:
Another difference between microservices and SOA is the interconnection of services and the technologies used when writing services. Microservices, on the other hand, advocate standards such as HTTP that are widely understood and commonly used. We can reap the key benefits of technological diversity by choosing the right language or work to build a component (microservice).
In addition to the technology stack and service scale, there is an even bigger difference between SOA and microservices: the domain model. In an opportunistic microservice software, each microservice should store its own management data locally and isolate the domain model into a single service. In SOA-oriented software, data is often stored in a single large database and domain models are shared between services.
Why node.js
Node.js is a new technology stack, and for many people, it’s just a trend, not a real tool for solving problems.
Let’s focus on Node.js. Node.js is an excellent choice for building microservices-oriented architectures for the following reasons:
-
Low barriers to learning (there are barriers if you want to be proficient)
-
extensible
-
Test friendly
-
Easy to deploy
-
Dependency management can be done through NPM
-
There are a number of libraries that integrate with mainstream standard protocols
API polymerization
API aggregation is an advanced technique for combining different functions (plug-ins, methods, and so on) into a single interface. Example:
const express = require('express');
const app = express();
app.get('/sayhello', function (req, res) {
res.send('Hello World! ');
});
app.get('/saygoodbye', function(req, res) {
res.send('Bye bye! ');
}
const server = app.listen(3000, function () {
let host = server.address().address;
let port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
Copy the code
The previous example uses Express, a Web framework that is popular in the Node.js technology stack. The framework is also built around API aggregation.
Let’s look at lines 4 and 7. In this code, the developer registers two methods. When someone requests urls: / sayHello and/sayGoodbye as GET requests, the two corresponding methods are executed. In this case, the interface is an app listening on port 3000.
summary
In this article you learned about some of the key benefits of a microservices-oriented architecture, such as the ability to choose the right language for the corresponding service (language diversity); And some of the misconceptions that may add to our burden, such as the operational overhead of having the distributed nature of the architecture for microservices.
Finally, we discussed node.js as a powerful tool for building microservices and how to build high-quality software components by leveraging techniques like API aggregation to benefit from JavaScript.