实现限流操作
This commit is contained in:
parent
505c07bde6
commit
301eb9d7a2
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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:";
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue