Design ideas of DMicro, a Go microservice development framework

Design ideas of Go microservice development framework DMicro

DMicro source address:

  • Gitee:
  • dmicro: dmicro is an efficient, scalable and easy-to-use microservice framework. Contains drpc, dserver, etc.

Background

The background of the birth of DMicro is because I wrote PHP for more than 10 years and wanted to promote Go within the company. The internal components and rpc protocol of the company are all based on swoole Customized development. Researched various frameworks on the market, including beego, goframe, gin, go-micro, go-zero, erpc, etc. It may be that my technical ability was limited at the time, and these frameworks could not be well adapted to our business.

We had several pain points in business development, and we could not find a complete set of solutions in the ecology of golang at that time.

  • Microservice applications and monolithic applications are developed at the same time.
  • High-performance, high-availability network communication.
  • Need to customize the protocol of the application layer (emphasis).
  • A flexible plug-in extension mechanism is required to facilitate adaptation to existing systems (emphasis).
  • The concepts of server and client are vague, and both can use the same api to call each other.
  • Push messages are supported.
  • Connection/session management.
  • Efficient development, support code generation through proto.
  • Support multiple network protocols, tcp, websocket, quic, unixsocket.
  • Compatible with http protocol.
  • The problem can be located more quickly.
  • Add new features more conveniently.

After doing a simple survey of commonly used open source frameworks, I found that there is no suitable framework that can meet all my needs. After serious thinking, I found that the combination of erpc and goframe can meet my needs, so the self-developed DMicro was born.

Overview

The idea of the drpc component in DMicro is to refer to the implementation of erpc, and it can even be said to be its successor.

The drpc component is a part of the DMicro framework. In order to adapt to the DMicro framework, it has been developed on the basis of erpc extension development.

The entire DMicro uses a lot of components in goframe, if the business uses the goframe framework, it can be seamlessly connected.

DRpc feature list:

  • Peer-to-peer communication , Peer-to-peer API
  • High performance , Non-blocking asynchronous IO
  • Custom Proto,, Compatible with http protocol, Custom Codec
  • Hook point , plug-in system ,
  • Push message, session management, Socket abstraction,
  • Disconnection reconnection , overload protection , load balancing , heartbeat mechanism ,
  • Graceful restart ...

List of DServer features:

  • quick build , smooth restart , multi-process support , single/multi-process consistency
  • predefined command line, ctrl command management service
  • observable , controllable , application sandbox

DMicro has built-in components:

  • [x] Registry service registration
  • [x] Selector service discovery
  • [x] Eventbus event bus
  • [x] Supervisor process management
  • [ ] Code gen code generation
  • [ ] Tracing link tracking
  • [ ] Metrics statistics alarm
  • [ ] Broker current limiting fuse
  • [ ] OpenAPI document is automatically generated

Structure

Design concept

The design of the DMicro framework has been pursuing flexibility and adaptability from the beginning of the design. On the premise of ensuring the stability of microservices, pursue the development efficiency of the project.

  • Interface-oriented design ensures code stability and provides flexible customization.
  • Abstract the interface of each component, high cohesion, low coupling.
  • Layered design, layer by layer packaging from top to bottom, which is conducive to stability and maintenance.
  • High performance, high availability, low consumption.
  • Friendly to development, encapsulates complexity.
  • Provide rich components and functions, allowing development to focus on business.

Countless days and nights of writing DMicro, I always keep in mind the three principles of development:

  • Clarity
  • Simplicity
  • Productivity

Regardless of work or open source projects, you should maintain these three principles and develop good habits.

Interface-oriented design

DMicro adheres to the principle that everything is an interface, and provides unparalleled scalability of the framework.

The figure below shows the flow of message sending. It can be seen that all function points are abstracted into interfaces, and each function point provides different implementations.

Session Session

Most Rpc frameworks do not emphasize the concept of session (session), because their application scenarios do not need to use session (session). Then Why does drpc need to abstract the session (session)?

  • Endpoint integrates Client and Server, and needs to provide the same Api.
  • The server needs to actively send messages to the client and get the response from the client.
  • The server supports sending messages in batches to multiple clients.
  • Asynchronously actively disconnect one or multiple sessions.
  • Get the underlying file descriptor of the session, and perform performance tuning on it.
  • Special data/properties can be bound per session.

Session abstracts the session of the entire drpc framework, and puts Socket, Message, Context All blended together. Developers only need to operate on session to achieve most of the requirements.

  • get connection info
  • Control the life cycle of the connection (timeout period)
  • Control the life cycle of a single request (timeout)
  • receive message
  • Send a message
  • The context in which the message was created
  • Information about the binding session (such as user information)
  • Disconnect and reconnect
  • Actively disconnect the session.
  • health examination
  • Get connection close event
  • set a separate id for the session

Session interface can be subdivided into 4 interface{}, namely EarlySession, BaseSession, CtxSession ,Session. Corresponding to the different attributes of the session (Session) in different life stages of the application.

  • EarlySession indicates that the session has just been generated and the goroutine has not yet started to read data.
  • BaseSession has only the most basic method, which is used for plug-in parameters when closing the connection.
  • CtxSession The session object passed in the handler context.
  • Session Full-featured session object.

Under normal circumstances, developers use the two interfaces Session and CtxSession, and the other two interfaces are used in plug-ins.

Message Message

The message Message contains the message header Header, and the message body Body, which is the entity of communication between the client and the server.

Message interface{} abstracts the operation of the communication entity.

  • Size the length of the message
  • Transfer-Filter-Pipeline message data filtering pipeline
  • Seq sequence number
  • MType message type
  • ServiceMethod resource identifier
  • Meta Metadata for the message
  • BodyCodec message body encoding format
  • Body message body

Protocol Proto

The protocol is the serialization and deserialization of the Message object, and the framework provides the Proto interface. Only by implementing this interface, developers can customize custom protocols that meet business needs, thereby improving the flexibility of the framework.

The interface is defined as follows:

type Proto interface {
Version() (byte, string)
Pack(Message) error
Unpack(Message) error
}
  • Version() returns the protocol’s id and name, which form a unique version number.
  • Pack serializes a message Message object.
  • Unpack deserializes the byte stream to generate a message Message object.

Currently the framework supports Http, Json, Raw, Protobuf, JsonRpc these 5 an agreement.

The RAW protocol consists of the following:

Other protocols can refer to the code.

Encoding Codec

As a general framework, there can be many supported protocols, and there can be many codecs for the message body. drpc uses the Codec interface to encode the message body decoding.

The interface is defined as follows:

type Codec interface {
ID () byte
Name() string
Marshal(interface{}) ([]byte, error)
Unmarshal([]byte, interface{}) error
}
  • ID returns the id of Codec
  • Name returns the name of the codec, the name is for developers to identify more easily.
  • Marshal encodes the content of the message
  • Unmarshal decodes the content of the message

Currently the framework supports Form, Json, plain, Protobuf, XML these 5 a codec.

Connect Socket

Socket extends net.Conn, and abstracts the interface to facilitate the integration of the framework to the underlying network protocol.

The Socket interface implements part of the functions of the Session interface. Some methods called by the Session interface actually forward and call the Socket method in code>.

Such a layered implementation allows Socket to have the ability to integrate other protocols.

  • TCP V4,TCP V6
  • Unix Socket
  • KCP
  • QUIC

Supports performance tuning for connections.

  • SetKeepAlive Turn on link keep alive
  • SetKeepAlivePeriod link keep-alive interval
  • SetReadBuffer Set the link read buffer size
  • SetWriteBuffer Get the link write buffer size
  • SetNoDelay Turn on and off the no delay algorithm
  • ControlFD supports raw handles for manipulating links

Organic combination

As mentioned above, everything in the DMicro framework is an interface, and the layered + interface design allows DMicro to have the ability to be flexible, efficient and in line with the actual business situation.

Next we will talk about the basis for realizing these capabilities. plugin system.

Plugins

The plug-in system brings great scalability and flexibility to the framework. It is a soul module of the whole framework. With it, the framework has unlimited possibilities.

What kind of plug-in system can be considered elegant? The ones I can think of are the following:

  • Reasonable and rich hook positions can cover the life cycle of the entire framework and run through all links of communication.
  • The input and output parameters of each hook position are carefully designed.
  • Each plugin can use multiple hook locations, and each hook location can be used by multiple plugins.
  • The design is simple enough and elegant. It is convenient for secondary development and customization.

In drpc, hooks run through the life cycle of the entire Endpoint and are an indispensable part of it.

Failed to transfer and re-upload to cancel Through these Hook points, the plugin is endowed with unlimited possibilities.

components

With plug-ins, you can write components with comprehensive functions through the combination of plug-ins. Currently, the framework provides some built-in components.

  • Server Rpc Server
  • Client Rpc Client
  • Service Registration Registry
  • Service Discovery Selector
  • Event Bus EventBus
  • Process Management Supervisor

Coming soon:

  • Link Tracing
  • Statistics Alarm Metrics
  • Current limit fuse Broker.

Due to limited space, the implementation of specific components will not be explained in depth here, please pay attention to the follow-up articles.

Future Outlook

If DMicro is compared to life, the growth stage is still in adolescence, and only the basic architecture design and the development of some components have been completed.

The next direction is mainly to develop in the direction of ease of use and reliability.

Ease of use:

  • Project performance tool dmctl tool development, including code generation, project structure generation, packaging, compilation and other functions.
  • Development of document components conforming to the openapi definition.
  • More complete documentation and usage examples.

reliability:

  • Observability
    • link tracking
    • Indicator information
    • log stream
  • production available
    • Improvement of test cases
    • code coverage
    • performance tuning

I hope that DMicro can thrive under everyone’s care and encouragement.