最近项目中有一个需求,在每一个接口的入口处都要打日志,并且打出来的日志是要xml格式的报文。刚接到这个需求的时候,也没多想,就直接使用spring的aop实现了这个需求,但在后面的性能测试中,却遇到了一个致命的问题:由于我们接口之间是使用Bean来进行消息传递的,如果每个接口的入口都要打日志,并且要是xml格式的,那么我们都需要进行一次xml转换,就是因为这一步转换,将我们的性能大大的降低,打个比方说,我们解析一个PNR的时间为100ms,但每个接口都转xml的时间总和为150ms,也就是说,打日志花的时间比我们整个流程走下来花的时间还要多,这肯定是不合理的,思来想去,最后找到了一个解决方案。
方案如下:
我们可以将打日志的工作,都抽取出来,做成异步的任务调用,只要需要打日志的地方,我们就将这个任务放到任务线程池里面去,让这个线程池来专门实现异步打日志的功能,这样主流程就完全不用理会存库和打日志等等这些和业务流程毫无关系的事情,专心的做自己该做的事情。
实现如下:
1、配置打日志的任务池
<task:annotation-driven />
<task:executor id="logExecutor" pool-size="5-10"
queue-capacity="20" keep-alive="2000" rejection-policy="CALLER_RUNS"></task:executor>
说明:logExecutor任务池的名字前缀,线程会在logExecutor的基础上依次递增,例如logExecutor-1,logExecutor-2
pool-size:任务池的大小,可以是固定大小,也可以是可变大小,具体的设置可以根据项目的需求来。
queue-capacity:队列大小,当任务过多时,会在队列里面排队。
keep-alive:当没有任务处理时,线程的存活时间,避免频繁的创建线程。
rejection-policy:拒绝策略,当队列满了,但是还是有任务源源不断的提交过来的时候,会启用拒绝策略,取值有4个,分别是ABORT,CALLER_RUNS,DISCARD,DISCARD_OLDEST
2、配置日志的aop
<!-- 配置打印日志切面 -->
<aop:config>
<aop:pointcut id="myLogAspect"
expression="
execution(* com.chhliu.core.service.*.process*(..)) ||
execution(* com.chhliu.service.*.transform*(..)) ||
execution(* com.chhliu.channel.output.*.send*(..))" />
<aop:aspect id="logProxy" ref="logProxy">
<aop:before method="logStart" pointcut-ref="myLogAspect" />
</aop:aspect>
</aop:config>
3、异步打日志的实现
@Component("logProxy")
public class LogProxy {
@Async("logExecutor")
public void logStart(JoinPoint jp){
}
注:spring异步调用任务的实现,加了@Async注解之后,每次执行这个任务的时候,就会将这个任务直接丢到任务池中进行处理,主流程会直接跳过这个方法
4、效果如下
主流程的线程如下:
![78ecd0d25edc1590da2560b33336e9e4.png](https://img-blog.csdnimg.cn/img_convert/78ecd0d25edc1590da2560b33336e9e4.png)
异步打日志的线程如下:
![97698151486e6a763b203ce19327f7ac.png](https://img-blog.csdnimg.cn/img_convert/97698151486e6a763b203ce19327f7ac.png)
![a47dfcccbc2988602d0761abddc049c9.png](https://img-blog.csdnimg.cn/img_convert/a47dfcccbc2988602d0761abddc049c9.png)
异步存库的线程如下:
![590448c33dbb410480fca1fe9d637186.png](https://img-blog.csdnimg.cn/img_convert/590448c33dbb410480fca1fe9d637186.png)
![8d421678330e95ebc3c3afa9e2d7216a.png](https://img-blog.csdnimg.cn/img_convert/8d421678330e95ebc3c3afa9e2d7216a.png)
这样大大的提高了我们程序的效率,同时让业务流程更加的单一和清晰。