Golang计时器(股票代号)延迟在选择中触发

时间:2019-05-10 09:54:01

标签: go

编写一个简单的TCP请求压力测试工具,并希望指定停止它的时间,但这会延迟每次执行

使用两个选择器进行收听,但仍然相同

我怀疑因为completeChannel已被接受,所以我不会执行testDuration.C,所以我编写了一个演示,一直在通道中写入数据,但是计时器仍然可以工作

客户端:

package main

import (
    "encoding/json"
    "flag"
    "fmt"
    "net"
    "os"
    "strings"
    "syscall"
    "time"
)

var (
    count           int
    second          int
    conn            int
    ip              string
    completeChannel = make(chan struct{}, 0)
    testDuration    = new(time.Timer)
    printOutTpl     = `
Test results:
The process ID: %d
Request the address: %s
Total number of requests: %d
Test of time: %f
Total number of completed: %d
`
)

const (
    network = "tcp"
)

func getPutMessage(key, value string) string {
    m := struct {
        Protocol int         `json:"protocol"` // 协议版本,保留字段
        Type     int         `json:"type"`     // 消息类型,见constant
        Put      interface{} `json:"put"`      // 消息体
    }{
        Protocol: 1,
        Type:     20000, // PUT
        Put: struct {
            Key   string `json:"key"`
            Value string `json:"value"`
        }{
            Key:   key,
            Value: value,
        },
    }

    bytes, _ := json.Marshal(m)
    return string(bytes)
}

func writeToLoopex(id, address string) {
    connection, err := net.Dial(network, address)
    if err != nil {
        fmt.Printf("connect to %s failed: %v\n", address, err)
        return
    }

    value := `{"remote_ip":"127.0.0.1","referrer":"http://www.baidu.com","channel":1,"province":11,"click_at":1556275700473}`

    for i := 0; i < count; i += 1 {
        k := fmt.Sprintf("%s-%d", id, i)
        s := getPutMessage(k, value)
        connection.Write([]byte(s + "\n"))
        completeChannel <- struct{}{}
    }

    connection.Close()

}

func concurrentlyWriteToLoopex(id, address string, concurrency int) {
    for i := 0; i < concurrency; i++ {
        nid := fmt.Sprintf("%s%d", id, i)
        go func() {
            writeToLoopex(nid, address)
        }()
    }
}

func main() {
    var (
        complete = 0
        allCount = 0
        start    = time.Now()
        ids      = []string{"A", "B", "C", "D", "E", "F"}
    )

    flag.IntVar(&conn, "conn", 300, "连接数")
    flag.IntVar(&second, "second", 0, "持续时间")
    flag.IntVar(&count, "count", 100, "单个连接发送数量")
    flag.StringVar(&ip, "ip", "127.0.0.1", "IP 地址支持逗号 , 分隔多个")

    flag.Parse()

    ips := strings.Split(ip, ",")
    if len(ips) < 1 {
        fmt.Println("请输入IP地址!")
        os.Exit(1)
    }

    if second >= 1 {
        testDuration = time.NewTimer(time.Duration(second) * time.Second)
    }

    defer func() {
        testDuration.Stop()
        end := time.Since(start)
        fmt.Printf(printOutTpl, syscall.Getpid(), ip, allCount, end.Seconds(), complete)
    }()

    for i := 0; i < len(ips); i++ {
        go concurrentlyWriteToLoopex(ids[i], ips[i], conn)
    }

    allCount = conn * count * len(ips)

    for {
        select {
        case <-completeChannel:
            complete++
            if complete == allCount {
                return
            }
        case <-testDuration.C:
            return
        }
    }
}

服务器:

package main

import (
    "fmt"
    "log"
    "net"
    "sync/atomic"
    "time"
)

var (
    count int64 = 0
)

func main(){
    n,err := net.Listen("tcp", ":8081")

    if err != nil{
        log.Fatal(err)
    }

    for {
        conn,err := n.Accept()
        if err != nil{
            log.Fatal(err)
        }


        go func(conn net.Conn) {
            bytes := make([]byte,4096)
            conn.Read(bytes)
            fmt.Println(string(bytes))
            atomic.AddInt64(&count,1)
            defer conn.Close()
        }(conn)
        fmt.Println(count)
    }

}

cmd: 我希望这花费一秒钟以上的时间

./cli/cli -conn=200 -count 3000 -ip 127.0.0.1:8081,127.0.0.1:8081 -second 1

只要时间到了,就执行defer并打印结果。 时间与时间测试相同

0 个答案:

没有答案