func StreamServerInterceptor(limiter Limiter) grpc.StreamServerInterceptor
func UnaryServerInterceptor(limiter Limiter) grpc.UnaryServerInterceptor
type Limiter
限制器定义了执行请求速率限制的接口。如果Limit函数返回true,请求将被拒绝。否则,请求将通过。
type Limiter interface {
Limit() bool
}
type Bucket
github.com/juju/ratelimit
type Bucket struct {
// contains filtered or unexported fields
}
func NewBucket(fillInterval time.Duration, capacity int64) *Bucket
- 按指定间隔向桶里填充一个令牌,直到 capacity,桶初始化是满的
func (tb Bucket) Available() int64:返回令牌桶可用的数量
func (tb Bucket) Capacity() int64:返回桶初始容量
func (tb Bucket) Rate() float64:填充速率,以秒为单位
func (tb Bucket) TakeAvailable(count int64) int64 不阻塞取出,没有返回0
func (tb *Bucket) TakeMaxDuration(count int64, maxWait time.Duration) (time.Duration, bool)
- TakeMaxDuration类似于Take,只是它只在令牌的等待时间不大于maxWait时才从bucket中获取令牌。
- 如果等待令牌可用的时间比maxWait长,那么它将不执行任何操作,并报告false,否则它将返回调用者应该等待的时间,直到令牌真正可用,然后报告true。
func (tb Bucket) Wait(count int64) 阻塞取出,桶内没有可用的则等待
func (tb Bucket) WaitMaxDuration(count int64, maxWait time.Duration) bool
import ( “context” “errors” “fmt” “github.com/grpc-ecosystem/go-grpc-middleware” “github.com/grpc-ecosystem/go-grpc-middleware/ratelimit” juju “github.com/juju/ratelimit” “google.golang.org/grpc” “log” “net” pb “study/grpc/protobuf/person” “time” )
const ( port = “:8080” )
type Limiter struct{ Bucket *juju.Bucket }
func (this *Limiter) Limit() bool { token := this.Bucket.TakeAvailable(1) fmt.Println(“桶可用数量:”,this.Bucket.Available()) if token == 0 { return true } return false }
func main() { lis, err := net.Listen(“tcp”, port) if err != nil { log.Fatalf(“failed to listen: %v”, err) } limiter := &Limiter{juju.NewBucket(time.Second*2,2)} opts := grpc_middleware.WithUnaryServerChain(ratelimit.UnaryServerInterceptor(limiter)) s := grpc.NewServer(opts) //起一个服务 pb.RegisterPersonserverServer(s,&Server{})
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
超速client端的错误: rpc error: code = ResourceExhausted desc = /person.personserver/GetPerson is rejected by grpc_ratelimit middleware, please retry later. refused it. ```