NET Coreでインターフェイスリクエストの数を制限する方法

NET Coreでインターフェイスリクエストの数を制限する方法

AspNetCoreRateLimitのようなホイールは前に紹介しましたが、今日は言わないで、その背後にある原理について話しましょう。

最后更新 2022/07/08 6:54
黑哥聊dotNet
预计阅读 3 分钟
分类
ASP.NET Core
标签
.NET C# ASP.NET Core

AspNetCoreRateLimit这种轮子我前面有给大家介绍过,今天就不说了,我们来聊聊背后的原理,欢迎各位大佬指正!

私たちが頻繁に見るAPiリクエストインターフェイスサイトのいくつか:

例えば、外国の主要都市の7日間のインターフェイスを要求すると、非 VIPは2000回しか使用できず、VIPユーザーは1日10000回まで要求し、インターフェイスを要求するときは、アカウントを登録してappidとキーを取得する必要があります。

そこで、この要件に応じて、天気を取得するための制限フローインターフェースを設計します。

最初のステップ

ログインアカウントが存在することを確認し、存在しない場合は存在しないエラーをスローします。

[HttpPost("GetWeather")]
public IActionResult ApiLimit(WeatherInfor weatherInfor)
{
  if (!_userService.IsValid(weatherInfor.Appid, weatherInfor.Appsecret))
  {
    throw new Exception("账号或者密码错误");
  }
}

第二のステップ

アカウントがVIPユーザーであるかどうかを判断し、それがVIPユーザーである場合は、呼び出しの合計数はなく、1日の制限数だけ、この1日の制限数のように、翌日のデータを空にするためにキャッシュを使用して処理する必要があります、我々はすべての要求キャッシュが有効かどうかを設定します。これはキャッシュの絶対的な有効期限です。

具体的なビジネスロジックは、ユーザーのappidが一意であるため、それをキー値として使用し、呼び出しの数を値として使用することができます。キャッシュが存在しない場合はキャッシュを追加し、キャッシュが存在する場合は呼び出し数を取得し、2000より大きい場合は呼び出し元に呼び出し数がなくなったことを伝え、存在しない場合はキャッシュから呼び出し数を取得して+1を与える。

** キャッシュクラス **

public class MemoryCacheHelper
{

    public static MemoryCache _cache = new MemoryCache(new MemoryCacheOptions());

    /// <summary>
    /// 验证缓存项是否存在
    /// </summary>
    /// <param name="key">缓存Key</param>
    /// <returns></returns>
    public static bool Exists(string key)
    {
        if (key == null)
        {
            return false;
        }
        return _cache.TryGetValue(key, out _);
    }

    /// <summary>
    /// 获取缓存
    /// </summary>
    /// <param name="key">缓存Key</param>
    /// <returns></returns>
    public static object Get(string key)
    {
        if (key == null)
        {
            throw new ArgumentNullException(nameof(key));
        }
        if (!Exists(key))
            throw new ArgumentNullException(nameof(key));


        return _cache.Get(key);
    }

    /// <summary>
    /// 添加缓存
    /// </summary>
    /// <param name="key">缓存Key</param>
    /// <param name="value">缓存Value</param>
    /// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
    /// <param name="expiressAbsoulte">绝对过期时长</param>
    /// <returns></returns>
    public static bool AddMemoryCache(string key, object value)
    {
        if (key == null)
        {
            throw new ArgumentNullException(nameof(key));
        }
        if (value == null)
        {
            throw new ArgumentNullException(nameof(value));
        }
        DateTime time = Convert.ToDateTime(DateTime.Now.AddDays(1).ToString("D").ToString()).AddSeconds(-1);
        _cache.Set(key, value, time);
        return Exists(key);
    }
}

** ビジネスロジック **

public bool IsLimit(string appId)
{
    if (MemoryCacheHelper.Exists(appId))
    {
        int value = int.Parse(MemoryCacheHelper.Get(appId).ToString());
        if (value > 2000)
            return false;
        else
            value = value + 1;

        MemoryCacheHelper.AddMemoryCache(appId, value);
    }
    else
    {
        MemoryCacheHelper.AddMemoryCache(appId, 1);
    }
    return true;
}

最後に、

気象インターフェイスにアクセスしてデータを返す

[HttpPost("GetWeather")]
public IActionResult ApiLimit(WeatherInfor weatherInfor)
{
    if (!_userService.IsValid(weatherInfor.Appid, weatherInfor.Appsecret))
    {
        throw new Exception("账号或者密码错误");
    }
    bool isLimit = false;
    if (_userService.IsVIP(weatherInfor.Appid))
    {
        isLimit= _sqlServices.IsLimit(weatherInfor.Appid);
    }
    else
    {
        isLimit = _memoryCacheServices.IsLimit(weatherInfor.Appid);
    }
    if (isLimit)
    {
        //查询天气接口 返回数据
    }
    else
    {
        throw new Exception("调用次数已用完");
    }
    return Ok("");
}

最后大家如果喜欢我的文章,还烦烦烦给个注目并点个赞,希望 net生态圏好!

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 2022/06/22

ASP.NET Core Web APIのローカライズ(単一リソースファイル)

マイクロソフトのデフォルトは、複数のリソースファイルに対応するクラスであり、使用はより面倒ですが、この記事では、単一のリソースファイルの使用方法、すなわち、プロジェクト全体のすべてのクラスが多言語リソースファイルのセットに対応しています。

继续阅读