限流
This commit is contained in:
parent
ee3631b559
commit
2c213025ea
@ -53,7 +53,6 @@ public class PathPlanningApiImpl implements PathPlanningApi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void synchronousLineObject(Object obj, String topic) {
|
public void synchronousLineObject(Object obj, String topic) {
|
||||||
log.info("收到请求 :{}", JSON.toJSONString(obj));
|
|
||||||
try {
|
try {
|
||||||
mqttUtils.pub(topic, JSON.toJSONString(obj));
|
mqttUtils.pub(topic, JSON.toJSONString(obj));
|
||||||
log.info("同步信息给PP--完成 :{}", JSON.toJSONString(obj));
|
log.info("同步信息给PP--完成 :{}", JSON.toJSONString(obj));
|
||||||
|
@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil;
|
|||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import cn.iocoder.yudao.module.system.api.robot.dto.RobotGenericsDataDTO;
|
import cn.iocoder.yudao.module.system.api.robot.dto.RobotGenericsDataDTO;
|
||||||
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO;
|
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO;
|
||||||
|
import cn.iocoder.yudao.module.system.config.ratelimiter.SystemRateLimiter;
|
||||||
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
|
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
|
||||||
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
|
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
@ -25,10 +26,11 @@ public class RobotGenericsStatusApiImpl implements RobotGenericsStatusApi {
|
|||||||
@Resource
|
@Resource
|
||||||
private RedisUtil redisUtil;
|
private RedisUtil redisUtil;
|
||||||
|
|
||||||
@Resource@Value("${zn.robot_position_cache_time:600}")
|
@Resource@Value("${zn.robot_position_cache_time:10}")
|
||||||
private Long robotPositionCacheTime;
|
private Long robotPositionCacheTime;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@SystemRateLimiter(time = 1, count = 20, keyArg = "updateRobotCommonStatus",message = "机器人上报车辆其他信息")
|
||||||
public void updateRobotCommonStatus(RobotGenericsDataDTO robotStatusData) {
|
public void updateRobotCommonStatus(RobotGenericsDataDTO robotStatusData) {
|
||||||
doUpdateRobotCommonStatus(robotStatusData);
|
doUpdateRobotCommonStatus(robotStatusData);
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDTO;
|
|||||||
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataErrorDTO;
|
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataErrorDTO;
|
||||||
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO;
|
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO;
|
||||||
import cn.iocoder.yudao.module.system.api.robot.vo.RobotInformationVO;
|
import cn.iocoder.yudao.module.system.api.robot.vo.RobotInformationVO;
|
||||||
|
import cn.iocoder.yudao.module.system.config.ratelimiter.SystemRateLimiter;
|
||||||
import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant;
|
import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant;
|
||||||
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
|
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotWarnCodeMappingDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotWarnCodeMappingDO;
|
||||||
@ -45,7 +46,7 @@ public class RobotStatusApiImpl implements RobotStatusApi {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private RobotInformationService robotInformationService;
|
private RobotInformationService robotInformationService;
|
||||||
|
|
||||||
@Value("${zn.robot_position_cache_time:600}")
|
@Value("${zn.robot_position_cache_time:10}")
|
||||||
private Long robotPositionCacheTime;
|
private Long robotPositionCacheTime;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
@ -64,10 +65,9 @@ public class RobotStatusApiImpl implements RobotStatusApi {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@SystemRateLimiter(time = 1, count = 150, keyArg = "robotStatusUpdate",message = "机器人上报点位超过限流")
|
||||||
public void robotStatusUpdate(RobotPoseStatusDTO robotStatusDataDTO) {
|
public void robotStatusUpdate(RobotPoseStatusDTO robotStatusDataDTO) {
|
||||||
taskExecutor.execute(()->{
|
|
||||||
updateRobotPosed(robotStatusDataDTO);
|
updateRobotPosed(robotStatusDataDTO);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,7 +92,6 @@ public class RobotStatusApiImpl implements RobotStatusApi {
|
|||||||
}
|
}
|
||||||
robotStatusDataPoseDTO.setRobotNo(robotNo);
|
robotStatusDataPoseDTO.setRobotNo(robotNo);
|
||||||
redisUtil.set(pose2dKey, JSON.toJSONString(robotStatusDataPoseDTO), robotPositionCacheTime);
|
redisUtil.set(pose2dKey, JSON.toJSONString(robotStatusDataPoseDTO), robotPositionCacheTime);
|
||||||
pathPlanningApi.synchronousLineObject(robotStatusDataPoseDTO, PathPlanningTopicConstant.AGV_POSE);
|
|
||||||
|
|
||||||
//机器人身上是否有货
|
//机器人身上是否有货
|
||||||
String taskStatusKey = RobotTaskChcheConstant.ROBOT_TASK_STATUS + robotStatusDataDTO.getMac();
|
String taskStatusKey = RobotTaskChcheConstant.ROBOT_TASK_STATUS + robotStatusDataDTO.getMac();
|
||||||
@ -110,5 +109,12 @@ public class RobotStatusApiImpl implements RobotStatusApi {
|
|||||||
// 合并请求 - 这里接受到的数据都丢给 RequestProcessor - 再整合数据通过WebSocket丢给前端
|
// 合并请求 - 这里接受到的数据都丢给 RequestProcessor - 再整合数据通过WebSocket丢给前端
|
||||||
processor.handleRequest(robotStatusDataPoseDTO.getFloor() + "_" + robotStatusDataPoseDTO.getArea(),
|
processor.handleRequest(robotStatusDataPoseDTO.getFloor() + "_" + robotStatusDataPoseDTO.getArea(),
|
||||||
robotStatusDataDTO.getMac(), JSONUtil.toJsonStr(robotInformationVO));
|
robotStatusDataDTO.getMac(), JSONUtil.toJsonStr(robotInformationVO));
|
||||||
|
sendToPP(robotStatusDataPoseDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendToPP(RobotStatusDataPoseDTO robotStatusDataPoseDTO) {
|
||||||
|
taskExecutor.execute(()->{
|
||||||
|
pathPlanningApi.synchronousLineObject(robotStatusDataPoseDTO, PathPlanningTopicConstant.AGV_POSE);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,85 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.config.aop;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.iocoder.yudao.module.system.config.ratelimiter.SystemRateLimiter;
|
||||||
|
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.aspectj.lang.JoinPoint;
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Around;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.annotation.Before;
|
||||||
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拦截声明了 {@link SystemRateLimiter} 注解的方法,实现限流操作
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class SystemRateLimiterAspect {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(SystemRateLimiterAspect.class);
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RedisUtil redisUtil;
|
||||||
|
|
||||||
|
@Value("${zn.open_rate_limiter:false}")
|
||||||
|
private Boolean openRateLimiter;
|
||||||
|
|
||||||
|
@Pointcut("@annotation(cn.iocoder.yudao.module.system.config.ratelimiter.SystemRateLimiter)")
|
||||||
|
public void serviceLimit() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Around("serviceLimit()")
|
||||||
|
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||||
|
if (!openRateLimiter) {
|
||||||
|
return joinPoint.proceed();
|
||||||
|
}
|
||||||
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||||
|
Method method = signature.getMethod();
|
||||||
|
SystemRateLimiter systemRateLimiter = method.getAnnotation(SystemRateLimiter.class);
|
||||||
|
String key = systemRateLimiter.keyArg();
|
||||||
|
int time = systemRateLimiter.time();
|
||||||
|
// 获取redis的value
|
||||||
|
Integer maxTimes = null;
|
||||||
|
Object value = redisUtil.get(key);
|
||||||
|
if (value != null) {
|
||||||
|
maxTimes = (Integer) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object obj = null;
|
||||||
|
|
||||||
|
if (maxTimes == null) {
|
||||||
|
// 如果redis中没有该ip对应的时间则表示第一次调用,保存key到redis
|
||||||
|
redisUtil.set(key, 1, time);
|
||||||
|
//这个方法用于执行原来的方法或继续原来的控制流程。
|
||||||
|
obj = joinPoint.proceed();
|
||||||
|
} else if (maxTimes < systemRateLimiter.count()) {
|
||||||
|
// 如果redis中的时间比注解上的时间小则表示可以允许访问,这是修改redis的value时间
|
||||||
|
redisUtil.set(key, maxTimes + 1, time);
|
||||||
|
//这个方法用于执行原来的方法或继续原来的控制流程。
|
||||||
|
obj = joinPoint.proceed();
|
||||||
|
} else {
|
||||||
|
// 请求过于频繁
|
||||||
|
logger.info("请求过于频繁 :{}", key);
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.config.ratelimiter;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 限流注解
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Target({ElementType.METHOD})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface SystemRateLimiter {
|
||||||
|
/**
|
||||||
|
* 限流的时间,默认为 1 秒
|
||||||
|
*/
|
||||||
|
int time() default 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 限流次数
|
||||||
|
*/
|
||||||
|
int count() default 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提示信息,请求过快的提示
|
||||||
|
*
|
||||||
|
* @see GlobalErrorCodeConstants#TOO_MANY_REQUESTS
|
||||||
|
*/
|
||||||
|
String message() default ""; // 为空时,使用 TOO_MANY_REQUESTS 错误提示
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用的 Key 参数
|
||||||
|
*/
|
||||||
|
String keyArg() default "";
|
||||||
|
}
|
@ -240,4 +240,5 @@ zn:
|
|||||||
robot_config: #机器人取放货默认配置
|
robot_config: #机器人取放货默认配置
|
||||||
offset_height: 0.1 #叉起货需要在原来高度基础上偏移的高度
|
offset_height: 0.1 #叉起货需要在原来高度基础上偏移的高度
|
||||||
default_tray_height: 1.1 #默认每层高度
|
default_tray_height: 1.1 #默认每层高度
|
||||||
|
open_rate_limiter: true #是否开启限流
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user