RateLimitMng.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Linq;
  4. using System.Runtime.CompilerServices;
  5. using Newtonsoft.Json;
  6. using Newtonsoft.Json.Linq;
  7. using Sers.Core.Module.Message;
  8. using Sers.Core.Module.Rpc;
  9. using Sers.ServiceCenter.Entity;
  10. using Vit.Core.Util.ComponentModel.SsError;
  11. using Vit.Extensions;
  12. using Vit.Extensions.Newtonsoft_Extensions;
  13. namespace Sers.Gover.RateLimit
  14. {
  15. public class RateLimitMng
  16. {
  17. /// <summary>
  18. /// rateLimitType -> RateLimitType 限制
  19. /// </summary>
  20. [JsonIgnore]
  21. ConcurrentDictionary<string, Type> limitType_Map = new ConcurrentDictionary<string, Type>();
  22. /// <summary>
  23. /// rateLimitKey -> IRateLimit 映射
  24. /// </summary>
  25. [JsonProperty]
  26. ConcurrentDictionary<string, IRateLimit> limit_Map = new ConcurrentDictionary<string, IRateLimit>();
  27. private IRateLimit[] limits=new IRateLimit[0];
  28. public RateLimitMng()
  29. {
  30. LimitType_Add("FixedWindow", typeof(FixedWindow));
  31. }
  32. #region 服务限流规则 管理
  33. public void LimitType_Add(string rateLimitType, Type type)
  34. {
  35. limitType_Map[rateLimitType] = type;
  36. }
  37. public void LimitType_Remove(string rateLimitType)
  38. {
  39. limitType_Map.TryRemove(rateLimitType, out _);
  40. }
  41. #endregion
  42. #region 服务限流项管理
  43. /// <summary>
  44. /// 获取所有限流项目
  45. /// </summary>
  46. /// <returns></returns>
  47. public IRateLimit[] RateLimit_GetAll()
  48. {
  49. return limits;
  50. }
  51. public void RateLimit_Remove(string rateLimitKey)
  52. {
  53. if (limit_Map.TryRemove(rateLimitKey, out _))
  54. {
  55. limits = limit_Map.Values.ToArray();
  56. }
  57. }
  58. public bool RateLimit_Add(JObject rateLimit)
  59. {
  60. if (!limitType_Map.TryGetValue(rateLimit["rateLimitType"].Value<string>(),out var type)) return false;
  61. var limitItem=rateLimit.Deserialize(type) as IRateLimit;
  62. if (null == limitItem) return false;
  63. limit_Map[limitItem.rateLimitKey] = limitItem;
  64. limits = limit_Map.Values.ToArray();
  65. return true;
  66. }
  67. #endregion
  68. #region 接口调用时触发的事件
  69. /// <summary>
  70. /// 若返回不为null,则对应服务被限流(服务直接返回对应错误)
  71. /// </summary>
  72. /// <param name="rpcData"></param>
  73. /// <param name="requestMessage"></param>
  74. /// <returns></returns>
  75. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  76. public SsError BeforeLoadBalancing(RpcContextData rpcData, ApiMessage requestMessage)
  77. {
  78. foreach (var rateLimit in limits)
  79. {
  80. var error = rateLimit.BeforeLoadBalancing(rpcData, requestMessage);
  81. if (null != error)
  82. return error;
  83. }
  84. return null;
  85. }
  86. /// <summary>
  87. /// 若返回不为null,则对应服务被限流(服务直接返回对应错误)
  88. /// </summary>
  89. /// <param name="rpcData"></param>
  90. /// <param name="requestMessage"></param>
  91. /// <param name="apiNode"></param>
  92. /// <returns></returns>
  93. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  94. public SsError BeforeCallRemoteApi(RpcContextData rpcData, ApiMessage requestMessage,ApiNode apiNode)
  95. {
  96. foreach (var rateLimit in limits)
  97. {
  98. var error = rateLimit.BeforeCallRemoteApi(rpcData, requestMessage, apiNode);
  99. if (null != error)
  100. return error;
  101. }
  102. return null;
  103. }
  104. #endregion
  105. }
  106. }