background

The most popular technology architecture topic in the industry these two years has moved away from the front and back end to distributed, microservices, and DDD. Is microservices architecture appropriate for all companies, and at what point does the business scenario evolve to consider microservices? After all, the choice of technology architecture should be based on whether the business is compatible with it or not. Otherwise, the onerous architecture design such as distributed and microservices becomes a kill-or-kill technique for some companies and becomes a burden for the front-line development team.

In my short career, I’ve worked in small startups, large projects like state-owned enterprises, and various projects I’ve seen at ThoughtWorks. Architecture is like a grocery store, and microservices are just tool boxes, not hammers looking for nails.

I want to try to make architecture more accessible, forgive me for the many inappropriate metaphors. In order to describe the evolution of technical architecture of common Internet companies, a virtual background is set here:

Neo, a software engineer, stayed in the city after graduation to join an Internet startup that offers food delivery services to restaurants, where users can pre-order ingredients from an APP or wechat and the company delivers them the next morning. The Java + MySQL stack is used, so far only one server is used, and the database and applications are still deployed on the same server.

One of the first issues Neo’s team faced as users grew and services became more complex was the need to scale up the system to make it more responsive. Capacity expansion for Internet companies is generally “add machines”, so the first step, how to add machines?

Single-database multi-application service architecture

When I added the machine scheme, the first thing THAT came to my mind was the working mode of the software Park restaurant.

The user of the software system is like the customer of the restaurant, and the server is like the server, which can charge and sell food, like sometimes we have the application code and database deployed on the same server. Adding staff to a model in which the waiter is responsible for both the checkout and the meal is inefficient and the final tally is likely to be inconsistent, so restaurants typically have more than one waiter serving the meal and one person taking care of the bill.

Going back to our architectural issues, if we need multiple servers to respond to more users, we also need to ensure data consistency. According to the paradigm theory of database, the lower the redundancy of data, the higher the consistency of data. Therefore, our first step can be separated into multiple application servers to handle user requests and a database server to deal with data reading and writing in a centralized manner, so as to share the server pressure and ensure the correctness of data.

However, in the application server entry, we need to add a load balancing server to distribute different user requests to specific application servers. This is somewhat similar to the queuing machine in a restaurant, which diverts users. A load balancing server can be a common PC server configured with Nginx software or a dedicated hardware load balancing device such as F5.

Neo’s team spent half a month redeploying the servers, improving performance by stripping databases and adding application servers.

Database architecture for read-write separation

Half a year passed quickly, Neo’s company added many new businesses and the system added more features. Merchants who ordered vegetables could also check their orders and various statistics on their phones. Neo found that even with the addition of application servers, users had to wait for a long time, and eventually the database was hit by a bottleneck.

Databases are the hardest problem in distributed architectures because unlike application servers, they do not hold data. If you want to increase the number of database servers, you first need to address data duplication and consistency. In reality, there are many corresponding schemes, such as read/write separation, database physical partition, logical partition table, logical partition library, but in essence, just split the database operation in different ways, and we deal with the database performance of the most common and cost-effective way is read/write separation.

Again, I can’t help but use the food city example to illustrate the idea of database read-write separation.

As mentioned above, centralized processing of the data worked well at first, but as the number of users increased, the servers responsible for processing the data became overwhelmed. The same example: In real life, another operation mode appears in scenes with more traffic, such as many food cities. Food cities are generally composed of management companies and various merchants. Consumers need to first go to the top-up point set by the management company, and then swipe the card at each merchant. The checkout personnel only need to write the top-up data, and then each merchant can read the data.

Since reading data requires a large amount of computing resources and does not need to modify the data, we can consider separating the database read and write operations.

We can use the master/slave architecture of the database to increase the number of read servers. The master database guarantees the consistency of data, and the master server synchronizes data to the slave server to achieve the final consistency of data. Of course, this architecture can still encounter performance bottlenecks, but it can be used for a long time.

Of course, if you add caching, static file separation, performance is further improved. The average project at this point can handle most of the requirements.

However, in the following days, the product manager proposed that video introduction should be provided in the ordering page of food materials, so a large number of video transcoding operations consuming computing resources or consuming time appeared in the system.

Use the architecture of message queues

There’s a classic line from the movie Let the Bullets Fly, “Let the bullets fly for a while.” The world of programming is always similar to real life. If we want to send a piece of mail to the post office, or send a package to the express company, we don’t have to wait for the mail or the package to reach the recipient before we leave, which can take days.

Accordingly, systems tend to have a similar scenario, when we go to video web site after uploading a video, video web site often for transcoding to fit network play, this operation requires a lot of server resources, impossible in real time when users click on the submit completed post-processing, otherwise the user needs to wait for a long time, even the connection timeout.

For this kind of application scenario, we can spare the system from having to deal with such tasks in real time. When a user submits a request, the system adds the task to the message queue and changes the status of the data after completion. The user knows that the task has been processed after refreshing or receiving notification.

In the system architecture mentioned above, application servers are simply cloned and deployed separately, and the code on each application server is identical. Just like protozoa, cells don’t differentiate and all cells have the same function. From this section on, the responsibilities of different application servers change, just as plants start to differentiate cells.

With the development of the business, Neo’s company began to expand into new areas, developing agent platforms and logistics platforms to expand more merchants. It even needed to connect with third-party platforms and ensure that some common data and logic on these platforms were consistent.

Service-oriented Architecture (SOA)

If you have seen the cartoon “Working Cell”, you will be impressed by the cute sister platelet, “Working Cell” through the way of animation anthropomorphic tells the responsibility and work of different cells in the human body. Each cell has its own unique function, with platelets responsible for stopping bleeding and repairing wounds, and T cells responsible for engulfing foreign bodies and finding invaders.

As software systems become more complex and more developers are involved, it makes sense to separate and differentiate applications. Front-end ORIENTED API application servers no longer really handle the business logic but instead call specialized servers to do it.

Single sign-on (SSO) is a typical service-oriented architecture that is widely used in Internet companies. Chinese Internet giants often have multiple systems, such as Tencent’s QQ Music and Space, which can be logged in using the same QQ id. As a result, user services and authentication services are separated, and user experience is greatly improved through unified login and management of user information between various systems. This is an example of service-oriented architecture.

These large factories not only completed unified authentication and user management in their own systems, but also opened the login and authorization services to third-party systems. Many websites, for example, support wechat login, which allows users to use a set of usernames and passwords to log in to a large number of systems. And the industry has a general specification, easy access to all kinds of systems, this is the OAuth standard.

There are many ways to invoke a service, using the RPC framework or using HTTP requests directly, depending on the network protocol.

Neo’s company, through a service-oriented architecture transformation, has divided the system into user service, logistics service, order service and other services, and provides authentication connection of cash register system through OAuth. Some cash register manufacturers have also connected with this system, and merchants can order food ingredients through the supported cash register equipment.

Microservices Architecture

As Neo’s company grew rapidly, more and more business requirements were added to the system, which became extremely large. Different applications and data depend on each other, the logic is entangled, the deployment of projects into a chaotic state, for large, complex dependency systems need a more robust architecture. This is where microservices and domain-driven modeling (DDD) comes in to address the problem of system complexity and service decoupling.

Microservices are a concept that everyone knows came from Martin Fowler and became popular with him. Applications of the above mentioned architectures are still strongly related to each other, and even when they are separated, they are treated as system components, making it difficult to operate independently.

Microservices are designed to decouple large software systems. Services with different responsibilities are deployed independently to achieve high cohesion within services and low coupling between services, making development more flexible. Of course “apart for better together”, a basket of tools has been invented to recombine and stabilize these services, including service discovery, circuit breakers, and service deployment monitoring.

I used to joke with my colleagues that the best microservices do is a country’s government. I believe everyone has been to the government affairs center, which operates like a software system when you need to apply for an account or other municipal business.

The signage in the hall is like an API gateway everywhere. It helps you to arrange the number and also requires your ID card (authentication). If you are found not to meet the requirements of this area (authorization or scope), you will be rejected directly. When you queue multiple people and assign them to different Windows, you feel like you’re not dealing with the little sister in the foreground but with a load balancing server with polling policies. For some businesses, the window for receiving the business is BFF (Backend for Frontend) but not actually processed. The actual processing department will submit the data to the archives, just like reading and writing database. When a department in the system stops working for some reason, a notice will be posted (circuit breaker). Of course, there are too many examples to repeat.

Microservices are not even an architecture, but rather an ecosystem, with applications independent of each other but dependent on each other. Design a map using the DDD model and put the right code in the right place. There are too many tools involved in implementing microservices, some of which I have omitted to make the architecture clearer.

The myth of architecture

Zhou Aimin, the former architect of Alipay, once said that “real architects have no title”. However, in fact, there is no title in the architecture of IT system. The architecture of each company is unique, mixed and suitable for business needs. IT is hard to say that our current architecture is the standard “micro service”, and a “standard micro service” may sometimes be very uncomfortable for front-line developers.

Architecture is also difficult to design perfectly from the start. Architecture is not designed, or even cannot be designed, but can only evolve as requirements change. The job of an architect is not so much to build the big picture as an architect, but rather to serve as a pharmacist. As Cathedral and Bazaar puts it, “software is largely a service industry, though long and unreasonably mistaken as a manufacturing industry.”

Just as life evolves by adapting to the natural environment; To be agile, our architecture needs to evolve according to our requirements.

WeChat
Sina Weibo
Evernote
Pocket
Instapaper
Email
LinkedIn
Pinterest