1

Overview of Microservices

Microservice architecture is an architectural style that builds a large system as a collection of multiple microservices, which are built around business functions. Services focus on a single business function. These services have the following characteristics:

  • Highly maintainable and testable
  • loose coupling
  • Can be deployed independently
  • Build around business capabilities
  • Maintained by different small teams

The microservice architecture can deliver large and complex applications quickly, frequently and reliably, realize service componentization through business splitting, and use components to combine to quickly develop systems.

Service division

We first divide microservices. In actual project development, we usually adopt two strategies for dividing microservices. The first way is to divide the boundaries of microservices through business functions, and the second way is to use the bounded context of DDD. To divide the boundaries of microservices, we use the business functions that are easier for everyone to understand to divide microservices, and paste the mind map of our e-commerce project again:

From the above mind map, we can see that the entire e-commerce system has many functions. We divide the following microservices according to business functions:

  • Product service (product) - functions such as product addition, information query, inventory management, etc.
  • Shopping Cart Service (cart) - Add, delete, modify and check shopping carts
  • Order service (order) - generate orders, order management
  • Payment service (pay) - realize payment function by calling third-party payment
  • Account service (user) - user information, level, ban, address management
  • Recommendation service (recommend) - Home page product recommendation
  • Comment service (reply) - product comment function, comment reply function

BFF layer

Generally, we use HTTP interfaces to provide services to clients. Does the above-mentioned microservices need to directly provide HTTP interfaces to provide services to the outside world? This is of course possible, and the overall architecture looks relatively simple.

But for a complex high-concurrency system, we need to deal with various abnormal scenarios. For example, a page needs to rely on data provided by multiple microservices. In order to avoid the time-consuming caused by serial requests, we generally To request multiple microservices in parallel, at this time, if one of the service requests is abnormal, we may need to do some special processing, such as providing some degraded data. In addition, the data displayed on our pages are often oriented to business functions, rather than the data of a single microservice. At this time, we often need to assemble the data of multiple microservices to meet the needs. If each of our microservices directly If the HTTP interface is provided externally, then these complex data assembly and exception handling can only be done by the client. As we all know, the client is not suitable for complex business logic. The focus of the client should be more on the optimization of the interactive experience. Our overall architecture needs to focus on the front and the back, that is, the client logic should be as little as possible and the heavier business The processing logic sinks to the server side, and the server side is divided into different microservices according to business functions. These microservices only focus on a single business, so where should the processing of these complex logic oriented to business scenarios be placed? Our solution is to add a layer, that is, the BFF layer, through which the HTTP interface is provided externally, and the client only interacts with the BFF.

The introduction of the BFF layer solves the problems we encountered above, but adding one layer will increase the complexity of the architecture, so if your service is a single application, then the BFF is unnecessary, and introducing it will not increase any value. For our project, our application relies on microservices, and we need to provide HTTP interfaces for business functions and ensure high availability of interfaces, so BFF is a suitable choice for our project.

Can we provide multiple BFFs? The answer is of course. The purpose of BFF is to provide a centralized interface for clients. For example, the data protocols of mobile pages and browser pages are different. In this case, in order to better represent data, two BFFs can be used, and only one BFF can be used at the same time. BFF exceptions will affect all services. Providing multiple BFFs can also improve service availability and reduce the impact of service exceptions. The multiple BFF architecture diagrams are as follows:

Our project will only use one BFF service for simplicity.

Engineering structure

We adopt a centralized management method and put all services into a large warehouse. The directory structure of the warehouse is as follows:

lebron is the project name. There are two directories, apps and pkg, under lebron. Apps stores all our microservices. For example, order is an order-related microservice. The pkg directory is the storage path of packages that all services depend on together, such as all All services need to rely on authentication and can be placed in the pkg directory.

  • app - BFF service
  • cart - shopping cart service
  • order - order service
  • pay - payment service
  • product - commodity service
  • recommend - recommend service
  • reply - the comment service
  • user - account service

In each service directory, we will be divided into multiple services, mainly the following types of services:

  • api - External BFF service, accepting requests from clients, exposing HTTP interfaces
  • rpc - Internal microservice, only accepts requests from other internal microservices or BFF, and exposes the gRPC interface
  • rmq - responsible for streaming task processing, the upstream generally relies on message queues, such as kafka, etc.
  • admin - is also an internal service. Different from RPC, it is more oriented to the operation side and has higher data authority. It can bring better code-level security through isolation and directly provide HTTP interface.

The structure of each service in the apps directory is as follows:

Most services will be split into rpc, rmq and admin to meet the needs of providing rpc interface and operational data internally, while processing streaming tasks through rmq. What is special is that there is only api service under the app, because the app is BFF only has api service, and rmq service may be added later, for example, to stream the logic of the user's first login and experience every day, we can expand it at any time later, temporarily first. Only provide api services. recommend only has the rpc service, because the recommendation service needs to rely on the data provided by the AI team or the big data team, we only need to request the corresponding data interface and do some business-satisfying processing, so here recommend only the rpc service.

code initialization

The structure of the entire project has been clearly defined, let's do the initialization of the service code below

We use goctl to initialize the project. For example, we initialize the order first and enter the order directory first:

 $ cd lebron/apps/order

Execute the following command to initialize the order rpc code

 $ goctl rpc new rpc

The generated code structure is as follows:

Execute the following command to initialize the order admin code. Note that the order admin is an api service that directly provides an HTTP interface to the front end

 $ goctl api new admin

The generated code structure is as follows:

We can run the generated service code directly, listening on port 8888 by default

 $ go run admin.go

Starting server at 0.0.0.0:8888...

For the rmq service, we will use the kq function provided by go-zero. Here we initialize main.go first.

At this point, the code initialization of the order service has been completed, and other services are similar to the order service, so I won't go into details here.

There is currently no need to initialize under pkg, and we will add it when we need to provide general business functions.

concluding remarks

In this article, we explain the definition of microservices. Microservices are built around business functions. Services focus on a single business. A lightweight communication mechanism is used between services. Each microservice can be deployed and tested independently.

We split the microservices according to the function of the mall, mainly splitting services such as shopping cart, order, payment, commodity, comment, recommendation, account, etc., and then we explained why we need to introduce BFF service. BFF is essentially a user For data assembly services, it provides external HTTP interfaces for business functions or for client UIs.

Then we defined the directory structure of our project, which is mainly divided into services such as api, rpc, rmq, and admin. Different services have different responsibilities. API provides HTTP interface externally, rpc provides RPC interface internally, and rmq handles streaming data processing. , admin provides HTTP interface for operation background.

Finally, we initialized the project through goctl. Using goctl can generate the project framework code with one click, which greatly improves productivity.

Hope this article is helpful to you, thank you.

Updated every Monday and Thursday

Code repository: https://github.com/zhoushuguang/lebron

refer to

https://microservices.io/index.html

https://blog.bitsrc.io/bff-pattern-backend-for-frontend-an-introduction-e4fa965128bf

project address

https://github.com/zeromicro/go-zero

Welcome go-zero and star support us!

WeChat exchange group

Follow the official account of " Microservice Practice " and click on the exchange group to get the QR code of the community group.


kevinwan
931 声望3.5k 粉丝

go-zero作者