throttled 是一个非常轻量且易扩展的限流组件,我们可以将它轻松地集成到应用程序中,以实现限流和配额管理的能力。

简介

throttled(https://github.com/throttled/throttled) 基于通用信元速率算法实现了对资源的访问速率限制,资源可以是特定的 URL、用户或者任何自定义的形式,可以很方便地与各种 http 和 rpc 框架进行集成。throttled 定义了限流元信息的存储抽象,并内置了 memstore,redis store 等元信息存储实现,我们可以根据具体的使用场景实现单机限流和集群限流。

使用举例

下面我们来基于 throttled 自带的 http 限流组件实现一个简单的 demo 试试看:

  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "net/http"
  6. "github.com/throttled/throttled/v2"
  7. "github.com/throttled/throttled/v2/store/memstore"
  8. )
  9. func main() {
  10. // 在 store 中添加 key 的数量限制
  11. store, err := memstore.New(65536)
  12. if err != nil {
  13. log.Fatal(err)
  14. }
  15. // 配置限流规则
  16. quota := throttled.RateQuota{
  17. MaxRate: throttled.PerMin(20),
  18. MaxBurst: 5,
  19. }
  20. rateLimiter, err := throttled.NewGCRARateLimiter(store, quota)
  21. if err != nil {
  22. log.Fatal(err)
  23. }
  24. httpRateLimiter := throttled.HTTPRateLimiter{
  25. RateLimiter: rateLimiter,
  26. // 根据 path 进行限流
  27. VaryBy: &throttled.VaryBy{Path: true},
  28. }
  29. handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  30. fmt.Fprintf(w, "hello, world\n")
  31. })
  32. http.ListenAndServe(":8080", httpRateLimiter.RateLimit(handler))
  33. }

以上我们实现了一个按请求 path 进行限流的 http 服务,允许同一个 path 每分钟 20 次请求,并支持短时间内最多 5 个请求的 burst。
此外,我们也可以通过指定 VaryBy 和 DeniedHandler 的方式对资源定义和超限处理进行一些更多的定制。

总结

throttled 是一款小巧轻量的限流组件,我们可以使用 throttled 非常轻松地实现单机或集群的 QPS 限流能力。当然,throttled 的限流手段比较单一,当前仅支持基于 QPS 的限流规则,尚未扩展更全面的限流模式和更丰富的阻断规则。