一、问题导向
有没有办法像QQ扩列、Soul匹配规则那样,判断用户是否在某个时间内有过快的请求?这个请求是用户单一的请求,而不是高并发的请求,所以暂时不考虑限流算法。
二、程序思路
通过设置随机种子和循环来模拟用户的请求,设置个记录变量(requestCount),用来记录请求达到某个闸值(DISTINGUISH_FREQUENCY)时开始判断用户再次请求是否满足时间上的限制(DISTINGUISH_TIME)。
如果满足则增加记录值,并且类似出栈那样替换数组中的每一个值,否则提示过快,并跳过当前循环,进行下一次模拟请求。
三、实现代码
#include <iostream>
#include <stdio.h>
#include <malloc.h>
#include <time.h>
#include <windows.h>
#define random(x) rand()%(x)
// 如果在次数DISTINGUISH_FREQUENCY内满足n~n+k并且时间小于DISTINGUISH_TIME则认为请求过快,需进行等待
// 满足最大次数REQUEST_MAX_LIMIT_TIMES后禁止请求
#define DISTINGUISH_FREQUENCY 10 // 判别过快次数
#define DISTINGUISH_TIME 60.00 // 判别过快时间(s)
#define REQUEST_MAX_LIMIT_TIMES 50 // 最大请求数
using namespace std;
int main(void)
{
srand((int)time(0));
// DWORD类型的数组,存放每次请求的时间,数组长度为每次判别请求过快所需的次数DISTINGUISH_FREQUENCY
DWORD *arrayRequestTime = (DWORD*)malloc(sizeof(DWORD) * DISTINGUISH_FREQUENCY);
// 累计请求次数统计(只统计成功请求)
int requestCount = 0;
while (TRUE)
{
// 假设通过设置随机时间休眠来模拟用户随机时间进行请求
Sleep(1000 * (random(10) + 1));
// ======== 休眠结束,模拟用户开始请求 ======== //
// TODO
if (requestCount < DISTINGUISH_FREQUENCY)
{
arrayRequestTime[requestCount] = timeGetTime();
requestCount ++;
printf("请求成功,这是第%d次请求!\n", requestCount);
}
else
{
// 临时存储当前时间
DWORD temporaryNowTime = timeGetTime();
// 时间差决定了请求是否成功
double timeGap = (temporaryNowTime - arrayRequestTime[0]) * 1.00 / 1000;
printf("time: %.2f\n", timeGap);
if (timeGap > DISTINGUISH_TIME)
{
// 每次请求成功就将当前时间存入数组顶替末一位元素并递推
for (int i = 0; i < DISTINGUISH_FREQUENCY - 1; i ++)
{
arrayRequestTime[i] = arrayRequestTime[i + 1];
}
arrayRequestTime[DISTINGUISH_FREQUENCY - 1] = temporaryNowTime;
requestCount ++;
printf("请求成功,这是第%d次请求!\n", requestCount);
}
else
{
printf("请求过快!请求差距为%.2f\n", timeGap);
continue;
}
}
if (requestCount >= REQUEST_MAX_LIMIT_TIMES)
{
printf("请求结束!\n");
break;
}
}
// 验证存储时间是否正确
for (int i = 0; i < DISTINGUISH_FREQUENCY; i ++)
{
if (0 != i)
{
cout << i << " and " << i - 1 << " is " << arrayRequestTime[i] - arrayRequestTime[i - 1] << endl;
}
cout << i << ": " << arrayRequestTime[i] << endl;
}
free(arrayRequestTime);
return 0;
}
四、运行结果