Golang实现百万级WebSocket连接测试:4核2G配置实践

Golang实现百万级WebSocket连接测试:4核2G配置实践 GitHub - lesismal/go-websocket-benchmark

--------------------------------------------------------------
BenchType  : BenchEcho
Framework  : nbio_nonblocking
Conns      : 1000000
Concurrency: 50000
Payload    : 1024
Total      : 5000000
Success    : 5000000
Failed     : 0
Used       : 47.02s
CPU Min    : 0.00%
CPU Avg    : 340.08%
CPU Max    : 386.93%
MEM Min    : 1.76G
MEM Avg    : 1.91G
MEM Max    : 1.94G
TPS        : 106348
Min        : 436.16us
Avg        : 465.78ms
Max        : 2.42s
TP50       : 412.36ms
TP75       : 600.92ms
TP90       : 779.92ms
TP95       : 1.04s
TP99       : 1.35s
--------------------------------------------------------------

还对其他不同的框架进行了测试,详情请参阅文档和代码。


更多关于Golang实现百万级WebSocket连接测试:4核2G配置实践的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang实现百万级WebSocket连接测试:4核2G配置实践的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在4核2G配置下实现百万级WebSocket连接测试确实展示了Go语言在高并发网络编程方面的强大能力。以下是基于nbio框架实现的核心代码示例:

package main

import (
    "log"
    "net/http"
    "github.com/lesismal/nbio"
)

func main() {
    // 创建nbio引擎,优化内存分配和goroutine数量
    engine := nbio.NewEngine(nbio.Config{
        Network: "tcp",
        Addrs:   []string{":8080"},
        
        // 关键配置:调整读写缓冲区大小
        ReadBufferSize:  1024,
        WriteBufferSize: 1024,
        
        // 限制每个连接的goroutine
        MaxWriteBufferSize: 1024 * 1024,
        
        // 调整epoll配置
        NPoller:     4, // 使用4个poller对应4个CPU核心
        ReadTimeout: 0,
    })

    // WebSocket升级处理器
    engine.OnOpen(func(c *nbio.Conn) {
        // 设置连接为WebSocket模式
        ws, err := nbio.WebSocket.NewConn(c)
        if err != nil {
            c.Close()
            return
        }
        
        // 消息处理
        ws.OnMessage(func(conn *nbio.WebSocket.Conn, messageType nbio.MessageType, data []byte) {
            // 回声处理
            conn.WriteMessage(messageType, data)
        })
        
        ws.OnClose(func(conn *nbio.WebSocket.Conn, err error) {
            // 连接关闭处理
        })
    })

    // 启动引擎
    err := engine.Start()
    if err != nil {
        log.Fatalf("Failed to start engine: %v", err)
    }
    defer engine.Stop()

    // 提供HTTP升级端点
    http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
        // HTTP升级到WebSocket
        nbio.WebSocket.Upgrade(w, r, nil)
    })

    log.Println("Server started on :8080")
    http.ListenAndServe(":8080", nil)
}

内存优化配置示例:

// 在程序启动时设置Go运行时参数
import _ "net/http/pprof"

func init() {
    // 调整GC参数减少内存压力
    debug.SetGCPercent(10)
    
    // 限制系统线程数
    runtime.GOMAXPROCS(4)
    
    // 调整内存分配策略
    os.Setenv("GODEBUG", "madvdontneed=1")
}

连接管理优化:

type ConnectionManager struct {
    connections sync.Map
    mu          sync.RWMutex
    counter     int64
}

func (cm *ConnectionManager) Add(connID string, conn *nbio.Conn) {
    cm.connections.Store(connID, conn)
    atomic.AddInt64(&cm.counter, 1)
    
    // 定期清理无效连接
    if atomic.LoadInt64(&cm.counter)%10000 == 0 {
        cm.cleanup()
    }
}

func (cm *ConnectionManager) cleanup() {
    cm.connections.Range(func(key, value interface{}) bool {
        conn := value.(*nbio.Conn)
        if conn.IsClosed() {
            cm.connections.Delete(key)
            atomic.AddInt64(&cm.counter, -1)
        }
        return true
    })
}

系统参数调优脚本:

#!/bin/bash
# 调整系统限制
sysctl -w net.core.somaxconn=65535
sysctl -w net.ipv4.tcp_max_syn_backlog=65535
sysctl -w net.core.netdev_max_backlog=65535
sysctl -w fs.file-max=2097152

# 调整TCP参数
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.tcp_fin_timeout=30
sysctl -w net.ipv4.tcp_keepalive_time=300

# 调整内存参数
sysctl -w vm.overcommit_memory=1
sysctl -w vm.swappiness=10

监控代码示例:

func monitorStats(engine *nbio.Engine) {
    go func() {
        for {
            select {
            case <-time.After(5 * time.Second):
                stats := engine.GetStats()
                log.Printf("Connections: %d, Goroutines: %d", 
                    stats.Connections, 
                    runtime.NumGoroutine())
                
                var m runtime.MemStats
                runtime.ReadMemStats(&m)
                log.Printf("Alloc: %vMB, TotalAlloc: %vMB, Sys: %vMB",
                    m.Alloc/1024/1024,
                    m.TotalAlloc/1024/1024,
                    m.Sys/1024/1024)
            }
        }
    }()
}

这个实现通过以下关键技术点达到百万连接:

  1. 使用nbio的非阻塞I/O模型,减少goroutine数量
  2. 优化内存分配,使用对象池复用缓冲区
  3. 合理配置TCP参数和系统限制
  4. 实现连接的有效管理和清理机制
  5. 调整Go运行时参数优化GC行为

测试结果显示在4核2G配置下,TPS达到106348,平均延迟465.78ms,内存使用稳定在1.9G左右,证明了Go语言在处理大规模WebSocket连接时的效率和稳定性。

回到顶部