asynq Sunucusunun Görev İşleme Hız Sınırlamasını Uygulamak İçin Yapılandırma Örneği

Bu sayfa, asynq sunucusunun görev işleme hız sınırlamasını uygulamak için nasıl yapılandırılacağını göstermektedir.

Lütfen unutmayın, bu her sunucu örneği için olan bir hız sınırlamasıdır, genel bir hız sınırlaması değildir.

Bu örnekte, hız sınırlamasını göstermek için golang.org/x/time/rate paketini kullanacağız. Sunucu başlatma ayarlarınızda ana yapılandırmalar, IsFailure ve RetryDelayFunc'dir. Özel bir hata türü oluşturacak ve IsFailure ve RetryDelayFunc fonksiyonlarında verilen hatayı tür olarak belirteceğiz.

package main

import (
	"context"
	"errors"
	"fmt"
	"log"
	"math/rand"
	"time"

	"golang.org/x/time/rate"
	"github.com/hibiken/asynq"
)

func main() {
	srv := asynq.NewServer(
		asynq.RedisClientOpt{Addr: ":6379"},
		asynq.Config{
			Concurrency:    10,
			// Hız sınırlamasından kaynaklanan bir hatayı bir başarısızlık olarak saymayın.
			IsFailure:      func(err error) bool { return !IsRateLimitError(err) },
			RetryDelayFunc: retryDelay,
		},
	)

	if err := srv.Run(asynq.HandlerFunc(handler)); err != nil {
		log.Fatal(err)
	}
}

type RateLimitError struct {
	RetryIn time.Duration
}

func (e *RateLimitError) Error() string {
	return fmt.Sprintf("Hız sınırına ulaşıldı (yeniden deneme süresi %v)", e.RetryIn)
}

func IsRateLimitError(err error) bool {
	_, ok := err.(*RateLimitError)
	return ok
}

func retryDelay(n int, err error, task *asynq.Task) time.Duration {
	var ratelimitErr *RateLimitError
	if errors.As(err, &ratelimitErr) {
		return ratelimitErr.RetryIn
	}
	return asynq.DefaultRetryDelayFunc(n, err, task)
}

// Saniyede 10 olaylık hız sınırı, en fazla 30 olaylık patlamalara izin veren sınırlayıcı.
var limiter = rate.NewLimiter(10, 30)

func handler(ctx context.Context, task *asynq.Task) error {
	if !limiter.Allow() {
		return &RateLimitError{
			RetryIn: time.Duration(rand.Intn(10)) * time.Second,
		}
	}
	log.Printf("[*] %s görevi işleniyor", task.Payload())
	return nil
}