Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the gnet approach to open source a lightweight and high-performance Go network framework?

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly introduces "what is the gnet method of open source a lightweight and high-performance Go network framework". In daily operations, it is believed that many people have doubts about what is the gnet method of open source a lightweight and high-performance Go network framework. The editor consulted all kinds of materials and sorted out simple and useful operation methods. I hope it will be helpful to answer the question of "what is the gnet method of open source a lightweight and high-performance Go network framework?" Next, please follow the editor to study!

Gnet is a high performance and lightweight network framework based on event-driven. It uses epoll and kqueue system calls directly instead of the standard Golang network package: net to build web applications, and it works like two open source network libraries: netty and libuv.

The value of this project is to provide a Go language network server framework with similar performance to Redis and Haproxy in network packet processing.

The highlight of gnet is that it is a high-performance, lightweight, non-blocking transport layer (TCP/UDP/Unix-Socket) network framework for pure Go implementation. Developers can use gnet to implement their own application layer network protocols, thus building their own application layer network applications: for example, implementing the HTTP protocol on gnet can create a HTTP server or Web development framework. By implementing the Redis protocol, you can create your own Redis server, and so on.

Gnet is derived from another project: evio, but its performance is much better.

Function

High performance event-loop event-driven based on Multi-thread / Goe Model

Built-in Round-Robin polling load balancing algorithm

Built-in goroutine pool, supported by open source library ants

Built-in bytes memory pool, supported by open source library pool

Concise APIs

Efficient memory utilization based on Ring-Buffer

Supports multiple network protocols: TCP, UDP, Unix Sockets

Supports two event-driven mechanisms: epoll in Linux and kqueue in FreeBSD

Support for asynchronous write operations

Flexible event timer

SO_REUSEPORT port reuse

Core design multi-thread / Goto model master-slave multi-Reactors model

Gnet has redesigned and developed a new built-in multithreading / Reactors model: "master-slave multi-threading", which is also the default threading model for netty. Here is the schematic of this model:

Its running process is shown in the following sequence diagram:

Master-slave multi-Reactors + thread / Go program pool

You might ask a question: what if my business logic is blocked, then the logic in the EventHandler.React registration method will also block, resulting in blocking the event-loop thread?

As you know, there is a most important principle for writing your web server based on gnet: never let your business logic (usually written in EventHandler.React) block event-loop threads, otherwise it will greatly reduce server throughput, which is also one of the most important principles of netty.

My answer is that another multithreading / goe model based on gnet: "master-slave multi-Reactors with thread / Go pool" can solve the blocking problem. This new network model solves the problem of business logic blocking by introducing a worker pool: it initializes a worker pool at startup and then executes the blocking code in the EventHandler.React into the worker pool, thus avoiding blocking event-loop threads.

The architectural diagram of the model is as follows:

Its running process is shown in the following sequence diagram:

Gnet implements the "master-slave multi-Reactors + thread / Go pool" network model by using ants goroutine pool (a high-performance goroutine pool developed based on Go, which realizes scheduling management and goroutines reuse of large-scale goroutines). The full functionality and use of ants can be found in the ants documentation.

Gnet integrates ants and provides a pool.NewWorkerPool method to initialize an ants goroutine pool, and then you can submit the blocked business logic in EventHandler.React to the goroutine pool for execution. Finally, the code in the goroutine pool calls the gnet.Conn.AsyncWrite method to write the output data back to the client asynchronously after dealing with the blocking logic, so as to avoid blocking event-loop threads.

You can learn more about using ants goroutine pools in gnet here.

Ring-Buffer with automatic capacity expansion

Gnet uses Ring-Buffer to buffer network data and manage memory.

Get started with installing the $go get-u github.com/panjf2000/gnet usage example

The detailed documentation is here: the gnet interface documentation, but let's first take a look at a brief way to use gnet.

Using gnet to build a web server is very simple, just implement the gnet.EventHandler interface and register the event function you care about, and finally pass it to the gnet.Serve function along with the listening address. After the server starts working, each incoming network connection is passed between events. If you want to close a connection or shut down the entire server in an event, just set gnet.Action to Cosed or Shutdown.

The Echo server is the simplest network server, and it would be most appropriate to use it as an example of getting started with gnet. Here is the simplest echo server that listens on port 9000:

Echo server package mainimport ("log"github.com/panjf2000/gnet") type echoServer struct {* gnet.EventServer} func (es * echoServer) React (c gnet.Conn) (out [] byte, action gnet.Action) {out = c.Read () c.ResetBuffer () return} func main () {echo: = new (echoServer) log.Fatal (gnet.Serve (echo) "tcp://:9000", gnet.WithMulticore (true))}

As you can see, the gnet instance in the above example registers only one EventHandler.React event. Generally speaking, the main business logic code will be written in this event method, which will be called when the server receives the data written by the client, then processes the input data (here just echo the data back) and assigns the output data to the out variable and returns after processing, then you don't have to worry about it, gnet will help you write the data back to the client.

Echo server package mainimport ("log"time"github.com/panjf2000/gnet"github.com/panjf2000/gnet/pool") type echoServer struct {* gnet.EventServer pool * pool.WorkerPool} func (es * echoServer) React (c gnet.Conn) (out [] byte, action gnet.Action) {data: = append ([] byte {}, c.Read ()...) C.ResetBuffer () / / Use ants pool to unblock the event-loop. _ = es.pool.Submit (func () {time.Sleep (1 * time.Second) c.AsyncWrite (data)}) return} func main () {p: = pool.NewWorkerPool () defer p.Release () echo: = & echoServer {pool: P} log.Fatal (gnet.Serve (echo, "tcp://:9000") Gnet.WithMulticore (true))}

As I said in the section "Master-Slave Multi-Reactors + Thread / Go Pool", if your business logic contains blocking code, you should make the blocking code non-blocking, for example, by running this code through goroutine, but note that if your server handles enough traffic, this will result in creating a large number of goroutines that consumes system resources. So I generally recommend that you use goroutine pool to reuse and manage goroutines and save system resources.

More examples can be seen here: the gnet example.

Ipaw O event

Gnet currently supports the following iUnip O events:

EventHandler.OnInitComplete is called after server initialization is complete.

EventHandler.OnOpened is called when the connection is opened.

EventHandler.OnClosed is called when the connection is closed.

EventHandler.React is called when the server side receives the data sent from the client side. (your core business code is usually written in this method)

The EventHandler.Tick server is called once when it starts, and then called once at a given interval, which is a timer method.

The EventHandler.PreWrite pre-write data method is called before the server side writes the data back to the client side.

Timer

EventHandler.Tick will be triggered every once in a while, and you can control the interval by setting the returned delay variable.

The first time the timer is triggered is after the gnet.Serving event. If you want to set the timer, don't forget to set the option option: WithTicker (true).

Events.Tick = func () (delay time.Duration, action Action) {log.Printf ("tick") delay = time.Second return} UDP support

Gnet supports UDP protocol. You can bind the UDP address in gnet.Serve. Gnet's UDP support has the following features:

Immediately after entering the server, the data is written back to the client without caching.

EventHandler.OnOpened and EventHandler.OnClosed are not available under UDP, and the only available event is React.

Use multicore

The gnet.WithMulticore (true) parameter specifies whether gnet will use multicore for service, and if it is true, it will use multicore, otherwise it will run in a single core, and the number of cores used is generally the number of CPU of the machine.

Load balancing

Currently, gnet's built-in load balancing algorithm is polling and scheduling Round-Robin, which does not support self-customization.

SO_REUSEPORT port multiplexing

The server supports SO_REUSEPORT port reuse, allowing multiple sockets to listen on the same port, and then the kernel will help you with load balancing, awakening only one socket at a time to process accept requests to avoid shock effect.

It is also easy to turn on this feature, just use functional options to set it:

Gnet.Serve (events, "tcp://:9000", gnet.WithMulticore (true) Gnet.WithReusePort (true)) performance test performance comparison of the same type of network library Linux (epoll) system parameter # Machine information OS: Ubuntu 18.04/x86_64 CPU: 8 Virtual CPUs Memory: 16.0 GiB# Go version and configurationsGo Version: go1.12.9 linux/amd64GOMAXPROCS=8FreeBSD (kqueue) system parameter # Machine information OS: macOS Mojave 10.14.6/x86_64 CPU: 4 CPUs Memory: 8.0 GiB# Go version And configurationsGo Version: go version go1.12.9 darwin/amd64GOMAXPROCS=4 so far The study on "what is the gnet method of open source a lightweight and high-performance Go network framework" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report