日志异步落库

本文探讨了在高并发场景下,如何实现日志异步落库以保证接口性能。介绍了三种方案:基于log4j的异步appender(存在数据丢失可能)、增量消费log4j日志(数据延迟较高)和基于内存文件队列的异步日志消费(兼顾数据完整性和延迟)。最后推荐了自研的内存文件队列方案,它能有效防止数据丢失,且对接口ops影响较小。
摘要由CSDN通过智能技术生成

在互联网设计架构过程中,日志异步落库,俨然已经是高并发环节中不可缺少的一环。为什么说是高并发环节中不可缺少的呢? 原因在于,如果直接用mq进行日志落库的时候,低并发下,生产端生产数据,然后由消费端异步落库,是没有什么问题的,而且性能也都是异常的好,估计tp99应该都在1ms以内。

但是一旦并发增长起来,慢慢的你就发现生产端的tp99一直在增长,从1ms,变为2ms,4ms,直至send timeout。尤其在大促的时候,我司的系统就经历过这个情况,当时mq的发送耗时超过200ms,甚至一度有不少timeout产生。

考虑到这种情况在高并发的情况下才出现,所以今天我们就来探索更加可靠的方法来进行异步日志落库,保证所使用的方式不会因为过高的并发而出现接口ops持续下降甚至到不可用的情况。

方案一: 基于log4j的异步appender实现

此种方案,依赖于log4j。在log4j的异步appender中,通过mq进行生产消费入库。相当于在接口和mq之间建立了一个缓冲区,使得接口和mq的依赖分离,从而不让mq的操作影响接口的ops。

此种方案由于使用了异步方式,且由于异步的discard policy策略,当大量数据过来,缓冲区满了之后,会抛弃部分数据。此种方案适用于能够容忍数据丢失的业务场景,不适用于对数据完整有严格要求的业务场景。

来看看具体的实现方式:

首先,我们需要自定义一个Appender,继承自log4j的AppenderSkeleton类,实现方式如下:

public class AsyncJmqAppender extends AppenderSkeleton {

    @Resource(name = "messageProducer")
    private MessageProducer messageProducer;

    @Override
    protected void append(LoggingEvent loggingEvent) {
        asyncPushMessage(loggingEvent.getMessage());
    }

    /**
     * 异步调用jmq输出日志
     * @param message
     */
    private void asyncPushMessage(Object message) {

        CompletableFuture.runAsync(() -> {

            Message messageConverted = (Message) message;

            try {
                messageProducer.send(messageConverted);
            } catch (JMQException e) {
                e.printStackTrace();
            }

        });
    }


    @Override
    public boolean requiresLayout() {
        return false;
    }

    @Override
    public void close() {

    }
}

然后在log4j.xml中,为此类进行配置:

<!--异步JMQ appender-->
<appender name="async_mq_appender" class="com.jd.limitbuy.common.util.AsyncJmqAppender">
    <!-- 设置File参数:日志输出文件名 -->
    <param name="File" value="D:/export/Instances/order/server1/logs/order.async.jmq" />
    <!-- 设置是否在重新启动服务时,在原有日志的基础添加新日志 -->
    <param name="Append" value="true" />
    <!-- 设置文件大小 -->
    <param name="MaxFileSize" value="10KB" />
    <!-- 设置文件备份 -->
    <param name="MaxBackupIndex" value="10000" />
    <!-- 设置输出文件项目和格式 -->
    <layo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值