1. 程式人生 > >WebApiThrottle限流框架——執行期間更新限制頻率

WebApiThrottle限流框架——執行期間更新限制頻率

為了更新限制策略物件,並在執行時使用新的ThrottlingHandler物件,需要引入WebApiThrottle 1.2版本後支援的ThrottleManager.UpdatePolicy函式。

在啟動時註冊ThrottlingHandler物件,並在建構函式中傳入PolicyCacheRepository ,如果你是通過Owin自寄宿的webapi,需要使用PolicyMemoryCacheRepository物件。

public static void Register(HttpConfiguration config)
{
    //trace provider
    var traceWriter = new SystemDiagnosticsTraceWriter()
    {
        IsVerbose = true
    };
    config.Services.Replace(typeof(ITraceWriter), traceWriter);
    config.EnableSystemDiagnosticsTracing();

    //新增限流處理者到Web API訊息處理集合裡
    config.MessageHandlers.Add(new ThrottlingHandler(
        policy: new ThrottlePolicy(perMinute: 20, perHour: 30, perDay: 35, perWeek: 3000)
        {
            //啟用ip限制策略
            IpThrottling = true,

            //啟用客戶端key限制策略
            ClientThrottling = true,
            ClientRules = new Dictionary<string, RateLimits>
            { 
                { "api-client-key-1", new RateLimits { PerMinute = 60, PerHour = 600 } },
                { "api-client-key-2", new RateLimits { PerDay = 5000 } }
            },

            //啟用端點限制策略
            EndpointThrottling = true
        },

        //如果是owin寄宿,替換成PolicyMemoryCacheRepository
        policyRepository: new PolicyCacheRepository(),

        //如果是owin寄宿,替換成MemoryCacheRepository 
        repository: new CacheRepository(),

        logger: new TracingThrottleLogger(traceWriter)));
}

當你想更新限制策略物件時,可以在任何你的程式碼裡呼叫靜態方法ThrottleManager.UpdatePolicy去重新整理記憶體中的策略資料。

public void UpdateRateLimits()
{
    //初始化策略倉庫
    var policyRepository = new PolicyCacheRepository();

    //從快取中獲取策略物件
    var policy = policyRepository.FirstOrDefault(ThrottleManager.GetPolicyKey());

    //更新客戶端限制頻率
    policy.ClientRules["api-client-key-1"] =
        new RateLimits { PerMinute = 80, PerHour = 800 };

    //新增新的客戶端限制頻率
    policy.ClientRules.Add("api-client-key-3",
        new RateLimits { PerMinute = 60, PerHour = 600 });

    //應用策略更新
    ThrottleManager.UpdatePolicy(policy, policyRepository);

}