背景
隨着公司代碼的迭代,有一些垃圾代碼邏輯冗餘在項目中,導致消耗了資源又不好維護。爲了保險,需要在線上統計代碼使用的頻率,剔除無用代碼。
描述
方法便可分爲如下幾種:
- 對於確定沒用的代碼,可以先註釋掉,並替換爲
error
日誌,保證遇到問題及時發現。 - 對疑似無用代碼,可以使用統計方法調用次數,運行一段時間,判斷去留。
設計
第一種方法就是,註釋代碼添加日誌,所以我們着重描述第二種情況:
使用 spring aop
進行攔截,注意只能攔截被 ioc
管理的對象
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CountInvokeTimes {
}
@Aspect
@Slf4j
@Component
public class CountInvokedTimesAspect {
private final RedisUtils redisUtil;
public CountInvokedTimesAspect(RedisUtils redisUtil) {
this.redisUtil = redisUtil;
}
@Pointcut("@within(com.tao.annotation.CountInvokeTimes) || @annotation(com.tao.annotation.CountInvokeTimes)")
public void countInvokeTimes() {
}
@Around(value = "countInvokeTimes()")
public Object doAround(ProceedingJoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
Class<?>[] argTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
argTypes[i] = args[i].getClass();
}
try {
String methodName = joinPoint.getSignature().getName();
Method method = joinPoint.getTarget().getClass().getMethod(methodName, argTypes);
Class<?> aClass = joinPoint.getTarget().getClass();
String className = aClass.getName();
boolean isClassAnnotationPresent = aClass.isAnnotationPresent(CountInvokeTimes.class);
boolean isMethodAnnotationPresent = method.isAnnotationPresent(CountInvokeTimes.class);
if (isClassAnnotationPresent || isMethodAnnotationPresent) {
// 此處也可以發送mq消息給統計服務
redisUtil.getRedisTemplate().opsForZSet().incrementScore(RedisConstant.METHOD_STATISTICS, className + "." + methodName, 1);
}
} catch (Exception e) {
log.error("CountInvokedTimesAspect error", e);
}
Object object = null;
try {
object = joinPoint.proceed();
} catch (Throwable throwable) {
log.error("CountInvokedTimesAspect error", throwable);
}
return object;
}
}
@RequestMapping("/getMethodStatistics")
public String getMethodStatistics() {
Set<ZSetOperations.TypedTuple<String>> typedTuples = redisUtils.getRedisTemplate().opsForZSet().rangeWithScores(RedisConstant.METHOD_STATISTICS, 0, -1);
return JSON.toJSONString(typedTuples);
}