【故障補牢】貪吃的 Bing 爬蟲,限量供應的應對措施

部落格園團隊發表於2023-05-09

相對於【故障公告】,【故障補牢】分享的是園子在發生故障後採取的亡羊補牢措施。

在上次被微軟 Bing 爬當機後(詳見 【故障公告】被放出的 Bing 爬蟲,又被爬當機的園子),我們採取了2個應對措施,然後解除了對 Bing 爬蟲的遮蔽。

措施1:限流——採用滑動視窗進行限流

我們之前採用的限流措施沒有采用滑動視窗,只能防君子不能防小人,比如限制同一個IP一天只能請求2萬次,但如果遇到大胃口的爬蟲,1秒請求2萬次,雖然沒有超過限制,但伺服器已趴下。

我們透過 ASP.NET Core 內建的 rate limiting middleware 進行滑動視窗限流,參考博文 ASP.NET Core rate limiting middleware in .NET 7

services.AddRateLimiter(
    _ =>
    {
        _.GlobalLimiter = PartitionedRateLimiter.CreateChained(
            PartitionedRateLimiter.Create<HttpContext, string>(
                _ => RateLimitPartition.GetSlidingWindowLimiter(
                    "total",
                    _ => new SlidingWindowRateLimiterOptions()
                    {
                        AutoReplenishment = true,
                        PermitLimit = limitOptions.TotalPermitLimit,
                        QueueLimit = 0,
                        Window = TimeSpan.FromSeconds(limitOptions.WindowSize),
                        SegmentsPerWindow = limitOptions.WindowSize,
                        QueueProcessingOrder = QueueProcessingOrder.OldestFirst
                    })),
            PartitionedRateLimiter.Create<HttpContext, string>(
                context => RateLimitPartition.GetFixedWindowLimiter(
                    partitionKey: context.GetUserIp() ?? "unspecified",
                    factory: _ => new FixedWindowRateLimiterOptions
                    {
                        AutoReplenishment = true,
                        PermitLimit = limitOptions.PermitLimit,
                        QueueLimit = limitOptions.QueueLimit,
                        Window = TimeSpan.FromSeconds(limitOptions.WindowSize),
                        QueueProcessingOrder = QueueProcessingOrder.OldestFirst
                    })));
        _.OnRejected = (context, _) =>
        {
            context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests;
            return default;
        };
    });

措施2:隔離——專用 pod 限制計算資源、專用負載均衡限制頻寬

藉助 k8s 的資源隔離能力,部署專用的 pod 給 Bing 爬蟲使用,最多把 pod 爬掛,不會造成伺服器當機,對其他應用 pod 毫無影響。

部署專門的負載均衡給 Bing 爬蟲通行,這樣可以避免因爬蟲搶佔頻寬而造成其他正常請求無法正常響應,而且可以透過限制頻寬控制爬蟲的併發請求量以及頻寬成本。

相關文章