说明:1、实现api预警切点切入api接口获取api记录信息,并远程调用预警服务执行cru操作
This commit is contained in:
parent
a63615cd12
commit
60f76ee94a
|
|
@ -5,10 +5,14 @@ import com.ruoyi.common.core.domain.R;
|
||||||
import com.xjs.business.warning.domain.ApiRecord;
|
import com.xjs.business.warning.domain.ApiRecord;
|
||||||
import com.xjs.business.warning.factory.RemoteWarningCRUDFactory;
|
import com.xjs.business.warning.factory.RemoteWarningCRUDFactory;
|
||||||
import org.springframework.cloud.openfeign.FeignClient;
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.cloud.openfeign.SpringQueryMap;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author xiejs
|
* @author xiejs
|
||||||
* @desc 远程rpc调用预警服务crud接口
|
* @desc 远程rpc调用预警服务crud接口
|
||||||
|
|
@ -19,12 +23,17 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||||
fallbackFactory = RemoteWarningCRUDFactory.class)
|
fallbackFactory = RemoteWarningCRUDFactory.class)
|
||||||
public interface RemoteWarningCRUDFeign {
|
public interface RemoteWarningCRUDFeign {
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping("apiwarning")
|
||||||
public R<ApiRecord> saveApiRecord(@RequestBody ApiRecord apiRecord);
|
public R<ApiRecord> saveApiRecord(@RequestBody ApiRecord apiRecord);
|
||||||
|
|
||||||
|
|
||||||
@PutMapping
|
@PutMapping("apiwarning")
|
||||||
public R<ApiRecord> updateApiRecord(@RequestBody ApiRecord apiRecord);
|
public R<ApiRecord> updateApiRecord(@RequestBody ApiRecord apiRecord);
|
||||||
|
|
||||||
|
@GetMapping("apiwarning")
|
||||||
|
R<List<ApiRecord>> selectApiRecordList(@SpringQueryMap ApiRecord apiRecord) ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,11 @@ public class ApiRecord implements Serializable {
|
||||||
/** api地址 */
|
/** api地址 */
|
||||||
private String apiUrl;
|
private String apiUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求耗费时间
|
||||||
|
*/
|
||||||
|
private Integer requestTime;
|
||||||
|
|
||||||
/** api总请求次数 */
|
/** api总请求次数 */
|
||||||
private Long totalCount;
|
private Long totalCount;
|
||||||
|
|
||||||
|
|
@ -86,4 +91,12 @@ public class ApiRecord implements Serializable {
|
||||||
public void setUpdateTime(Date updateTime) {
|
public void setUpdateTime(Date updateTime) {
|
||||||
this.updateTime = updateTime;
|
this.updateTime = updateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getRequestTime() {
|
||||||
|
return requestTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestTime(Integer requestTime) {
|
||||||
|
this.requestTime = requestTime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.cloud.openfeign.FallbackFactory;
|
import org.springframework.cloud.openfeign.FallbackFactory;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author xiejs
|
* @author xiejs
|
||||||
* @desc 调用预警服务降级处理
|
* @desc 调用预警服务降级处理
|
||||||
|
|
@ -23,13 +25,19 @@ public class RemoteWarningCRUDFactory implements FallbackFactory<RemoteWarningCR
|
||||||
return new RemoteWarningCRUDFeign() {
|
return new RemoteWarningCRUDFeign() {
|
||||||
@Override
|
@Override
|
||||||
public R<ApiRecord> saveApiRecord(ApiRecord apiRecord) {
|
public R<ApiRecord> saveApiRecord(ApiRecord apiRecord) {
|
||||||
log.error("调用预警服务添加接口失败----"+apiRecord.getApiName());
|
log.error("调用预警服务添加接口失败,执行降级处理----"+apiRecord.getApiName());
|
||||||
return R.fail();
|
return R.fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R<ApiRecord> updateApiRecord(ApiRecord apiRecord) {
|
public R<ApiRecord> updateApiRecord(ApiRecord apiRecord) {
|
||||||
log.error("调用预警服务修改接口失败----"+apiRecord.getApiName());
|
log.error("调用预警服务修改接口失败,执行降级处理----"+apiRecord.getApiName());
|
||||||
|
return R.fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R<List<ApiRecord>> selectApiRecordList(ApiRecord apiRecord) {
|
||||||
|
log.error("调用预警服务查询接口失败,执行降级处理----"+apiRecord.getApiName());
|
||||||
return R.fail();
|
return R.fail();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,26 @@
|
||||||
package com.xjs.common.aop;
|
package com.xjs.common.aop;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import com.ruoyi.common.core.domain.R;
|
||||||
import com.xjs.business.warning.RemoteWarningCRUDFeign;
|
import com.xjs.business.warning.RemoteWarningCRUDFeign;
|
||||||
|
import com.xjs.business.warning.domain.ApiRecord;
|
||||||
import com.xjs.enums.StatusEnum;
|
import com.xjs.enums.StatusEnum;
|
||||||
import com.xjs.log.mapper.ApiLogMapper;
|
import com.xjs.log.mapper.ApiLogMapper;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import org.aspectj.lang.JoinPoint;
|
import org.aspectj.lang.JoinPoint;
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.Signature;
|
||||||
import org.aspectj.lang.annotation.*;
|
import org.aspectj.lang.annotation.*;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -51,17 +58,8 @@ public class ApiLogAspect {
|
||||||
LocalDateTime localDateTime2 = DateUtil.date().toLocalDateTime();
|
LocalDateTime localDateTime2 = DateUtil.date().toLocalDateTime();
|
||||||
long between = ChronoUnit.MILLIS.between(localDateTime1, localDateTime2);
|
long between = ChronoUnit.MILLIS.between(localDateTime1, localDateTime2);
|
||||||
log.info("调用接口耗费时间:{}ms", between);
|
log.info("调用接口耗费时间:{}ms", between);
|
||||||
|
|
||||||
//执行预警切入逻辑
|
//执行预警切入逻辑
|
||||||
|
warning(between, joinPoint);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
@ -71,7 +69,6 @@ public class ApiLogAspect {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理完请求后执行
|
* 处理完请求后执行
|
||||||
*
|
|
||||||
* @param joinPoint 切点
|
* @param joinPoint 切点
|
||||||
*/
|
*/
|
||||||
@AfterReturning(pointcut = "@annotation(apiLog)", returning = "jsonResult")
|
@AfterReturning(pointcut = "@annotation(apiLog)", returning = "jsonResult")
|
||||||
|
|
@ -80,6 +77,12 @@ public class ApiLogAspect {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异常切点
|
||||||
|
* @param joinPoint 连接点
|
||||||
|
* @param apiLog 自定义注解
|
||||||
|
* @param e 抛出的异常
|
||||||
|
*/
|
||||||
@AfterThrowing(value = "@annotation(apiLog)", throwing = "e")
|
@AfterThrowing(value = "@annotation(apiLog)", throwing = "e")
|
||||||
public void doAfterThrowing(JoinPoint joinPoint, ApiLog apiLog, Exception e) {
|
public void doAfterThrowing(JoinPoint joinPoint, ApiLog apiLog, Exception e) {
|
||||||
handleApiLog(joinPoint, apiLog, e, null);
|
handleApiLog(joinPoint, apiLog, e, null);
|
||||||
|
|
@ -108,4 +111,51 @@ public class ApiLogAspect {
|
||||||
apiLogMapper.insert(entity);
|
apiLogMapper.insert(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预警切入
|
||||||
|
* @param between api接口调用时间
|
||||||
|
* @param joinPoint aop连接对象
|
||||||
|
*/
|
||||||
|
private void warning(long between, ProceedingJoinPoint joinPoint) {
|
||||||
|
//获取目标类名及方法名
|
||||||
|
Signature signature = joinPoint.getSignature();
|
||||||
|
String method = signature.getName();
|
||||||
|
Class aclass = signature.getDeclaringType();
|
||||||
|
Method[] methods = aclass.getMethods();
|
||||||
|
//根据目标的方法名判断当前方法
|
||||||
|
for (Method thisMethod : methods) {
|
||||||
|
if (method.equals(thisMethod.getName())) {
|
||||||
|
//拿到当前方法的注解判断是否为apiLog注解
|
||||||
|
Annotation[] declaredAnnotations = thisMethod.getDeclaredAnnotations();
|
||||||
|
for (Annotation annotation : declaredAnnotations) {
|
||||||
|
if (annotation instanceof ApiLog) {
|
||||||
|
String name = ((ApiLog) annotation).name();
|
||||||
|
String url = ((ApiLog) annotation).url();
|
||||||
|
//根据拿到的url和name查询数据库是否存在,存在则count+1,不存在则add
|
||||||
|
ApiRecord apiRecord = new ApiRecord();
|
||||||
|
apiRecord.setApiName(name);
|
||||||
|
apiRecord.setApiUrl(url);
|
||||||
|
apiRecord.setRequestTime((int) between);
|
||||||
|
R<List<ApiRecord>> listR = remoteWarningCRUDFeign.selectApiRecordList(apiRecord);
|
||||||
|
if (listR.getCode() == R.SUCCESS) {
|
||||||
|
List<ApiRecord> data = listR.getData();
|
||||||
|
if (CollUtil.isEmpty(data)) {
|
||||||
|
//设置初始请求次数
|
||||||
|
apiRecord.setTotalCount(1L);
|
||||||
|
remoteWarningCRUDFeign.saveApiRecord(apiRecord);
|
||||||
|
}else {
|
||||||
|
ApiRecord haveApiRecord = data.get(0);
|
||||||
|
haveApiRecord.setRequestTime((int) between);
|
||||||
|
haveApiRecord.setTotalCount(haveApiRecord.getTotalCount()+1L);
|
||||||
|
remoteWarningCRUDFeign.updateApiRecord(haveApiRecord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ import com.xjs.service.ApiWarningService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author xiejs
|
* @author xiejs
|
||||||
* @desc api预警控制器
|
* @desc api预警控制器
|
||||||
|
|
@ -21,6 +23,7 @@ public class ApiWarningController extends BaseController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存 apiRecord
|
* 保存 apiRecord
|
||||||
|
*
|
||||||
* @param apiRecord api记录
|
* @param apiRecord api记录
|
||||||
* @return apiRecord
|
* @return apiRecord
|
||||||
*/
|
*/
|
||||||
|
|
@ -29,9 +32,21 @@ public class ApiWarningController extends BaseController {
|
||||||
return apiWarningService.saveApiRecord(apiRecord) ? R.ok() : R.fail();
|
return apiWarningService.saveApiRecord(apiRecord) ? R.ok() : R.fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改
|
||||||
|
*
|
||||||
|
* @param apiRecord api记录
|
||||||
|
* @return ApiRecord
|
||||||
|
*/
|
||||||
@PutMapping
|
@PutMapping
|
||||||
public R<ApiRecord> updateApiRecord(@RequestBody ApiRecord apiRecord) {
|
public R<ApiRecord> updateApiRecord(@RequestBody ApiRecord apiRecord) {
|
||||||
return apiWarningService.updateApiRecord(apiRecord) ? R.ok() : R.fail();
|
return apiWarningService.updateApiRecord(apiRecord) ? R.ok() : R.fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public R<List<ApiRecord>> selectApiRecordList(ApiRecord apiRecord) {
|
||||||
|
List<ApiRecord> apiRecords = apiWarningService.selectApiRecordList(apiRecord);
|
||||||
|
return R.ok(apiRecords);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ package com.xjs.service;
|
||||||
|
|
||||||
import com.xjs.domain.ApiRecord;
|
import com.xjs.domain.ApiRecord;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author xiejs
|
* @author xiejs
|
||||||
* @desc
|
* @desc
|
||||||
|
|
@ -23,4 +25,11 @@ public interface ApiWarningService {
|
||||||
* @return apiRecord
|
* @return apiRecord
|
||||||
*/
|
*/
|
||||||
boolean updateApiRecord(ApiRecord apiRecord);
|
boolean updateApiRecord(ApiRecord apiRecord);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 apiurl和name查询
|
||||||
|
* @param apiRecord
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<ApiRecord> selectApiRecordList(ApiRecord apiRecord);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import com.xjs.service.ApiWarningService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -41,5 +42,12 @@ public class ApiWarningServiceImpl implements ApiWarningService {
|
||||||
return name == 1;
|
return name == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ApiRecord> selectApiRecordList(ApiRecord apiRecord) {
|
||||||
|
return apiRecordMapper
|
||||||
|
.selectList(new QueryWrapper<ApiRecord>().eq("api_name",apiRecord.getApiName())
|
||||||
|
.eq("api_name",apiRecord.getApiName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue