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
  • 相关阅读:
    360天擎安装上之后,手机开热点之后就没有办法连接
    Redis基本数据类型--Hash(哈希)
    Redis基本数据类型--Set
    redis的五种基本数据类型之List
    Redis的五种基本数据类型 String
    Android应用程序的安装位置
    Java中long和Long有什么区别(转)
    Logcat打印调试信息
    Java GUI图形界面开发工具
    CSDN精选Android开发博客
  • 原文地址:https://www.cnblogs.com/CherryTab/p/12827726.html
Copyright © 2011-2022 走看看