练习Go语言-HTTP压力测试.md

来源:互联网 发布:java 语句 顺序 编辑:程序博客网 时间:2024/06/03 19:27

    • 设计
    • 服务端
    • 客户端

2017年10月20日星期五 7:26

设计

压力测试HTTP服务端。比如看看你的电脑能同时建立多少长连接。
算是我的第一个Go程序。
熬夜了。

主要运用了:

  • 参数处理
  • channel通讯
  • 整合了CPU和内存统计代码

协程和通讯的事都让Go做了,我就是来验证它的性能的。

服务端

package mainimport (    "fmt"    "io"    "log"    "net/http"    "os"    "runtime"    "runtime/pprof"    "strings")func helloHandler(w http.ResponseWriter, r *http.Request) {    r.ParseForm() //解析参数    if openLog {        fmt.Println(r.Form)        fmt.Println("path", r.URL.Path)        fmt.Println("scheme", r.URL.Scheme)        fmt.Println(r.Form["url_long"])    }    if openLog {        for k, v := range r.Form {            fmt.Println("key:", k)            fmt.Println("val:", strings.Join(v, ""))        }    }    io.WriteString(w, "Hello,Test Me!")    fmt.Fprintf(w, "Hello!")    My_Mem_Prof()    /*       不退出测试长连接性能    */    chLongLink <- true    <-chExitThreads}var chExitThreads chan boolvar chLongLink = make(chan bool, 1000*100)func openService() {    http.HandleFunc("/MyWeb", helloHandler)    err := http.ListenAndServe(":8686", nil)    if err != nil {        log.Fatal("ListenAndServe:", err.Error())    }}const openLog bool = falsevar ch_sync chan boolfunc calc() {    number := 0    for {        _, ok := <-chLongLink        if !ok {            break        }        number++        if (number % 100) == 0 {            fmt.Println("now long link:", number)        }    }    fmt.Println("All long link number is:", number)    close(ch_sync)    fmt.Println("End")}func My_Mem_Prof() {    fm, err := os.OpenFile("./tmp/mem.out", os.O_RDWR|os.O_CREATE, 0644)    if err != nil {        log.Fatal(err)    }    pprof.WriteHeapProfile(fm)    fm.Close()}func My_Cpu_Prof() {    f, err := os.OpenFile("./tmp/cpu.prof", os.O_RDWR|os.O_CREATE, 0644)    if err != nil {        log.Fatal(err)    }    defer f.Close()    pprof.StartCPUProfile(f)    defer pprof.StopCPUProfile()    <-chExitThreads    pprof.StopCPUProfile()    fmt.Println("End CPU Prof")    f.Close()    close(chExitProf)}var chExitProf chan boolfunc main() {    /*初始化channel通知*/    chExitThreads = make(chan bool)    ch_sync = make(chan bool)    chExitProf = make(chan bool)    runtime.GOMAXPROCS(runtime.NumCPU() * 2)    fmt.Println("CPU Number:", runtime.NumCPU())    fmt.Println("Thread Number:", runtime.NumCPU()*2)    go My_Cpu_Prof()    exp := `Please visit:      "http://localhost:8686/MyWeb"    `    /////////////////    fmt.Println(exp)    go calc()    go openService()    /*        直到用户输入才开始退出协程    */    input := make([]byte, 1024)    os.Stdin.Read(input)    close(chLongLink)    <-ch_sync    fmt.Println("OK")    close(chExitThreads)    <-chExitProf}

客户端

package mainimport (    "flag"    "fmt"    "io/ioutil"    "net/http"    "runtime"    "time")func client(exit_ch chan int, webPath string) {    var err error    resp, err := http.Get(webPath)    if err != nil {        // handle error        fmt.Println(err.Error())        goto threadEnd    }    /*body*/    _, err = ioutil.ReadAll(resp.Body)    if err != nil {        // handle error        fmt.Println(err.Error())        goto threadEnd    }    defer resp.Body.Close()    //fmt.Println(string(body))threadEnd:    exit_ch <- 1}func main() {    var webPath string    flag.StringVar(&webPath, "webpath", "http://baidu.com", "Tested Web Path")    test_time_work := flag.Int("time", 50, "Test times")    flag.Parse()    fmt.Println(webPath)    runtime.GOMAXPROCS(runtime.NumCPU() * 2)    exit_ch := make(chan int)    test_time := time.Now()    for i := 0; i < *test_time_work; i++ {        go client(exit_ch, webPath)    }    for i := 0; i < *test_time_work; i++ {        <-exit_ch        fmt.Println("Success time!:", i+1)    }    test_time_end := time.Since(test_time)    fmt.Println("End*******************")    fmt.Println("CPU Number:", runtime.NumCPU())    fmt.Println(test_time_end)}
原创粉丝点击