gain 基于io_uring 的golang 网络框架

io_uring 是linux kernel 从5.1开始支持的新的io 操作模式,性能很不错,gain 是一个golang 实现

参考使用

  • main.go
package main
 
import (
    "fmt"
    "log"
    "net"
    "os"
    "sync/atomic"
    "time"
 
    "github.com/pawelgaczynski/gain"
    "github.com/pawelgaczynski/gain/logger"
    "github.com/rs/zerolog"
)
 
const (
    port            = 8080
    numberOfClients = 2
)
 
var testData = []byte("echo")
 
type EventHandler struct {
    server gain.Server
 
    logger zerolog.Logger
 
    overallBytesSent atomic.Uint64
}
 
func (e *EventHandler) OnStart(server gain.Server) {
    e.server = server
    e.logger = zerolog.New(os.Stdout).With().Logger().Level(zerolog.InfoLevel)
}
 
func (e *EventHandler) OnAccept(conn gain.Conn) {
    e.logger.Info().
        Int("active connections", e.server.ActiveConnections()).
        Str("remote address", conn.RemoteAddr().String()).
        Msg("New connection accepted")
}
 
func (e *EventHandler) OnRead(conn gain.Conn, n int) {
    e.logger.Info().
        Int("bytes", n).
        Str("remote address", conn.RemoteAddr().String()).
        Msg("Bytes received from remote peer")
 
    var (
        err    error
        buffer []byte
    )
 
    buffer, err = conn.Next(n)
    if err != nil {
        return
    }
 
    _, _ = conn.Write(buffer)
}
 
func (e *EventHandler) OnWrite(conn gain.Conn, n int) {
    e.overallBytesSent.Add(uint64(n))
 
    e.logger.Info().
        Int("bytes", n).
        Str("remote address", conn.RemoteAddr().String()).
        Msg("Bytes sent to remote peer")
 
    err := conn.Close()
    if err != nil {
        e.logger.Error().Err(err).Msg("Error during connection close")
    }
}
 
func (e *EventHandler) OnClose(conn gain.Conn, err error) {
    log := e.logger.Info().
        Str("remote address", conn.RemoteAddr().String())
    if err != nil {
        log.Err(err).Msg("Connection from remote peer closed")
    } else {
        log.Msg("Connection from remote peer closed by server")
    }
 
    if e.overallBytesSent.Load() >= uint64(len(testData)*numberOfClients) {
        e.server.AsyncShutdown()
    }
}
 
func runClients() {
    for i := 0; i < numberOfClients; i++ {
        go func() {
            time.Sleep(time.Second)
 
            conn, err := net.DialTimeout("tcp", fmt.Sprintf("127.0.0.1:%d", port), time.Second)
            if err != nil {
                log.Panic(err)
            }
 
            n, err := conn.Write(testData)
            if err != nil {
                log.Panic()
            }
 
            if n != len(testData) {
                log.Panic()
            }
 
            buffer := make([]byte, len(testData))
 
            n, err = conn.Read(buffer)
            if err != nil {
                log.Panic()
            }
 
            if n != len(testData) {
                log.Panic()
            }
        }()
    }
}
 
func main() {
    // runClients()
 
    err := gain.ListenAndServe(
        fmt.Sprintf("tcp://0.0.0.0:%d", port), &EventHandler{}, gain.WithLoggerLevel(logger.WarnLevel))
    if err != nil {
        log.Panic(err)
    }
}

以上代码会创建server,监听在8080 端口,对于测试,可以通过telnet 发送echo 数据,如果有异常的服务会关闭

说明

基于io_uring 的网络框架已经有不少了,但是目前国内一般linux kernel 版本都不太高,所以基本上使用是有些问题的

参考资料

https://github.com/pawelgaczynski/gain
https://en.wikipedia.org/wiki/Io_uring
https://developers.redhat.com/articles/2023/04/12/why-you-should-use-iouring-network-io
https://medium.com/better-programming/an-introduction-to-gain-part-1-writing-high-performance-tcp-application-df5f7253e54a
https://betterprogramming.pub/gain-the-new-fastest-go-tcp-framework-40ec111d40e6
https://blog.vmsplice.net/2020/07/rethinking-event-loop-integration-for.html

posted on   荣锋亮  阅读(172)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2022-07-10 基于jprofiler 的一个简单dremio 查询处理学习
2019-07-10 presto docker简单试用
2018-07-10 Packer 基本试用
2017-07-10 Service Mesh 了解
2017-07-10 docker swarm mode routing mesh 使用
2017-07-10 Portainer docker 可视化管理工具

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示