FixedWindow.cs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using System;
  2. using System.Threading;
  3. using Sers.Core.Module.Message;
  4. using Sers.Core.Module.Rpc;
  5. using Sers.ServiceCenter.Entity;
  6. using Vit.Core.Util.ComponentModel.SsError;
  7. namespace Sers.Gover.RateLimit
  8. {
  9. /// <summary>
  10. /// 固定时间窗口限流
  11. /// </summary>
  12. public class FixedWindow: IRateLimit
  13. {
  14. /// <summary>
  15. /// 限流规则名称,一般对应一个类
  16. /// </summary>
  17. public string rateLimitType { get; set; }
  18. /// <summary>
  19. /// 限流项名称,必须唯一
  20. /// </summary>
  21. public string rateLimitKey { get; set; }
  22. /// <summary>
  23. /// 时间窗口内最大请求数
  24. /// </summary>
  25. public int reqLimit = 1000;
  26. /// <summary>
  27. /// 时间窗口ms
  28. /// </summary>
  29. public long msInterval = 1000;
  30. public SsError error = SsError.Err_RateLimit_Refuse;
  31. private int reqCount = 0;
  32. private long timeStampStart=0;
  33. private long timeStampEnd=0;
  34. public SsError BeforeLoadBalancing(RpcContextData rpcData, ApiMessage requestMessage)
  35. {
  36. //以_开始的系统节点不限流
  37. var route = rpcData.route??"";
  38. if (route.Length>1&& '_' == route[1])
  39. {
  40. return null;
  41. }
  42. //TODO: don't use lock !!!
  43. lock (this)
  44. {
  45. DateTime dtNow = DateTime.Now;
  46. long now = dtNow.Ticks;
  47. if (now < timeStampEnd)
  48. {
  49. // 在时间窗口内
  50. // 判断当前时间窗口内是否超过最大请求控制数
  51. if (Interlocked.Increment(ref reqCount) > reqLimit)
  52. return error;
  53. else
  54. {
  55. return null;
  56. }
  57. }
  58. else
  59. {
  60. timeStampStart = now;
  61. //timeStampEnd = timeStampStart + msInterval;
  62. timeStampEnd = dtNow.AddMilliseconds(msInterval).Ticks;
  63. // 超时后重置
  64. reqCount = 1;
  65. return null;
  66. }
  67. }
  68. }
  69. public SsError BeforeCallRemoteApi(RpcContextData rpcData, ApiMessage requestMessage, ApiNode apiNode)
  70. {
  71. return null;
  72. }
  73. }
  74. }