package main
import (
"fmt"
"os"
"os/signal"
"sync"
"sync/atomic"
"syscall"
"time"
"github.com/aceld/zinx/ziface"
"github.com/aceld/zinx/znet"
)
var requestCounter atomic.Uint64
type EchoRouter struct {
znet.BaseRouter
}
func (r *EchoRouter) Handle(request ziface.IRequest) {
requestCounter.Add(1)
request.GetConnection().SendMsg(request.GetMsgID(), request.GetData())
}
func runServer() {
s := znet.NewServer()
s.AddRouter(1, &EchoRouter{})
go func() {
var lastCount uint64 = 0
var lastTime = time.Now()
for {
time.Sleep(1 * time.Second)
currentCount := requestCounter.Load()
currentTime := time.Now()
elapsed := currentTime.Sub(lastTime).Seconds()
rps := float64(currentCount-lastCount) / elapsed
fmt.Printf("[Stats] 当前RPS: %.2f req/s, 总请求数: %d\n", rps, currentCount)
lastCount = currentCount
lastTime = currentTime
}
}()
fmt.Println("[Server] 基准测试服务器启动在 127.0.0.1:8999")
fmt.Println("[Server] 按 Ctrl+C 停止服务器...")
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
fmt.Println("[Server] 接收到停止信号,正在关闭...")
s.Stop()
}()
s.Serve()
}
func runClient(connections, requestsPerConn int) {
fmt.Printf("[Client] 开始基准测试: %d 并发连接, 每连接 %d 请求\n", connections, requestsPerConn)
totalRequests := connections * requestsPerConn
completedRequests := atomic.Int64{}
totalLatency := atomic.Int64{}
var wg sync.WaitGroup
var barrier sync.WaitGroup
barrier.Add(1)
wg.Add(connections)
startTime := time.Now()
for i := 0; i < connections; i++ {
go func(id int) {
defer wg.Done()
client := znet.NewClient("127.0.0.1", 8999)
if client == nil {
fmt.Printf("[Client %d] 连接失败\n", id)
return
}
client.Start()
defer func() {
if client != nil {
client.Stop()
}
}()
time.Sleep(100 * time.Millisecond)
barrier.Wait()
for j := 0; j < requestsPerConn; j++ {
payload := make([]byte, 64)
for k := range payload {
payload[k] = 'A'
}
requestStart := time.Now()
time.Sleep(100 * time.Millisecond)
conn := client.Conn()
if conn == nil {
fmt.Printf("[Client %d] 获取连接失败\n", id)
continue
}
err := conn.SendMsg(1, payload)
if err != nil {
fmt.Printf("[Client %d] 请求失败: %s\n", id, err)
continue
}
latency := time.Since(requestStart).Microseconds()
totalLatency.Add(latency)
completedRequests.Add(1)
}
}(i)
}
go func() {
for {
time.Sleep(1 * time.Second)
completed := completedRequests.Load()
progress := float64(completed) / float64(totalRequests) * 100.0
fmt.Printf("[Progress] %.2f%% (%d/%d)\n", progress, completed, totalRequests)
if completed >= int64(totalRequests) {
break
}
}
}()
fmt.Println("[Client] 所有连接已就绪,开始测试...")
barrier.Done()
wg.Wait()
elapsed := time.Since(startTime)
completed := completedRequests.Load()
avgLatency := float64(0)
if completed > 0 {
avgLatency = float64(totalLatency.Load()) / float64(completed)
}
fmt.Println("\n===== 基准测试结果 =====")
fmt.Printf("总连接数: %d\n", connections)
fmt.Printf("每连接请求数: %d\n", requestsPerConn)
fmt.Printf("总请求数: %d\n", totalRequests)
fmt.Printf("完成请求数: %d\n", completed)
fmt.Printf("总耗时: %.2f 秒\n", elapsed.Seconds())
fmt.Printf("平均延迟: %.2f 微秒\n", avgLatency)
fmt.Printf("吞吐量: %.2f 请求/秒\n", float64(completed)/elapsed.Seconds())
}