gevLightweight, fast Golang Network library
Gev is a lightweight, fast, non-blocking TCP network library based on the Reactor pattern. The underlying library does not use the Golang NET library, but ePoll and KQueue, so it does not support Windows.
Why geV
Golang’s Goroutine is very lightweight, but it still requires around 4K of memory per boot. After reading the bird’s Nest article “Thinking about millions of Go TCP Connections: EPoll method reduces resource usage”, I researched Evio.
Evio was very fast, but still had some problems, so I tried to optimize it, which led to the Eviop project. For more information about evio, see my other blog post on Evio’s problems/Bugs and Thoughts in Golang. In the process of optimizing eVIO to complete eviop, it became more and more troublesome to modify it because of its network model, and the cost ratio was higher than that of building a new one.
Finally decided to build a new one, more lightweight, do not need to remove all. In addition, I learned MUDUO in college, so I realized GEV by referring to the Reactor model used by MudUO.
In a Linux environment, the underlying GEV uses ePoll, which is where GEV will focus on optimization. When using kqueue on a MAC, you probably won’t pay much attention to this part of the optimization, since macs are rarely used as servers (not supported “yet” on Windows).
The characteristics of
- High performance event loop based on EPoll and KQueue
- Support multi-core multithreading
- Dynamically expand the Ring Buffer to implement read and write buffers
- Asynchronous read and write
- SO_REUSEPORT Port reuse is supported
A network model
Gev uses very few Goroutines. One goroutine listens for client connections, while the other Goroutines (Work coroutines) handle read and write events for connected clients. The number of Work coroutines can be configured and by default is the same as the number of cpus on the running host.
The performance test
The test environment Ubuntu18.04
Simple performance comparisons with similar libraries are performed in the same way as eVIO projects.
- gnet
- eviop
- evio
- Net (Standard Library)
Limit GOMAXPROCS= 1,1 work coroutine
Limit GOMAXPROCS= 1,4 work coroutines
Limit GOMAXPROCS=4 to 4 work coroutines
The installation
go get -u github.com/Allenxuxu/gev
Copy the code
The sample
package main
import (
"flag"
"strconv"
"log"
"github.com/Allenxuxu/gev"
"github.com/Allenxuxu/gev/connection"
"github.com/Allenxuxu/ringbuffer"
)
type example struct{}
func (s *example) OnConnect(c *connection.Connection) {
log.Println("OnConnect.", c.PeerAddr())
}
func (s *example) OnMessage(c *connection.Connection, buffer *ringbuffer.RingBuffer) (out []byte) {
//log.Println("OnMessage")
first, end := buffer.PeekAll()
out = first
if len(end) > 0 {
out = append(out, end...)
}
buffer.RetrieveAll()
return
}
func (s *example) OnClose(a) {
log.Println("OnClose")}func main(a) {
handler := new(example)
var port int
var loops int
flag.IntVar(&port, "port".1833."server port")
flag.IntVar(&loops, "loops".- 1."num loops")
flag.Parse()
s, err := gev.NewServer(handler,
gev.Network("tcp"),
gev.Address(":"+strconv.Itoa(port)),
gev.NumLoops(loops))
iferr ! =nil {
panic(err)
}
s.Start()
}
Copy the code
reference
This project was inspired by EVIO and implemented by Muduo.
- evio
- muduo
- eviop
Related articles
- Evio source code parsing
- Golang Network library Evio some issues/bugs and thoughts
- Gev: Go implements a non-blocking TCP network library based on the Reactor pattern