为了实现每个时间数量的请求数量限制的服务,我寻找在enqueue()/add()
命令超过某个频率时拒绝添加元素的队列的实现?
因此,例如,您可以每秒不再调用enqueue()/add()
1000次,并防止高资源消耗服务DDOS。
如果超出队列容量,队列必须拒绝enqueue()/add()
(直到您致电dequeue()/remove()
)。
答案 0 :(得分:1)
你想拒绝一个例外,或者你只是想忽略它们。
更好的方法可能是更新Map并忽略给定键的重复更新。这会丢弃您无法处理的事件,但始终确保最新更新密钥。
这样,您每秒消耗N条新消息,并且可以正常删除重复项。
e.g。
final ConcurrentMap<String, Message> map = new ConcurrentHashMap<>();
final BlockingQueue<String> queue = new ArrayBlockingQueue<>(10000);
int updateCount = 0;
long lastUpdate = 0;
public void enqueue(String key, Message message) {
map.put(key, message);
queue.offer(key);
}
public Message dequeue() throws InterruptedException {
long updateTime = System.currentTimeMillis();
long time = updateTime - lastUpdate;
lastUpdate = updateTime;
if (time > count)
count = 0;
else
count -= time;
if (count > 1000)
Thread.sleep(1);
count++;
while(true) {
String key = queue.take();
Message msg = map.remove(key);
if (msg != null)
return msg;
// if the msg is null, we have already sent the latest update for that key
}
}
这将为您提供每秒1000的更新速率,并始终为您提供任何密钥的最新更新。
答案 1 :(得分:1)
实现此目的的一种简单方法是在请求新的排队/添加操作时检查以下内容:
- 检查队列是否已满
- 检查自上次排队操作以来的时间是否> 1/1000秒。 2a)你可以通过保持时间来修改上面的第2点 1000枚最新排队行动的印章。每当请求入队操作时,请检查自此队列中进行的第一次操作以来的时间。 如果超过1秒,则从时间戳队列中弹出该操作并添加它 之一。
醇>