@前端
最近開發遇到的一個問題是關於日誌打印。日誌很是重要,經過查看日誌,咱們能夠快速排查問題。
咱們項目的整個系統內網關處作了攔截,可以看到前端傳過來的日誌,可是內部服務間調用,服務間的入參與出參看不到;還有,一些重要的方法若是要看到入參和出參,只能一個個去寫log方法。
這種重複的工做很是適合使用切面來寫一些小工具。下面是我寫的小工具,下面方法幾乎是搬運一位老哥寫的博客,老哥的博客找不見了,sorry。app
/** * @Description 打印參數 * @Author lkb * @CreateDate: 2021/3/25 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface MethodLog { }
/** * @Description * @Author lkb * @CreateDate: 2021/3/25 */ @Aspect @Component @Slf4j public class MethodLogAspect { @Pointcut("@annotation(com.....annotion.MethodLog)") public void pointCut(){} @Around(value = "pointCut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable{ try{ MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); MethodLog annotation = method.getAnnotation(MethodLog.class); if (Objects.isNull(annotation)){ try { return joinPoint.proceed(); } catch (Throwable throwable) { log.error("method proceed fail. e = {}", throwable.getMessage(), throwable); throw throwable; } }else{ String methodName = method.getDeclaringClass().getSimpleName() + "." + method.getName(); log.info("methodName: "+methodName); Object[] args = joinPoint.getArgs(); log.info("param: " + JsonUtil.toJSON(args)); Instant start = Instant.now(); log.info("method start. methodName = {}", methodName); Object result = null; try { // 這裏的result記得return result = joinPoint.proceed(); } catch (Throwable throwable) { log.error("method proceed fail. e = {}", throwable.getMessage(), throwable); throw throwable; } log.info("method end. methodName = {}, cost = {}", methodName, ChronoUnit.MILLIS.between(start, Instant.now())); return result; } }catch (Exception e){ log.error("MethodLogAspect around fail. e= {}", e.getMessage(), e); throw e; } } }
遇到的第二個問題是,
在一個調用中,須要屢次調用外部系統的服務,原本應該使用MQ去解耦,可是由於多方面緣由只能維持現狀(咱們服務屢次調用外部系統的服務)。這樣致使整個請求特別慢,上線多臺設備的時候可能須要十幾二十秒。
與其餘兩個系統的交互互不影響,相互獨立。所以,我想到使用任務切片的方式來加快執行速度。
下面是我寫的任務切片小工具。工具
/** * @Description * @Author lkb * @CreateDate: 2021/3/26 */ @Data public class AsynTaskDTO<T, R> { public T param; public Function<T, R> function; public R resultData; public Boolean result; public String key; public AsynTaskDTO(Function<T,R> function, T param){ this.function = function; this.param = param; this.result = false; this.key = String.valueOf(param.hashCode()); } }
/** * @Description * @Author lkb * @CreateDate: 2021/3/26 */ @Slf4j @Getter public class AsynTaskUtil { private static final ForkJoinPool ASYNC_IO_POOL = new ForkJoinPool((Runtime.getRuntime().availableProcessors() << 1) + 1); private List<AsynTaskDTO> taskDTOS; public AsynTaskUtil(List<AsynTaskDTO> taskDTOS){ this.taskDTOS = taskDTOS; } public boolean doTask(){ CompletableFuture[] futures = taskDTOS.stream().map(task -> CompletableFuture.runAsync(() -> { try{ task.setResultData(task.getFunction().apply(task.getParam())); task.setResult(true); }catch (Exception e){ log.error("AsynTaskUtil doTask fail. e = {}" + e.getMessage(), e); task.setResult(false); } }, ASYNC_IO_POOL)).toArray(CompletableFuture[]::new); CompletableFuture.allOf(futures).join(); boolean f = taskDTOS.stream().anyMatch(t -> Objects.equals(false, t.getResult())); return !f; } }