using System;
using System.Threading;
using Sers.Core.Module.Message;
using Sers.Core.Module.Rpc;
using Sers.ServiceCenter.Entity;
using Vit.Core.Util.ComponentModel.SsError;
namespace Sers.Gover.RateLimit
{
///
/// 固定时间窗口限流
///
public class FixedWindow: IRateLimit
{
///
/// 限流规则名称,一般对应一个类
///
public string rateLimitType { get; set; }
///
/// 限流项名称,必须唯一
///
public string rateLimitKey { get; set; }
///
/// 时间窗口内最大请求数
///
public int reqLimit = 1000;
///
/// 时间窗口ms
///
public long msInterval = 1000;
public SsError error = SsError.Err_RateLimit_Refuse;
private int reqCount = 0;
private long timeStampStart=0;
private long timeStampEnd=0;
public SsError BeforeLoadBalancing(RpcContextData rpcData, ApiMessage requestMessage)
{
//以_开始的系统节点不限流
var route = rpcData.route??"";
if (route.Length>1&& '_' == route[1])
{
return null;
}
//TODO: don't use lock !!!
lock (this)
{
DateTime dtNow = DateTime.Now;
long now = dtNow.Ticks;
if (now < timeStampEnd)
{
// 在时间窗口内
// 判断当前时间窗口内是否超过最大请求控制数
if (Interlocked.Increment(ref reqCount) > reqLimit)
return error;
else
{
return null;
}
}
else
{
timeStampStart = now;
//timeStampEnd = timeStampStart + msInterval;
timeStampEnd = dtNow.AddMilliseconds(msInterval).Ticks;
// 超时后重置
reqCount = 1;
return null;
}
}
}
public SsError BeforeCallRemoteApi(RpcContextData rpcData, ApiMessage requestMessage, ApiNode apiNode)
{
return null;
}
}
}