rio

package module
v1.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 7, 2025 License: LGPL-3.0 Imports: 17 Imported by: 0

README

RIO

基于IOURINGAIO网络库,非CGO方式,且遵循标准库使用设计模式。

支持协议:TCPUDPUNIXUNIXGRAMIP为代理标准库)。

Linux 内核版本需要>= 5.14,推荐版本为>= 6.1

性能

TCPKALI

服务端环境:Win11(Hyper-V)、Ubuntu24.10(6.11.0-8-generic)、CPU(4核)。

客户端环境:Win11(WSL2)、内核(6.6.36.6-microsoft-standard-WSL2)、CPU(4核)。

Benchmark

tcpkali --workers 1 -c 50 -T 10s -m "PING" 192.168.100.120:9000

注意:请不要本地压测本地。

http benchmark
类型 packet rate estimate
RIO 27791.8
GNET 22095.3
EVIO 14272.9
NET(STD) 15161.3
详细结果
------ RIO ------
Destination: [192.168.100.120]:9000
Interface eth0 address [192.168.100.1]:0
Using interface eth0 to connect to [192.168.100.120]:9000
Ramped up to 50 connections.
Total data sent:     287.6 MiB (301548988 bytes)
Total data received: 286.4 MiB (300361173 bytes)
Bandwidth per channel: 9.627⇅ Mbps (1203.3 kBps)
Aggregate bandwidth: 240.188↓, 241.138↑ Mbps
Packet rate estimate: 27791.8↓, 20820.1↑ (3↓, 32↑ TCP MSS/op)
Test duration: 10.0042 s.
------ GNET ------
Destination: [192.168.100.120]:9000
Interface eth0 address [192.168.100.1]:0
Using interface eth0 to connect to [192.168.100.120]:9000
Ramped up to 50 connections.
Total data sent:     219.4 MiB (230096896 bytes)
Total data received: 217.7 MiB (228243396 bytes)
Bandwidth per channel: 7.329⇅ Mbps (916.1 kBps)
Aggregate bandwidth: 182.481↓, 183.963↑ Mbps
Packet rate estimate: 22095.3↓, 15777.4↑ (3↓, 44↑ TCP MSS/op)
Test duration: 10.0062 s.
------ EVIO ------
Destination: [192.168.100.120]:9000
Interface eth0 address [192.168.100.1]:0
Using interface eth0 to connect to [192.168.100.120]:9000
Ramped up to 50 connections.
Total data sent:     200.4 MiB (210108416 bytes)
Total data received: 198.6 MiB (208234360 bytes)
Bandwidth per channel: 6.688⇅ Mbps (836.0 kBps)
Aggregate bandwidth: 166.458↓, 167.956↑ Mbps
Packet rate estimate: 14272.9↓, 14412.0↑ (2↓, 44↑ TCP MSS/op)
Test duration: 10.0078 s.
------ NET ------
Destination: [192.168.100.120]:9000
Interface eth0 address [192.168.100.1]:0
Using interface eth0 to connect to [192.168.100.120]:9000
Ramped up to 50 connections.
Total data sent:     199.2 MiB (208928768 bytes)
Total data received: 197.8 MiB (207359332 bytes)
Bandwidth per channel: 6.654⇅ Mbps (831.7 kBps)
Aggregate bandwidth: 165.720↓, 166.974↑ Mbps
Packet rate estimate: 15161.3↓, 14565.3↑ (2↓, 45↑ TCP MSS/op)
Test duration: 10.0101 s.

使用

go get -u github.com/brickingsoft/rio

基本使用rio替换net


// 将 net.Listen() 替换成 rio.Listen() 
ln, lnErr := rio.Listen("tcp", ":9000")
// 将 net.Dial() 替换成 rio.Dial() 
conn, dialErr := rio.Dial("tcp", "127.0.0.1:9000")

TLS场景:

// server("github.com/brickingsoft/rio/tls")
ln, _ = tls.Listen("tcp", "127.0.0.1:9000", tls.ConfigFrom(config))
// server(use wrap)
ln, _ := rio.Listen("tcp", ":9000")
ln, _ := tls.NewListener(ln, config)

// client("github.com/brickingsoft/rio/tls")
conn, _ = tls.Dial("tcp", "127.0.0.1:9000", tls.ConfigFrom(config))

// client(use wrap)
rawConn, dialErr := rio.Dial("tcp", "127.0.0.1:9000")
conn := tls.Client(rawConn, config)
if err := conn.HandshakeContext(ctx); err != nil {
	rawConn.Close()
	return nil, err
}

转换场景:

// tcp sendfile
reader, ok := conn.(io.ReaderFrom)
// 转换成 TCP 链接 
tcpConn, ok := conn.(*rio.TCPConn)
// 转换成 UDP 链接
udpConn, ok := conn.(*rio.UDPConn)
// 转换成 UNIX 链接
unixConn, ok := conn.(*rio.UnixConn)

纯客户端场景:

建议PINIOURING,直到程序退出再UNPIN

因为IOURING的生命周期为当被使用时开启,当被没有被使用时关闭。

因为Listen的生命周期往往和程序是一致的,所以IOURING为常驻状况。

Dial的生命周期是短的,往往是频繁Dial,所以需要PIN来常驻IOURING,而不是频繁启停。

// 程序启动位置
rio.Pin()
// 程序退出位置
rio.Unpin()

HTTP场景:

Server 使用Listener代替法。

Client 使用RoundTripper代替法。

// http server
http.Serve(ln, handler)
// fasthttp server
fasthttp.Serve(ln, handler)

REUSE PORT(监听TCP时自动启用):


lc := rio.ListenConfig{}
lc.SetReusePort(true)

ln, lnErr := lc.Listen(...)

进阶调参

通过设置环境变量进行调控,具体详见 IOURING

名称 说明
IOURING_ENTRIES 数字 环大小,默认为最大值 16384。
IOURING_SETUP_FLAGS 文本 标识,如IORING_SETUP_SQPOLL, IORING_SETUP_SUBMIT_ALL等。
IOURING_SETUP_FLAGS_SCHEMA 文本 标识方案,DEFAULTPERFORMANCE
IOURING_SQ_THREAD_CPU 数字 设置环锁亲和的CPUID。
IOURING_SQ_THREAD_IDLE 数字 在含有IORING_SETUP_SQPOLL标识时,设置空闲时长,单位为毫秒,默认是 1 毫秒。
IOURING_PREPARE_BATCH_SIZE 数字 准备 SQE 的缓冲大小,默认为 SQ 的大小。
IOURING_USE_CPU_AFFILIATE 布尔 是否使用 CPU AFFILIATE。
IOURING_CURVE_TRANSMISSION 文本 设置等待 CQ 策略曲线,如 1:1us, 8:2us

注意事项:

  • IOURING_SETUP_FLAGS 与系统内核版本有关联,请务必确认版本。
  • IORING_SETUP_SQPOLL 取决于运行环境,请自行测试效果。
  • IOURING_SETUP_FLAGS_SCHEMA 优先级低于 IOURING_SETUP_FLAGS
  • PERFORMANCEIORING_SETUP_SQPOLL IORING_SETUP_SUBMIT_ALL IORING_SETUP_SINGLE_ISSUER 的组合。
  • DEFAULTIORING_SETUP_SUBMIT_ALL

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	DefaultDialer = Dialer{}
)

Functions

func Dial

func Dial(network string, address string) (net.Conn, error)

func DialContext

func DialContext(ctx context.Context, network string, address string) (net.Conn, error)

func DialTimeout

func DialTimeout(network string, address string, timeout time.Duration) (net.Conn, error)

func Listen

func Listen(network string, addr string) (net.Listener, error)

func ListenPacket

func ListenPacket(network string, addr string) (net.PacketConn, error)

func Pin added in v0.9.0

func Pin() error

func PrepareIOURingSetupOptions added in v1.2.2

func PrepareIOURingSetupOptions(_ ...aio.Option)

func Unpin added in v0.9.0

func Unpin() error

func UseProcessPriority

func UseProcessPriority(level process.PriorityLevel)

Types

type Dialer

type Dialer struct {
	net.Dialer
}

func (*Dialer) SetFastOpen

func (d *Dialer) SetFastOpen(_ int)

type IPConn

type IPConn struct {
	*net.IPConn
}

func DialIP

func DialIP(network string, laddr, raddr *net.IPAddr) (*IPConn, error)

func ListenIP

func ListenIP(network string, addr *net.IPAddr) (*IPConn, error)

type TCPConn

type TCPConn struct {
	*net.TCPConn
}

func DialTCP

func DialTCP(network string, laddr, raddr *net.TCPAddr) (*TCPConn, error)

type TCPListener

type TCPListener struct {
	*net.TCPListener
}

func ListenTCP

func ListenTCP(network string, addr *net.TCPAddr) (*TCPListener, error)

type UDPConn

type UDPConn struct {
	*net.UDPConn
}

func DialUDP

func DialUDP(network string, laddr, raddr *net.UDPAddr) (*UDPConn, error)

func ListenMulticastUDP

func ListenMulticastUDP(network string, ifi *net.Interface, addr *net.UDPAddr) (*UDPConn, error)

func ListenUDP

func ListenUDP(network string, addr *net.UDPAddr) (*UDPConn, error)

type UnixConn

type UnixConn struct {
	*net.UnixConn
}

func DialUnix

func DialUnix(network string, laddr, raddr *net.UnixAddr) (*UnixConn, error)

func ListenUnixgram

func ListenUnixgram(network string, addr *net.UnixAddr) (*UnixConn, error)

type UnixListener

type UnixListener struct {
	*net.UnixListener
}

func ListenUnix

func ListenUnix(network string, addr *net.UnixAddr) (*UnixListener, error)

Directories

Path Synopsis
pkg
sys

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL