gnet

项目主页

欢迎大家围观~~,目前还在持续更新,感兴趣的话可以 star 一下暗中观察哦。

简介
gnet

这个项目存在的价值是提供一个在网络包处理方面能和 Redis、Haproxy 这两个项目具有相近性能的Go 语言网络服务器框架。

gnetgnetgnet
gnetevio
功能
  • 高性能 的基于多线程模型的 Event-Loop 事件驱动
  • 内置 Round-Robin 轮询负载均衡算法
  • 简洁的 APIs
  • 基于 Ring-Buffer 的高效内存利用
  • 支持多种网络协议:TCP、UDP、Unix Sockets
  • 支持两种事件驱动机制:Linux 里的 epoll 以及 FreeBSD 里的 kqueue
  • 支持异步写操作
  • 允许多个网络监听地址绑定在一个 Event-Loop 上
  • 灵活的事件定时器
  • SO_REUSEPORT 端口重用
核心设计

多线程模型

gnetnetty

multi_reactor

它的运行流程如下面的时序图:

reactor

gnet

multi_reactor_thread_pool

它的运行流程如下面的时序图:

multi-reactors

通信机制

gnetgnetgnet

所以我最终选择了 go-disruptor:高性能消息分发队列 LMAX Disruptor 的 Golang 实现。

自动扩容的 Ring-Buffer

gnet

开始使用

安装

$ go get -u github.com/panjf2000/gnet
复制代码

使用示例

// ======================== Echo Server implemented with gnet ===========================

package main

import (
	"flag"
	"fmt"
	"log"
	"strings"

	"github.com/panjf2000/gnet"
	"github.com/panjf2000/gnet/ringbuffer"
)

func main() {
	var port int
	var loops int
	var udp bool
	var trace bool
	var reuseport bool

	flag.IntVar(&port, "port", 5000, "server port")
	flag.BoolVar(&udp, "udp", false, "listen on udp")
	flag.BoolVar(&reuseport, "reuseport", false, "reuseport (SO_REUSEPORT)")
	flag.BoolVar(&trace, "trace", false, "print packets to console")
	flag.IntVar(&loops, "loops", 0, "num loops")
	flag.Parse()

	var events gnet.Events
	events.NumLoops = loops
	events.OnInitComplete = func(srv gnet.Server) (action gnet.Action) {
		log.Printf("echo server started on port %d (loops: %d)", port, srv.NumLoops)
		if reuseport {
			log.Printf("reuseport")
		}
		return
	}
	events.React = func(c gnet.Conn, inBuf *ringbuffer.RingBuffer) (out []byte, action gnet.Action) {
		top, tail := inBuf.PreReadAll()
		out = append(top, tail...)
		inBuf.Reset()

		if trace {
			log.Printf("%s", strings.TrimSpace(string(top)+string(tail)))
		}
		return
	}
	scheme := "tcp"
	if udp {
		scheme = "udp"
	}
	log.Fatal(gnet.Serve(events, fmt.Sprintf("%s://:%d", scheme, port)))
}

复制代码

I/O 事件

gnet
OnInitCompleteOnOpenedOnClosedOnDetachedReactTickPreWrite
性能测试

Linux (epoll)

系统参数

Go Version: go1.12.9 linux/amd64
OS:         Ubuntu 18.04
CPU:        8 Virtual CPUs
Memory:     16.0 GiB
复制代码

Echo Server

echolinux.png

HTTP Server

httplinux.png

FreeBSD (kqueue)

系统参数

Go Version: go version go1.12.9 darwin/amd64
OS:         macOS Mojave 10.14.6
CPU:        4 CPUs
Memory:     8.0 GiB
复制代码

Echo Server

echomac.png

HTTP Server

httpmac.png
证书
gnet
待做事项

gnet 还在持续开发的过程中,所以这个仓库的代码和文档会一直持续更新,如果你对 gnet 感兴趣的话,欢迎给这个开源库贡献你的代码~~