periodlimit.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. "log"
  6. "runtime"
  7. "strconv"
  8. "sync"
  9. "sync/atomic"
  10. "time"
  11. "github.com/tal-tech/go-zero/core/limit"
  12. "github.com/tal-tech/go-zero/core/stores/redis"
  13. )
  14. const seconds = 5
  15. var (
  16. rdx = flag.String("redis", "localhost:6379", "the redis, default localhost:6379")
  17. rdxType = flag.String("redisType", "node", "the redis type, default node")
  18. rdxPass = flag.String("redisPass", "", "the redis password")
  19. rdxKey = flag.String("redisKey", "rate", "the redis key, default rate")
  20. threads = flag.Int("threads", runtime.NumCPU(), "the concurrent threads, default to cores")
  21. )
  22. func main() {
  23. flag.Parse()
  24. store := redis.NewRedis(*rdx, *rdxType, *rdxPass)
  25. fmt.Println(store.Ping())
  26. lmt := limit.NewPeriodLimit(seconds, 5, store, *rdxKey)
  27. timer := time.NewTimer(time.Second * seconds)
  28. quit := make(chan struct{})
  29. defer timer.Stop()
  30. go func() {
  31. <-timer.C
  32. close(quit)
  33. }()
  34. var allowed, denied int32
  35. var wait sync.WaitGroup
  36. for i := 0; i < *threads; i++ {
  37. wait.Add(1)
  38. go func() {
  39. for {
  40. select {
  41. case <-quit:
  42. wait.Done()
  43. return
  44. default:
  45. if v, err := lmt.Take(strconv.FormatInt(int64(i), 10)); err == nil && v == limit.Allowed {
  46. atomic.AddInt32(&allowed, 1)
  47. } else if err != nil {
  48. log.Fatal(err)
  49. } else {
  50. atomic.AddInt32(&denied, 1)
  51. }
  52. }
  53. }
  54. }()
  55. }
  56. wait.Wait()
  57. fmt.Printf("allowed: %d, denied: %d, qps: %d\n", allowed, denied, (allowed+denied)/seconds)
  58. }