Dubbo中AccessLogFilter实现了记录请求日志的功能,在业务系统中,我们也可以借鉴Dubbo的实现原理,实现相应的业务功能。
Dubbo中AccessLogFilter的实现原理:利用ConcurrentMap作为请求记录的本地存储结构,key为日志文件,value为请求记录;利用ScheduledExecutorService.scheduleWithFixedDelay间隔执行任务,将请求记录写入日志文件中;每次请求,都将请求记录添加到ConcurrentMap中。关键性代码如下:
private final ConcurrentMap<String, Set<String>> logQueue = new ConcurrentHashMap<String, Set<String>>(); private final ScheduledExecutorService logScheduled = Executors.newScheduledThreadPool(2, new NamedThreadFactory("Dubbo-Access-Log", true)); private volatile ScheduledFuture<?> logFuture = null; private void init() { if (logFuture == null) { synchronized (logScheduled) { if (logFuture == null) { logFuture = logScheduled.scheduleWithFixedDelay(new LogTask(), LOG_OUTPUT_INTERVAL, LOG_OUTPUT_INTERVAL, TimeUnit.MILLISECONDS); } } } } private void log(String accesslog, String logmessage) { init(); Set<String> logSet = logQueue.get(accesslog); if (logSet == null) { logQueue.putIfAbsent(accesslog, new ConcurrentHashSet<String>()); logSet = logQueue.get(accesslog); } if (logSet.size() < LOG_MAX_BUFFER) { logSet.add(logmessage); } }
假如我们需要记录业务系统的操作日志,也可以借鉴Duboo的这种实现方式(数据同步记录到ConcurrentMap中,定时任务异步执行更新操作)。当然还可以使用一些消息中间件RocketMQ,或者Disruptor,异步处理。
希望能给大家一些启发。