Skip to content

Latest commit

 

History

History

framework

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Framework

ORM

  • Object–relational mapping (ORM) is a programming technique for converting data between a relational database and the heap of an object-oriented programming language (Wikipedia), like Mybatis in java.
  • Using ORM, we can associate a data table in database with a certain class/struct, and by modifying the class/struct instance, we can easily CRUD the database without using SQL statements.

Gorm

RPC

  • Remote Procedure Call(RPC) is a software communication protocol that one program can use to request a service from a program located in another computer on a network without having to understand the network's details.

RPC Process

  • RPC Process:

RPC Process

Layers (From top to bottom)

Application Layer

In the application layer, client programs request services by invoking functions on remote servers, which respond by executing the requested operations and returning results to the client. The application layer also addresses higher-level concerns such as authentication, authorization, and error handling.

Encoding Layer

The encoding layer is responsible for converting function calls, parameters, and results into formats suitable for transmission over the network, as well as converting received data back into the format required for local invocation. This layer involves data serialization and deserialization to ensure that data can be properly parsed and processed during network transmission.

RPC Process

  • Type–length–value (TLV)
struct Person{
  1: required string       userName,
  2: optional int64        interestNumber,
  3: optional []string     interests,
}

RPC Process

Transport Protocol Layer

At this layer, an appropriate transport protocol is chosen to ensure reliable data transmission, including error detection and recovery mechanisms. Common transport protocols include HTTP (Hypertext Transfer Protocol) and specific RPC protocols like gRPC.

RPC Process

  1. Special Fields
  • Terminator: eg, Message + \r\n + Message + \r\n

  • Variable Length: eg, Length + Message Body + Length + Message Body

  1. Process

Peek -> Magic Number (To know which protocol is used) -> Peek -> PayloadCodeC (To know encode method) -> Peek -> Payload

Transport Layer

This is the bottommost layer responsible for handling the details of data transmission over the network, such as packet segmentation, sending, and receiving. It provides the underlying network connection and communication mechanisms. Common protocols at this layer include TCP (Transmission Control Protocol) and UDP (User Datagram Protocol).

RPC Process

RPC Process

Performance

  1. Stability
  • Timeout: Avoid wastes on unavailable nodes.
  • Rate Limiter: Protect the callee and prevent the server from being overwhelmed by heavy traffic.
  • Circuit Breaker: Protect the callee and prevent the problem of the server from affecting the entire link.
  • Request Success Rate: Load balancing and Retry.
  • Long Tail Request: Backup Request.

RPC Process

Note: Stability indicators are usually implemented through middleware, eg, WithTimeout(), withRetry().

  1. Usability

  2. Scalability

RPC Process

  1. Observability
  • Log
  • Metric
  • Tracing
  1. Others
  • High Throughput: Connection Pool
  • Low Latency: Multiplexing

Kitex

Structure

RPC Process

Scalability

  1. Interaction: Png-Pong / Streaming / Oneway
  2. Codec: Thrift / Protobuf
  3. Application Layer Protocol: TTHeader / HTTP2
  4. Transport Layer: TCP

Optimization

Network Library
  1. Scheduling: epoll_wait, Reuse goroutines.
  2. LinkBuffer: Nocopy Buffer.
  3. Pool: Object Pool, Memory Pool.
Encoding
  1. Codegen: Pre-allocated memory, Inline operation, Thrift IDL encoding.
  2. JIT (Just-In-Time compilation): Frugal.

HTTP

Content

Request

  1. Request Line
  • Methods: GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH
  • URL
  • Protocol Version
  1. Header Fields
  2. Message Body

Response

  1. State Line
  • Protocol Version
  • State Code

RPC Process

  • State Description
  1. Header Fields
  2. Response Body
h := server.Default()
h.GET("/ping", func(c context.Context, ctx *app.RequestContext) {
	ctx.Data(200, "text/plain; charset=utf-8", []byte("OK"))
})
h.Spin()

Process

RPC Process

Layers (From top to bottom)

RPC Process

Application Layer

Application Layer provides APIs, eg ctx.Request.Header.Peek(key) -> API ctx.GetHeader(key).

Middleware Layer

  1. With pre-handle logic and post-handle logic.
func Middleware(params){
  // pre-handle logic

  Next() // nextMiddleware() or bizLogic()

  // after-handle logic
}
  1. Next()
  • Without Next(): Initialization logic AND does not need to be on the same call stack.
  • With Next(): Post-handle logic OR need to be in the same call stack
  1. Routing can register multiple middleware.

  2. Guaranteed to increment index at all times.

func (ctx *RequestContext) Next(){
  ctx.index++
  for ctx.index < int8(len(ctx.handler)){
    ctx.handlers[ctx.index]()
    ctx.index++
  }
}
  1. Exception handler
func (ctx *RequestContext) Abort(){
  ctx.index = IndexMax
}

Routing Layer

  1. Trie

RPC Process

  1. Method matching: Map + Method(string) + Tries + Header Node(*node)

  2. Multi-handler: add a list for each handler

node struct {
  prefix   string
  parent   *node
  children children
  handlers app.HandlersChain
  ...
}

Protocol Layer

  1. Do not store Contexts inside a struct type, instead, pass a Context explicitly to each function that needs it. The Context should be the first parameter.

  2. Read and write data on the connection.

type Server interface{
  Serve(c context.Context, conn network.Conn) error
}

Transport Layer

  1. Blocking I/O (BIO)
// BIO
go func() {
  for {
    conn, _ := listener.Accept()

    go func(){
      conn.Read(request)
      handler
      conn.Write(response)
    }()
  }
}()

// go net
type Conn interface {
  Read(b []byte) (n int, err error)  // if fail to read, blocked here
  Write(b []byte) (n int, err error) // if fail to write, blocked here
  ...
}
  1. New I/O (NIO)
// NIO
go func() {
  for {
    readableConns, _ := Monitor(conns) // read enough data
    for conn := range readableConns {
      go func(){
        conn.Read(request)
        handler
        conn.Write(response)
      }()
    }
  }
}()

// netpoll
type Reader interface {
  Peek(n int) ([]byte, error)
  ...
}

type Writer interface {
  Malloc(n int) (buf []byte, err error)
  Flush() error
}

Optimization

For Network Library

  1. go net with bufio.
type Reader interface {
  Peek(n int) ([]byte, error)  // stop pointer
  Discard(n int) (discarded int, err error)  // move-forward pointer
  Release() error  // reclaim memory
  Size() int
  Read(b []byte) (l int, err error)
  ...
}

type Writer interface {
  Write(p []byte)
  Size() int
  Flush() error
  ...
}
  1. netpoll with nocopy peek: Allocate a sufficiently large buffer and limit the buffer size

RPC Process

For Protocol Headers

  1. To find the Terminator \r\n quickly, use SIMD (Single Instruction/Multiple Data).

  2. To Parsing Headers body quickly, firstly filter out keys that do not meet the requirements by initials, then parse the corresponding value to an independent field, finally use byte slices to manage corresponding header storage for easy reuse.

switch s.Key[0] | 0x20 {
  case 'h':  // Filter out keys that do not meet the requirements by initials
  if utils.CaseInsensitiveCompare(s.Key, bytestr.StrHost) {
    h.setHostBytes(s.Value) // Parse the corresponding value to an independent field
    continue
  }
}
  1. Header key normalization, eg aaa-bbb -> Aaa-Bbb.

Hotspot Resource Pool

RPC Process

Hertz

Microservices

Example