实现限流操作

This commit is contained in:
Amadeus 2024-05-26 22:49:18 +08:00
parent 505c07bde6
commit 301eb9d7a2
2 changed files with 67 additions and 1 deletions

View File

@ -0,0 +1,62 @@
package com.example.filter;
import com.example.entity.RestBean;
import com.example.utils.Const;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
@Component
@Order(Const.ORDER_LIMIT)
public class FlowLimitFilter extends HttpFilter {
@Resource
StringRedisTemplate template;
@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
String address = request.getRemoteAddr();
if (this.tryCount(address)){
chain.doFilter(request,response);
}else {
this.writeBlockMessage(response);
}
}
private void writeBlockMessage(HttpServletResponse response) throws IOException {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.setContentType("application/json;charset=uft-8");
response.getWriter().write(RestBean.forbidden("操作频繁,请稍后再试").asJsonString());
}
private boolean tryCount(String ip){
synchronized (ip.intern()){
if (Boolean.TRUE.equals(template.hasKey(Const.FLOW_LIMIT_BLOCK + ip))){
return false;
}
return this.limitPeriodCheck(ip);
}
}
private boolean limitPeriodCheck(String ip){
if (Boolean.TRUE.equals(template.hasKey(Const.FLOW_LIMIT_COUNTER + ip))) {
long increment = Optional.ofNullable(template.opsForValue().increment(Const.FLOW_LIMIT_COUNTER + ip)).orElse(0L) ;
if (increment > 10){
template.opsForValue().set(Const.FLOW_LIMIT_BLOCK + ip , "" , 30 ,TimeUnit.SECONDS);
return false;
}
}else {
template.opsForValue().set(Const.FLOW_LIMIT_COUNTER + ip ,"1" ,3 , TimeUnit.SECONDS );
}
return true;
}
}

View File

@ -5,7 +5,11 @@ public class Const {
public static final String VERIFY_EMAIL_LIMIT = "verify:email:limit:";
public static final String VERIFY_EMAIL_DATA = "verify:email:data:";
public static final int ORDER_CORS = -102;
public static final int ORDER_LIMIT = -101;
public static final String FLOW_LIMIT_COUNTER= "flow:counter:";
public static final String FLOW_LIMIT_BLOCK= "flow:block:";
}