一个对网络库进行压测统计qps的小程序
参考:https://gist.github.com/Tsiannian/137b722f1b5dcebea0830a9e12720de0
package main
import (
"bufio"
"encoding/binary"
"fmt"
"net"
"os"
"time"
)
func timeStamp() uint64 {
return uint64(time.Now().UnixNano())
}
func encode(index uint64, stamp uint64) []byte {
sendData := make([]byte, 128)
binary.LittleEndian.PutUint64(sendData[0:64], index)//发送序列号
binary.LittleEndian.PutUint64(sendData[64:128], stamp)//发送时间
return sendData
}
func decode(buff []byte) (uint64, uint64) {
index := binary.LittleEndian.Uint64(buff[0:64])//解析发送序列号
stamp := binary.LittleEndian.Uint64(buff[64:128])//发送时间
return index, stamp
}
func handleWork(recv chan []byte, send chan []byte) {
fmt.Println("begin to handle")
defer fmt.Println("end to handle")
countChan := make(chan uint64, 10240)
go func() {
var index uint64
for {
index++
now := timeStamp()
data := encode(index, now)//生成data
send <- data//放到发送通道
countChan <- index//index放到count通道
}
}()
for {
inIndex := <-countChan//发送index
tcppacket := <-recv//收包的通道
now := timeStamp()
outindex, stamp := decode(tcppacket)//解析返回的数据index,时间
check(inIndex, outindex, now-stamp)//检查发送index到返回index,时间差
}
}
var couter, latency, begin int64
var max_latency uint64
func check(inIndex, outindex, delay uint64) {//检查发送index到返回index,时间差
if inIndex != outindex {//不相等,中间有出错,未返回
fmt.Println("index error", inIndex, outindex)
os.Exit(-1)
}
timeNow := time.Now().Unix()
couter++
latency += int64(delay)//总时间差
if delay > max_latency {
max_latency = delay
}
if begin < timeNow-1 {//1秒
fmt.Println("ops", couter, "all latency", latency, "max", max_latency, "avg lantency", latency/couter)
begin = timeNow
couter = 0
latency = 0
max_latency = 0
}
}
func sendWorker(data chan []byte, nc net.Conn) {
fmt.Println("begin to send")
defer fmt.Println("end to send")
for {
temp := <-data
remain := len(data)
for i := 0; i < remain; i++ {
left := <-data
temp = append(temp, left...)
}
size, err := nc.Write(temp)
if size != len(temp) || err != nil {
fmt.Println("send work error", size, err)
return
}
}
}
func recvWorker(data chan []byte, nc net.Conn) {
fmt.Println("begin to recv")
defer fmt.Println("end to recv")
reader := bufio.NewReaderSize(nc, 8192)
buff := make([]byte, 4096)
send := []byte{}
for {
size, err := reader.Read(buff)
if err != nil {
fmt.Println("recv work err", size, err)
return
}
send = append(send, buff[0:size]...)
for len(send) >= 128 {
data <- send[0:128]
send = send[128:]
}
}
}
func main() {
conn, err := net.Dial("tcp", "127.0.0.1:3050")
if err != nil {
fmt.Println(err)
return
}
sendChan := make(chan []byte, 10240)
recvChan := make(chan []byte, 10240)
go recvWorker(recvChan, conn)
go sendWorker(sendChan, conn)
go handleWork(recvChan, sendChan)
q := make(chan int)
<-q
fmt.Print("client exist")
}