The author | jian-fei zhang Alibaba senior technical experts
architecture
What is architecture?
It is difficult to give a clear definition of architecture, and there is no standard definition.
Just to give an overview, I think architecture is an abstract description of the entities in a system and the relationships between them.
Architecture begins with architecture because of human development (primitive man is self-sufficient and lives in trees, so there is no need for architecture) and the need for division of labor and cooperation. The target system is segmented according to a certain principle, which is convenient for different roles to work in parallel.
Why architecture?
Where there is a system, architecture is needed, ranging from a large aircraft to a small functional component in an e-commerce system.
One of my favorite quotes in Systems Architecture: Product Design and Development for Complex Systems is that well-structured creative activity is better than unstructured creative activity.
In contrast, many agile ideas now advocate no design, just work. Expect good architecture to emerge naturally in iterations. This idea is a bit too idealistic. In reality, engineers have little incentive to refactor and optimize as long as the code works.
Responsibilities of the architect
As architects, our most important value should be “simplifying”. Any architecture that makes things more complicated, that makes systems more obscure is questionable.
The architect’s job is to try to train his mind to understand complex systems and make those systems less difficult through proper decomposition and abstraction. We should strive to build an architecture that is easily understood by other people working on the system (such as designers, implementers, operators, etc.).
Software architecture
A software architecture is a sketch of a system. Software architecture describes objects that are abstract components that directly constitute a system. Connections between components explicitly and in relative detail describe communication between components. In the implementation phase, these abstract components are refined into actual components, such as concrete classes or objects. In the object-oriented world, interfaces are often used to connect components.
Software architecture provides a high-level abstraction of the structure, behavior, and properties of a software system, consisting of a description of components, their interactions, patterns that guide component integration, and the constraints of those patterns. Software architecture not only shows the correspondence between software requirements and software architecture, but also specifies the organization and topology of the entire software system, providing some basic principles for design decisions.
The core value of software architecture should revolve around a single core proposition: controlling complexity. He does not mean a particular layered structure, a particular methodology (anemia, DDD, etc.).
Software Architecture Classification
Before introducing application architecture, let’s take a look at the categories of software architecture.
With the development of the Internet, the current system has to support the needs of hundreds of millions of people shopping, communication and entertainment online at the same time, and the corresponding software architecture has become more and more complex. The meaning of software architecture has also become broader, we can not simply use a software architecture to refer to all software architecture work. As I understand it, I divide software architecture into:
Business Architecture: Responsible for business architects, also known as business domain experts, industry experts. Business architecture belongs to the top-level design, and its definition and division of business will affect the organizational structure and technical architecture. For example, before Alibaba did not have the Central Taiwan department, the technical structure of each business department was chimney style, taobao, Tmall, Feizhu, 1688 and so on each have a set of system structure. Later, the shared platform Business Division was established to get through the account, goods, orders and other systems, making it possible to reuse the implementation of commercial basis.
Application architecture: An application architect is responsible for designing application hierarchies, formulating application specifications, and defining interfaces and data interaction protocols according to the needs of business scenarios. In addition, the complexity of applications should be controlled to an acceptable level. In this way, applications can meet non-functional attributes (such as performance, security, and stability) while rapidly supporting service development and ensuring system availability and maintainability.
Distributed System Architecture: Distributed systems are almost mandatory for larger businesses. It has to deal with server load, registration and discovery of distributed services, messaging systems, caching systems, and distributed databases, while the architect has to balance Consistency, Availability, Partition tolerance (CAP).
Data Architecture: For larger organizations, data governance is an important topic. How to provide uniform service and standard for data collection and data processing is the problem that data architecture needs to pay attention to. Its purpose is to unify data definition norms, standardize data expression, form effective and easy to maintain data assets, build a unified big data processing platform, and form a closed loop of data use.
Physical architecture: Physical architecture is concerned with how software components are placed on hardware, including room building, network topology, network shunt, proxy server, Web server, application server, report server, consolidation server, storage server, and host.
Operation and maintenance architecture: responsible for the planning, selection and deployment of the operation and maintenance system and the establishment of a standardized operation and maintenance system.
Typical Application Architecture
Layered architecture
Layering is a common practice for organizing units of code according to roles in the system (separation of responsibilities). The common hierarchical structure is shown in the figure below:
CQRS
CQS(Command Query Separation) is a concept originally developed by Betrand Meyer, the father of the Eiffel language and creator of OCP. The basic idea is that methods on any object can be divided into two broad categories:
- Command: returns no result (void), but changes the state of the object.
- Query: Returns a result without changing the state of the object and has no adverse effects on the system.
Hexagonal structure
Hexagonal architecture was proposed by Alistair Cockburn in 2005 to solve the problem of traditional hierarchical architecture. It is actually a hierarchical architecture, but instead of top and bottom, it becomes inside and outside (as shown in the figure below).
Hexagonal architecture is also known as port-to-adapter architecture, which is more container friendly. A hexagon architecture divides a system into internal (internal hexagon) and external, with the internal representing the application’s business logic and the external representing the application’s driving logic, infrastructure, or other applications.
Adapters are classified into two types (as shown in the following figure). The Adapters on the left that represent the UI are called Driving Adapters because they initiate some operations on the application. Adapters shown on the right that link to the back-end tool are called passive Adapters because they only respond to the operation of the primary adapter.
Onion ring architecture
The Onion architecture has the same idea as the Hexagon architecture in that they both write adapter code to take the focus off the infrastructure of the application core and prevent the infrastructure code from infiltrating the application core. The tools and delivery mechanisms used by the application can be easily replaceable, avoiding a degree of technology, tool, or vendor lock-in.
The difference is that the Onion architecture also tells us that there are more than two layers in enterprise applications, adding layers (Application, Domain Service, Domain Model, Infrastructure, etc.) to the business logic that are identified in the domain-driven design process.
In addition, it has the advantage that applications can run without the real infrastructure and delivery mechanisms, so you can mock them instead for easy testing.
In the Onion architecture, the direction of dependencies is specified:
- Outer layer depends on inner layer;
- The inner layer has no sense of the outer layer.
COLA Application Architecture
COLA architecture is an application architecture independently developed by my team, which is now open source. In the design of COLA, we draw on the best ideas of classical architecture. In addition to this, we supplement the specification design and extension design, and use Archetype to solidify the architecture so that it can be used quickly in development.
COLA open Source address: github.com/alibaba/COL…
The layered design
The layered COLA is an improved three-tier architecture. The traditional business logic layer is divided into application layer, domain layer and basic implementation layer. As shown in the figure below, the traditional layered architecture is on the left and the layered architecture of COLA is on the right.
The scope and meaning of each layer are as follows:
1) Presentation Layer: Responsible for receiving Web requests in Rest format, and then routing the requests to the Application layer for execution, and returning the View Model, its carrier is usually DTO (Data Transfer Object);
2) Application Layer: it is mainly responsible for obtaining input, assembling context, verifying input, calling domain Layer for business processing, and sending message notification if necessary. Of course, the layers are open, and the application layer can also directly access the underlying implementation layer if needed.
3) Domain Layer: it mainly encapsulates core business logic and provides external calculation and processing of business logic through the functions of Domain Service and Domain object.
4) The Infrastructure Layer mainly includes Tunnel (data channel), Config and Common. Here we use the concept of Tunnel to abstract all data sources, which can be databases (MySQL, NoSql), search engines, file systems, SOA services, etc. Config is responsible for application configuration. Common is the generic utility class.
Scalable design
For a simple scenario with only one business, the need for extensibility is not so great, which is why extensibility design is often overlooked, because most of our systems start with a single business. However, as business scenarios became more complex, there began to be a lot of if-else logic in the code. At this point, in addition to regular policy patterns, we can consider providing a unified extension solution at the architectural level.
In the extension design, we distilled two important concepts, one is business identity and the other is extension point.
Business identity refers to the mark that uniquely identifies a business or a scenario in the system. In the concrete implementation, we use BizCode to represent business identity in a Java package-namespace-like manner. For example, we can use “ali. Tmall” said ali Tmall business, with “ali. Tmall. Car” said ali Tmall automotive business, with “ali. Tmall. Car. Aftermarket” represents the ali Tmall car business after market scenario.
Each business or scenario can implement one or more Extension points, that is, a business identity plus an Extension point uniquely identifies an Extension implementation. The combination of business identity and extension point is called ExtensionCoordinate, as shown in the figure below.
In this way, through business identity + extension points, we can realize the extension customization for different tenants, different businesses, and different scenarios at the framework level. The whole Ali business is based on this idea, the realization of multi-business support.
Specification design
Everything is a combination of regularity and randomness. The point of specification is that we can solidify things that are regular and minimize the complexity that comes with being arbitrary, and consistency reduces system complexity. From naming to architecture, architecture itself is a specification and a constraint, and breaking that constraint destroys architecture.
COLA has a list of specifications: Module structure, Package structure, naming, and so on.
For components, for example, we require COLA applications to follow the component division shown below:
Overview of the COLA architecture
In terms of architecture, COLA advocates the use of port-adaptors to decouple technical details like hexagonal architecture; Like the Onion circle architecture, the domain is the core and the dependency direction of the domain layer is reversed through dependency inversion. The resulting component relationship is shown in the figure below.
For another perspective, consider how the COLA application processes a response to a request. COLA uses CQRS to separate command and query responsibilities, and extension points and metadata to improve application scalability. The whole processing process is shown in the figure below:
The core of application architecture
Looking at all of the application architectures described above, one thing we can find in common is the “separation of core business logic and technical details”.
Yes, the core responsibility of the Hexagonal, Onion ring, and COLA architecture is to decouple and decouple core business logic from technical details.
Imagine a situation where the business logic and technical details are mixed together. All the code is written inside ServiceImpl. The first few lines do validation, the next few lines do convert, and then several lines of business processing logic, interspersed with, We need to get more data through RPC or DAO. After getting the data, we need several lines of convert code, followed by a business logic code, and then we need to drop the library and send the message….. And so on.
Even a simple business can become complex and difficult to maintain in this way of writing code.
Therefore, I believe that the core mission of application architecture is to separate business logic from technical details. Make the core business logic reflect domain models and domain applications, reusable, and easily understood. Allow technical details to be replaced while assisting in the implementation of business functions.
In the end, we find that the way to apply architecture is: “Let what is God be God, and what is Caesar be Caesar.”
“Alibaba Cloud originator focuses on micro-service, Serverless, container, Service Mesh and other technical fields, focuses on the trend of cloud native popular technology, large-scale implementation of cloud native practice, and becomes the public account that most understands cloud native developers.”