实现限流操作
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_LIMIT = "verify:email:limit:";
|
||||||
public static final String VERIFY_EMAIL_DATA = "verify:email:data:";
|
public static final String VERIFY_EMAIL_DATA = "verify:email:data:";
|
||||||
|
|
||||||
public static final int ORDER_CORS = -102;
|
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