Java漏洞桶代码:
import lombok.Getter;
@Getter
public class Funnel {
private int capacity;
private double leakingRate;
private int leftQuota;
private long leakingTs;
public Funnel(int capacity, double leakingRate, int leftQuota, long leakingTs) {
this.capacity = capacity;
this.leakingRate = leakingRate;
this.leftQuota = leftQuota;
this.leakingTs = leakingTs;
}
public Boolean water(int quota) {
makeSpace();
if (leftQuota >= quota) {
leftQuota = leftQuota - quota;
return true;
}
return false;
}
private void makeSpace() {
long nowTs = System.currentTimeMillis();
long deltaTs = nowTs - this.leakingTs;
int deltaQuota = (int) (deltaTs * leakingRate);
if (deltaQuota < 0) {
this.leftQuota = capacity;
this.leakingTs = nowTs;
return;
}
if (deltaQuota < 1) {
return;
}
this.leakingTs = nowTs;
this.leftQuota = this.leftQuota + deltaQuota;
if (this.leftQuota > this.capacity) {
this.leftQuota = this.capacity;
}
}
}
测试代码:
public class FunnelLimitRate {
private static Map<String, Funnel> funnels = new HashMap<>();
public static void main(String[] args) throws InterruptedException {
String userId = "2019";
String actionKey = "rgister";
int capacity = 8;
double leakingRate = 0.001;
int leftQuota = 5;
Funnel funnel = funnels.get(userId);
if (funnel == null) {
funnel = new Funnel(capacity, leakingRate, leftQuota, System.currentTimeMillis());
}
for (int i = 0; i < 8; i++) {
Boolean isBoolean = funnel.water(1);
TimeUnit.MILLISECONDS.sleep(1000);
System.out.println(isBoolean + " " + funnel.getLeakingRate());
}
}
|