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