periodlimit.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  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. i := i
  38. wait.Add(1)
  39. go func() {
  40. for {
  41. select {
  42. case <-quit:
  43. wait.Done()
  44. return
  45. default:
  46. if v, err := lmt.Take(strconv.FormatInt(int64(i), 10)); err == nil && v == limit.Allowed {
  47. atomic.AddInt32(&allowed, 1)
  48. } else if err != nil {
  49. log.Fatal(err)
  50. } else {
  51. atomic.AddInt32(&denied, 1)
  52. }
  53. }
  54. }
  55. }()
  56. }
  57. wait.Wait()
  58. fmt.Printf("allowed: %d, denied: %d, qps: %d\n", allowed, denied, (allowed+denied)/seconds)
  59. }