zoukankan      html  css  js  c++  java
  • 两个小实例测试

    ab压测

    package main
    
    import (
        "flag"
        "fmt"
        "log"
        "net/http"
        "os"
        "strings"
        "sync"
        "time"
    )
    
    var usage = `Usage: %s [options]
    Options are:
        -n number     Number of requests to perform
        -c concurrency  Number of multiple requests to make at a time
        -t timeout      Seconds to max. wait for each response
        -m method       Method name
    `
    
    var (
        number int
        concurrency int
        timeout int
        method string
        url string
    )
    
    func init() {
        flag.Usage = func() {
            fmt.Fprintf(os.Stderr, usage, os.Args[0])
        }
    
        flag.IntVar(&number, "n", 1000, "")
        flag.IntVar(&concurrency, "c", 10, "")
        flag.IntVar(&timeout, "t", 1, "")
        flag.StringVar(&method, "m", "GET", "")
    
        if flag.NArg() != 1 {
            exit("Invalid url")
        }
    
        method = strings.ToUpper(method)
        url = flag.Args()[0]
    
        if method != "GET" {
            exit("Invalid method")
        }
    
        if number < 1 || concurrency < 1 {
            exit("-n and -c cannot be smaller than 1.")
        }
    
        if number < concurrency {
            exit("-n cannot be less than -c.")
        }
    }
    
    type benchmark struct {
        number int
        concurrency int
        timeout int
        method string
        url string
        duration chan time.Duration
        start time.Time
        end time.Time
    }
    
    func (b *benchmark) run() {
        b.duration = make(chan time.Duration, b.number)
        b.start = time.Now()
        b.runWorks()
        b.end = time.Now()
    
        b.report()
    }
    
    func (b *benchmark) runWorks() {
        var wg sync.WaitGroup
    
        wg.Add(b.concurrency)
    
        for i := 0; i < b.concurrency; i++ {
            go func() {
                defer wg.Done()
                b.runWork(b.number / b.concurrency)
            }()
        }
    
        wg.Wait()
        close(b.duration)
    }
    
    func (b *benchmark) runWork(num int) {
        client := &http.Client{
            Timeout:time.Duration(b.timeout) * time.Second,
        }
    
        for i := 0; i < num; i++ {
            b.request(client)
        }
    }
    
    func (b *benchmark) request(client *http.Client) {
        req, err := http.NewRequest(b.method, b.url, nil)
    
        if err != nil {
            log.Fatal(req)
        }
    
        start := time.Now()
        client.Do(req)
        end := time.Now()
    
        b.duration <- end.Sub(start)
    }
    
    func (b *benchmark) report() {
        sum := 0.0
        num := float64(len(b.duration))
    
        for duration := range b.duration {
            sum += duration.Seconds()
        }
    
        rps := int(num / b.end.Sub(b.start).Seconds())
        tpr := sum / num * 1000
    
        fmt.Printf("rps: %d [#/sec]
    ", rps)
        fmt.Printf("tpr: %.3f [ms]
    ", tpr)
    }
    
    func exit(msg string) {
        flag.Usage()
        fmt.Fprintln(os.Stderr, "
    [ERROR] " + msg)
        os.Exit(1)
    }
    
    func main() {
        b := benchmark{
            number:      number,
            concurrency: concurrency,
            timeout:     timeout,
            method:      method,
            url:         url,
        }
    
        b.run()
    }

    数据库sql测试

    package main
    
    import (
        "database/sql"
        "fmt"
        "github.com/spf13/cobra"
        "github.com/spf13/viper"
        "log"
        "os"
        "sync"
        "time"
    )
    
    var db *sql.DB
    var number, concurrency int
    
    var cmd = &cobra.Command{
        Use:    "benchmark sql",
        Short:    "a sql benchmark tool",
        Args:     func(cmd *cobra.Command, args []string) error {
            if len(args) != 1 {
                cmd.Usage()
                os.Exit(1)
            }
            return nil
        },
        Run:     func(cmd *cobra.Command, args []string) {
            b := benchmark{
                sql:args[0],
                number:number,
                concurrency:concurrency,
            }
            b.run()
        },
    }
    
    func init() {
        cobra.OnInitialize(config)
    
        cmd.Flags().IntVarP(&number, "number", "n", 100, "number")
        cmd.Flags().IntVarP(&concurrency, "concurrency", "c", 1, "concurrency")
        cmd.Flags().SortFlags = false
    }
    
    func config() {
        viper.AddConfigPath(".")
        viper.SetConfigName("db")
        viper.SetConfigType("toml")
    
        err := viper.ReadInConfig()
        if err != nil {
            log.Fatal(err)
        }
    
        driver := viper.GetString("driver")
        dsn := viper.GetString("dsn")
    
        db, err = sql.Open(driver, dsn)
        if err != nil {
            log.Fatal(err)
        }
    }
    
    type benchmark struct {
        sql string
        number int
        concurrency int
        duration chan time.Duration
        start time.Time
        end time.Time
    }
    
    func (b *benchmark) run() {
        b.duration = make(chan time.Duration, b.number)
        b.start = time.Now()
        b.runWorkers()
        b.end = time.Now()
        b.report()
    }
    
    func (b *benchmark) runWorkers() {
        var wg sync.WaitGroup
        wg.Add(b.concurrency)
    
        for i := 0; i < b.concurrency; i++ {
            go func() {
                defer wg.Done()
                b.runWorker(b.number / b.concurrency)
            }()
        }
    
        wg.Wait()
        close(b.duration)
    }
    
    func (b *benchmark) runWorker(num int) {
        for i := 0; i < num; i++ {
            start := time.Now()
            b.request()
            end := time.Now()
            b.duration <- end.Sub(start)
        }
    }
    
    func (b *benchmark) request() {
        if _, err := db.Exec(b.sql); err != nil {
            log.Fatalln(err)
        }
    }
    
    func (b *benchmark) report() {
        sum := 0.0
        num := float64(len(b.duration))
    
        for duration := range b.duration {
            sum += duration.Seconds()
        }
    
        qps := int(num / b.end.Sub(b.start).Seconds())
        tpq := sum / num * 1000
    
        fmt.Printf("qps: %d [#/sec]
    ", qps)
        fmt.Printf("tpq: %.3f [ms]
    ", tpq)
    }

    轮子一堆,我们没必要面面俱到,当一个组装工也是不错的,说实话,我认为多数人的智商就不要自己写轮子,不如学点方法论。

    两个都是学习自火丁笔记

    https://blog.huoding.com/2017/06/09/623

    https://blog.huoding.com/2019/08/21/768

    end

    一个没有高级趣味的人。 email:hushui502@gmail.com
  • 相关阅读:
    winform+c#之窗体之间的传值 Virus
    ASP.NET 2.0 利用 checkbox获得选中行的行号, 在footer中显示 Virus
    .NET中的winform的listview控件 Virus
    我的书橱
    Expert .NET 2.0 IL Assembler·译者序一 写在一稿完成之即
    Verbal Description of Custom Attribute Value
    AddressOfCallBacks in TLS
    下一阶段Schedule
    2008 Oct MVP OpenDay 第二天 博客园聚会
    2008 Oct MVP OpenDay 第二天 颁奖·讲座·晚会
  • 原文地址:https://www.cnblogs.com/CherryTab/p/12827726.html
Copyright © 2011-2022 走看看