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,異步處理。
希望能給大家一些啟發。