Token Bucket Limiter
Trên trang này
Namespace: Nalix.Runtime.Throttling
Assembly: Nalix.Runtime
TokenBucketLimiter ([Injectable] public sealed partial class TokenBucketLimiter : IDisposable, IAsyncDisposable, IReportable) là bộ giới hạn tốc độ token bucket có phân mảnh và độ chính xác cao của Nalix. Nó phục vụ cả việc giới hạn tốc độ toàn cục theo endpoint (Evaluate(INetworkEndpoint)) lẫn giới hạn theo policy riêng của từng handler (Evaluate(INetworkEndpoint, in RateLimitPolicy)).
Ánh xạ mã nguồn
src/Nalix.Runtime/Throttling/TokenBucketLimiter.cssrc/Nalix.Runtime/Throttling/TokenBucketLimiter.Cleanup.cssrc/Nalix.Runtime/Throttling/TokenBucketLimiter.Report.cssrc/Nalix.Runtime/Throttling/TokenBucketLimiter.Types.cssrc/Nalix.Runtime/Options/TokenBucketOptions.cs
Các đặc điểm kiến trúc chính
- Số học micro-token dạng số cố định (
TokenScale): Số dư được theo dõi bằng số nguyên micro-token (1token đầy đủ =TokenScalemicro-token, mặc định100), dùng tick củaStopwatch.GetTimestamp(), tránh sai số dấu phẩy động khi tốc độ gói tin cao. - Phân mảnh theo lũy thừa của hai (
ShardCount = 256): Các endpoint được chia vàoShardCountshard độc lập bằng bitmask kiểuXxHash32/ Murmur (hash & (ShardCount - 1)), loại bỏ tranh chấp khóa toàn cục. - Điều chỉnh tốc độ nạp theo CPU (
AdaptiveThrottlingEnabled): KhiAdaptiveThrottlingEnabledlàtrue(mặc định) vàITaskManagerđã được đăng ký, tốc độ nạp token tự động co giãn theoITaskManager.ConcurrencyLimitRatio(0.0..1.0) khi CPU của máy chủ tải cao. - Leo thang từ Soft Throttle sang Hard Lockout: Khi một endpoint dùng hết token, mỗi yêu cầu bị từ chối trong
SoftViolationWindowSeconds(8s) sẽ tăngSoftViolations. Khi đạtMaxSoftViolations(5), endpoint bị khóa trongHardLockoutSeconds(30s). EndpointStatecó pool và số lượng bị chặn: Các instanceEndpointStateđược tái sử dụng quaObjectPoolManager.Shared, giới hạn ởMaxTrackedEndpoints(100_000), và được quét định kỳ bởi job dọn dẹp lặp lại"token.bucket".
Tham chiếu API công khai
Constructor & trường tĩnh
| Thành phần | Chữ ký | Mô tả |
|---|---|---|
RecurringName | public static readonly string RecurringName = "token.bucket"; | Tên gốc của job dọn dẹp các mục cũ lặp lại được lập lịch trong ITaskManager. |
TokenBucketLimiter() | public TokenBucketLimiter() | Khởi tạo bộ giới hạn bằng ConfigurationManager.Instance.Get<TokenBucketOptions>(). |
TokenBucketLimiter(TokenBucketOptions?) | public TokenBucketLimiter(TokenBucketOptions? options = null) | Khởi tạo bộ giới hạn với TokenBucketOptions được truyền vào và kiểm tra tính hợp lệ của nó. |
Phương thức đánh giá & chẩn đoán
| Phương thức | Chữ ký | Mô tả |
|---|---|---|
Evaluate (policy toàn cục) | public RateLimitDecision Evaluate(INetworkEndpoint key) | Tiêu thụ 1 token cho key theo TokenBucketOptions đã cấu hình của bộ giới hạn. |
Evaluate (policy động) | public RateLimitDecision Evaluate(INetworkEndpoint key, in RateLimitPolicy policy) | Tiêu thụ 1 token cho key theo RateLimitPolicy riêng của handler (được PolicyRateLimiter dùng). |
GenerateReport | public string GenerateReport() | Trả về bản tóm tắt chẩn đoán đã định dạng, gồm CapacityTokens, RefillPerSecond, TokenScale, Shards, TrackedEndpoints, PeakTrackedEndpoints, HardBlockedCount, SoftWarningCount và TotalCleaned. |
WriteReportData | public void WriteReportData(Utf8JsonWriter writer) | Ghi các chỉ số chẩn đoán dạng JSON có cấu trúc. |
Dispose / DisposeAsync | public void Dispose() / public ValueTask DisposeAsync() | Hủy job dọn dẹp lặp lại và đánh dấu bộ giới hạn đã dispose (các lệnh Evaluate sau đó fail-close với HardLockout). |
Kiểu lồng nhau (RateLimitDecision, RateLimitReason, RateLimitPolicy)
public readonly struct RateLimitDecision
{
public bool Allowed { get; init; }
public int RetryAfterMs { get; init; }
public ushort Credit { get; init; }
public RateLimitReason Reason { get; init; }
}
public enum RateLimitReason : byte
{
None = 0,
SoftThrottle = 1,
HardLockout = 2
}
Ví dụ sử dụng
using Nalix.Abstractions.Networking;
using Nalix.Runtime.Options;
using Nalix.Runtime.Throttling;
using TokenBucketLimiter limiter = new(new TokenBucketOptions
{
CapacityTokens = 64,
RefillTokensPerSecond = 32.0,
HardLockoutSeconds = 30,
MaxSoftViolations = 5
});
TokenBucketLimiter.RateLimitDecision decision = limiter.Evaluate(connection.NetworkEndpoint);
if (!decision.Allowed)
{
// Từ chối gói tin; khuyên client thử lại sau decision.RetryAfterMs
}