添加 /demo/connstat 用于测试 net.Conn.SetWriteDeadline 的性能开销

pull/2/head
q191201771 6 years ago
parent 856141eae4
commit 8f7f3be0fa

1
.gitignore vendored

@ -3,3 +3,4 @@ coverage.html
profile.out profile.out
/.idea /.idea
/bin

@ -36,4 +36,14 @@ pkg/ ......源码包
|-- errors/ ......错误处理 |-- errors/ ......错误处理
|-- log/ ......日志库 |-- log/ ......日志库
|-- unique/ ......对象唯一ID |-- unique/ ......对象唯一ID
demo/ ......示例相关的代码
bin/ ......可执行文件编译输出目录
``` ```
#### 依赖
无任何第三方依赖
#### 其他
本仓库主要用于存放我自己写的一些Go基础库代码。目前服务于我的另一个项目 [lal](https:////github.com/q191201771/lal)

@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -x
ROOT_DIR=`pwd`
echo ${ROOT_DIR}/bin
if [ ! -d ${ROOT_DIR}/bin ]; then
mkdir bin
fi
cd ${ROOT_DIR}/demo/connstat && go build -o ${ROOT_DIR}/bin/connstat

@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -x
ROOT_DIR=`pwd`
echo ${ROOT_DIR}/bin
if [ ! -d ${ROOT_DIR}/bin ]; then
mkdir bin
fi
cd ${ROOT_DIR}/demo/connstat && GOOS=linux GOARCH=amd64 go build -o ${ROOT_DIR}/bin/connstat_linux

@ -0,0 +1,82 @@
package main
import (
"flag"
"github.com/q191201771/nezha/pkg/errors"
"github.com/q191201771/nezha/pkg/log"
"net"
"sync"
"time"
)
// 测试 net.Conn.SetWriteDeadline 的性能开销
//
// 使用 <numOfConn> 个客户端端连接,并行向服务端发送数据
// 每个客户端发送 <numOfMsgPerConn> 个消息
// 服务端 MockServer 只接收数据,不做其他逻辑
const (
addr = ":10027"
)
var (
numOfConn int
numOfMsgPerConn int
)
func raw(writeTimeoutSec int) {
log.Infof("> raw. writeTimeoutSec=%d", writeTimeoutSec)
var ms MockServer
var conns []net.Conn
buf := make([]byte, 8)
ms.start(addr)
for i := 0; i < numOfConn; i++ {
conn, err := net.Dial("tcp", addr)
errors.PanicIfErrorOccur(err)
conns = append(conns, conn)
}
var wg sync.WaitGroup
wg.Add(numOfConn)
b := time.Now()
log.Infof("b:%+v", b)
for i := 0; i < numOfConn; i++ {
go func(ii int) {
for j := 0; j < numOfMsgPerConn; j++ {
if writeTimeoutSec != 0 {
err := conns[ii].SetWriteDeadline(time.Now().Add(time.Duration(writeTimeoutSec) * time.Second))
errors.PanicIfErrorOccur(err)
}
_, err := conns[ii].Write(buf)
errors.PanicIfErrorOccur(err)
}
wg.Done()
}(i)
}
wg.Wait()
log.Infof("cost=%v", time.Now().Sub(b))
for i := 0; i < numOfConn; i++ {
err := conns[i].Close()
errors.PanicIfErrorOccur(err)
}
ms.stop()
log.Info("< raw.")
}
func main() {
c := flag.Int("c", 0, "num of conn")
n := flag.Int("n", 0, "num of msg per conn")
flag.Parse()
if *c == 0 || *n == 0 {
flag.Usage()
return
}
numOfConn = *c
numOfMsgPerConn = *n
raw(0)
raw(5)
}

@ -0,0 +1,40 @@
package main
import "net"
// MockServer 开启一个TCP监听并从accept的连接上循环读取数据
type MockServer struct {
l net.Listener
}
func (ms *MockServer) start(addr string) (err error) {
ms.l, err = net.Listen("tcp", addr)
if err != nil {
return err
}
go func() {
for {
conn, err := ms.l.Accept()
if err != nil {
//fmt.Println(err)
return
}
go func() {
buf := make([]byte, 8)
for {
_, err = conn.Read(buf)
if err != nil {
//fmt.Println(err)
return
}
}
}()
}
}()
return
}
func (ms *MockServer) stop() {
ms.l.Close()
}

@ -5,7 +5,6 @@ import (
"testing" "testing"
) )
// 大部分时候 TestingT interface 的实例为单元测试中的 *testing.T 和 *testing.B // 大部分时候 TestingT interface 的实例为单元测试中的 *testing.T 和 *testing.B
// MockTestingT 是为了对自身做单元测试 // MockTestingT 是为了对自身做单元测试
type MockTestingT struct { type MockTestingT struct {

@ -11,7 +11,7 @@ type MockServer struct {
l net.Listener l net.Listener
} }
func (ms *MockServer)start() (err error) { func (ms *MockServer) start() (err error) {
ms.l, err = net.Listen("tcp", ":10027") ms.l, err = net.Listen("tcp", ":10027")
if err != nil { if err != nil {
return err return err
@ -38,7 +38,7 @@ func (ms *MockServer)start() (err error) {
return return
} }
func (ms *MockServer)stop() { func (ms *MockServer) stop() {
ms.l.Close() ms.l.Close()
} }
@ -53,7 +53,7 @@ func BenchmarkRaw(b *testing.B) {
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
conn, err := net.Dial("tcp", ":10027") conn, err := net.Dial("tcp", ":10027")
assert.Equal(b, nil , err) assert.Equal(b, nil, err)
conns = append(conns, conn) conns = append(conns, conn)
} }
@ -76,7 +76,7 @@ func BenchmarkDeadline(b *testing.B) {
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
conn, err := net.Dial("tcp", ":10027") conn, err := net.Dial("tcp", ":10027")
assert.Equal(b, nil , err) assert.Equal(b, nil, err)
conns = append(conns, conn) conns = append(conns, conn)
} }

@ -59,15 +59,15 @@ func TestNew(t *testing.T) {
l Logger l Logger
err error err error
) )
l, err = New(Config{Level:LevelError+1}) l, err = New(Config{Level: LevelError + 1})
assert.Equal(t, nil, l) assert.Equal(t, nil, l)
assert.Equal(t, logErr, err) assert.Equal(t, logErr, err)
l, err = New(Config{Filename:"/tmp"}) l, err = New(Config{Filename: "/tmp"})
assert.Equal(t, nil, l) assert.Equal(t, nil, l)
assert.IsNotNil(t, err) assert.IsNotNil(t, err)
l, err = New(Config{Filename:"./log_test.go/111"}) l, err = New(Config{Filename: "./log_test.go/111"})
assert.Equal(t, nil, l) assert.Equal(t, nil, l)
assert.IsNotNil(t, err) assert.IsNotNil(t, err)
} }
@ -82,10 +82,10 @@ func TestRotate(t *testing.T) {
err := Init(c) err := Init(c)
assert.Equal(t, nil, err) assert.Equal(t, nil, err)
b := make([]byte, 1024) b := make([]byte, 1024)
for i := 0; i < 2 * 1024; i++ { for i := 0; i < 2*1024; i++ {
Info(b) Info(b)
} }
for i := 0; i < 2 * 1024; i++ { for i := 0; i < 2*1024; i++ {
Infof("%+v", b) Infof("%+v", b)
} }
} }

Loading…
Cancel
Save