你所不知道的日志异步落库
在互联网设计架构过程中日志异步落库俨然已经是高并发环节中不可缺少的一环。为什么说是高并发环节中不可缺少的呢 原因在于如果直接用mq进行日志落库的时候低并发下生产端生产数据然后由消费端异步落库是没有什么问题的而且性能也都是异常的好估计tp99应该都在1ms以内。但是一旦并发增长起来慢慢的你就发现生产端的tp99一直在增长从1ms变为2ms4ms直至send timeout。尤其在大促的时候我司的系统就经历过这个情况当时mq的发送耗时超过200ms甚至一度有不少timeout产生。考虑到这种情况在高并发的情况下才出现所以今天我们就来探索更加可靠的方法来进行异步日志落库保证所使用的方式不会因为过高的并发而出现接口ops持续下降甚至到不可用的情况。方案一 基于log4j的异步appender实现此种方案依赖于log4j。在log4j的异步appender中通过mq进行生产消费入库。相当于在接口和mq之间建立了一个缓冲区使得接口和mq的依赖分离从而不让mq的操作影响接口的ops。此种方案由于使用了异步方式且由于异步的discard policy策略当大量数据过来缓冲区满了之后会抛弃部分数据。此种方案适用于能够容忍数据丢失的业务场景不适用于对数据完整有严格要求的业务场景。来看看具体的实现方式首先我们需要自定义一个Appender继承自log4j的AppenderSkeleton类实现方式如下12345678910111213141516171819202122232425262728293031323334353637383940publicclassAsyncJmqAppender extends AppenderSkeleton {Resource(name messageProducer)privateMessageProducer messageProducer;Overrideprotectedvoidappend(LoggingEvent loggingEvent) {asyncPushMessage(loggingEvent.getMessage());}/*** 异步调用jmq输出日志* param message*/privatevoidasyncPushMessage(Object message) {CompletableFuture.runAsync(() - {Message messageConverted (Message) message;try{messageProducer.send(messageConverted);}catch(JMQException e) {e.printStackTrace();}});}Overridepublicboolean requiresLayout() {returnfalse;}Overridepublicvoidclose() {}}然后在log4j.xml中为此类进行配置123456789101112131415161718!--异步JMQ appender--appendernameasync_mq_appender classcom.jd.limitbuy.common.util.AsyncJmqAppender!-- 设置File参数日志输出文件名 --paramnameFile valueD:/export/Instances/order/server1/logs/order.async.jmq /!-- 设置是否在重新启动服务时在原有日志的基础添加新日志 --paramnameAppend valuetrue /!-- 设置文件大小 --paramnameMaxFileSize value10KB /!-- 设置文件备份 --paramnameMaxBackupIndex value10000 /!-- 设置输出文件项目和格式 --layoutclassorg.apache.log4j.PatternLayoutparamnameConversionPattern value%m%n //layout/appenderloggernameasync_mq_appender_loggerappender-refrefasync_mq_appender//logger最后就可以按照如下的方式进行正常使用了1privatestaticLogger logger LoggerFactory.getLogger(filelog_appender_logger);注意 此处需要注意log4j的一个性能问题。在log4j的conversionPattern中匹配符最好不要出现 C% L%通配符压测实践表明这两个通配符会导致log4j打日志的效率降低10倍。方案一很简便且剥离了接口直接依赖mq导致的性能问题。但是无法解决数据丢失的问题但是我们其实可以在本地搞个策略落盘来不及处理的数据可以大大的减少数据丢失的几率。但是很多的业务场景是需要数据不丢失的所以这就衍生出我们的另一套方案来。方案二增量消费log4j日志此种方式是开启worker在后台增量消费log4j的日志信息和接口完全脱离。此种方式相比方案一可以保证数据的不丢失且可以做到完全不影响接口的ops。但是此种方式由于是后台worker在后台启动进行扫描会导致落库的数据慢一些比如一分钟之后才落库完毕。所以适用于对落库数据实时性不高的场景。具体的实现步骤如下首先将需要进行增量消费的日志统一打到一个文件夹以天为单位每天生成一个带时间戳日志文件。由于log4j不支持直接带时间戳的日志文件生成所以这里需要引入log4j.extras组件然后配置log4j.xml如下​编辑之后在代码中的申明方式如下1privatestaticLogger businessLogger LoggerFactory.getLogger(file_rolling_logger);最后在需要记录日志的地方使用方式如下1businessLogger.error(JsonUtils.toJSONString(myMessage))这样就可以将日志打印到一个单独的文件中且按照日期每天生成一个。然后当日志文件生成完毕后我们就可以开启我们的worker进行增量消费了这里的增量消费方式我们选择RandomAccessFile这个类来进行由于其独特的位点读取方式可以使得我们非常方便的根据位点的位置来消费增量文件从而避免了逐行读取这种低效率的实现方式。注意为每个日志文件都单独创建了一个位点文件里面存储了对应的文件的位点读取信息。当worker扫描开始的时候会首先读取位点文件里面的位点信息然后找到相应的日志文件从位点信息位置开始进行消费。这就是整个增量消费worker的核心。具体代码实现如下(代码太长做了折叠) View Code此种方式由于worker扫描是每隔一段时间启动一次进行消费所以导致数据从产生到入库可能经历时间超过一分钟以上但是在一些对数据延迟要求比较高的业务场景比如库存扣减是不能容忍的所以这里我们就引申出第三种做法基于内存文件队列的异步日志消费。方案三基于内存文件队列的异步日志消费由于方案一和方案二都严重依赖log4j且方案本身都存在着要么丢数据要么入库时间长的缺点所以都并不是那么尽如人意。但是本方案的做法既解决了数据丢失的问题又解决了数据入库时间被拉长的尴尬所以是终极解决之道。而且在大促销过程中此种方式经历了实战检验可以大面积的推广使用。此方案中提到的内存文件队列是我司自研的一款基于RandomAccessFile和MappedByteBuffer实现的内存文件队列。队列核心使用了ArrayBlockingQueue并提供了produce方法进行数据入管道操作提供了consume方法进行数据出管道操作。而且后台有一个worker一直启动着每隔5ms或者遍历了100条数据之后就将数据落盘一次以防数据丢失。具体的设计就这么多感兴趣的可以根据我提供的信息自己实践一下。由于有此中间件的加持数据生产的时候只需要入压入管道然后消费端进行消费即可。未被消费的数据会进行落盘操作谨防数据丢失。当大促的时候大量数据涌来的时候管道满了的情况下会阻塞接口数据不会被抛弃。虽然可能会导致接口在那一瞬间无响应但是由于有落盘操作和消费操作此操作操控的是JVM堆外内存数据不受GC的影响所以不会出现操作暂停的情况为什么呢因为用了MappedByteBuffer此种阻塞并未影响到接口整体的ops。

相关新闻

番茄小说下载器完整指南:构建个人数字图书馆的终极方案

番茄小说下载器完整指南:构建个人数字图书馆的终极方案

番茄小说下载器完整指南:构建个人数字图书馆的终极方案 【免费下载链接】Tomato-Novel-Downloader 番茄小说下载器不精简版 项目地址: https://gitcode.com/gh_mirrors/to/Tomato-Novel-Downloader 你是否曾遇到过这样的情况:在番茄小说上找到一部…

2026/7/2 4:53:48阅读更多 →
Attention Sinks and Compression Valleys in LLMs are Two Sides of the Same Coin

Attention Sinks and Compression Valleys in LLMs are Two Sides of the Same Coin

paper: https://arxiv.org/pdf/2510.06477 ICLR 2026 一句话概括 这篇论文想说明:LLM 中的 attention sink 和 compression valley 不是两个孤立现象,而是同一个底层机制的两种表现,这个机制就是 residual stream 中某些 token,尤…

2026/7/2 4:53:48阅读更多 →
操作系统复习(一)

操作系统复习(一)

操作系统复习(一) 记录一下复习。 操作系统中的不确定性 程序运行结果的不确定性执行顺序的不确定性 操作系统的两个基本特征 并发执行资源共享 分时系统 分时系统(Time-Sharing System)是指:一台计算机同时连接多个终…

2026/7/2 4:53:48阅读更多 →
完整指南:使用macOS Catalina Patcher让老旧Mac焕发新生

完整指南:使用macOS Catalina Patcher让老旧Mac焕发新生

完整指南:使用macOS Catalina Patcher让老旧Mac焕发新生 【免费下载链接】macos-catalina-patcher macOS Catalina Patcher (http://dosdude1.com/catalina) 项目地址: https://gitcode.com/gh_mirrors/ma/macos-catalina-patcher macOS Catalina Patcher是一…

2026/7/2 6:18:57阅读更多 →
别再当盲盒用了!个微接口深度集成:把群聊碎语洗成 AI 一眼看懂的

别再当盲盒用了!个微接口深度集成:把群聊碎语洗成 AI 一眼看懂的

在搭建大模型本地知识库(RAG)或者做 AI 搜索优化(GEO)的时候,很多朋友都通过个微接口,把私聊、技术群里的海量客户反馈成功接到了自己的后台。但这之后,大家往往会遇到一个非常折磨人的大坑&…

2026/7/2 6:18:57阅读更多 →
拆解Qwen-AgentWorld:阿里原生世界建模,补齐智能体落地的环境交互短板

拆解Qwen-AgentWorld:阿里原生世界建模,补齐智能体落地的环境交互短板

当前AI行业落地重心已从通用对话大模型,转向可自主规划、环境交互、闭环执行的任务型智能体,现有开源方案普遍存在适配差、交互单一、部署调试成本高、插件稳定性弱等问题,制约了产业规模化落地。针对这些痛点,阿里通义千问开源推…

2026/7/2 6:18:57阅读更多 →
导师严选!高效论文写作全流程一键生成论文工具推荐(2026 最新)

导师严选!高效论文写作全流程一键生成论文工具推荐(2026 最新)

2026年论文写作全流程可拆解为文献调研→选题/开题→大纲/初稿→文献综述→降重/去AI味→润色/格式→查重/投稿七大环节,以下工具按环节精准匹配,兼顾中文适配、降重能力、去AI痕迹、学术合规四大核心需求,覆盖免费/付费、通用/垂直场景。一、…

2026/7/2 6:18:57阅读更多 →
上海定位视频公司选哪家不踩雷

上海定位视频公司选哪家不踩雷

一个老甲方的真实心路兄弟们,最近公司要做品牌升级,我负责找定位视频公司,前前后后接触了不下七八家。说实话,这行水真的很深,报价从几万到几百万都有,但最后拿到的片子,能真正把品牌核心讲明白…

2026/7/2 6:18:57阅读更多 →
5个你绝对不知道的明日方舟自动化技巧:MAA智能助手深度解析

5个你绝对不知道的明日方舟自动化技巧:MAA智能助手深度解析

5个你绝对不知道的明日方舟自动化技巧:MAA智能助手深度解析 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients. 项目地址: https:…

2026/7/2 6:13:57阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/7/1 4:42:14阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/7/1 5:19:01阅读更多 →
塞尔达传说旷野之息存档修改器:3分钟掌握海拉鲁世界自由定制技巧

塞尔达传说旷野之息存档修改器:3分钟掌握海拉鲁世界自由定制技巧

塞尔达传说旷野之息存档修改器:3分钟掌握海拉鲁世界自由定制技巧 【免费下载链接】BOTW-Save-Editor-GUI A Work in Progress Save Editor for BOTW 项目地址: https://gitcode.com/gh_mirrors/bo/BOTW-Save-Editor-GUI 想在《塞尔达传说:旷野之息…

2026/7/2 0:03:01阅读更多 →
告别 AccessKey:多云平台 CLI OAuth 免密认证完全指南

告别 AccessKey:多云平台 CLI OAuth 免密认证完全指南

在本地开发环境使用云厂商 CLI 时,传统的 AccessKey(AK)方式需要手动创建、下载和保管密钥,不仅繁琐,还存在泄漏风险。其实,主流云平台都已提供基于 OAuth 2.0 的免密认证方案,让开发者可以通过浏览器登录一次性完成授权,CLI 自动管理临时凭证的刷新,兼顾了便利与安全…

2026/7/2 0:03:01阅读更多 →
基于13DOF传感器与PIC32MZ的高精度嵌入式导航系统设计

基于13DOF传感器与PIC32MZ的高精度嵌入式导航系统设计

1. 项目背景与核心价值在嵌入式系统开发领域,高精度定位与导航一直是极具挑战性的技术方向。传统方案往往面临成本、精度和实时性难以兼顾的困境。这个项目通过13DOF(13自由度)传感器组合与PIC32MZ2048EFH100高性能MCU的协同工作,…

2026/7/2 0:03:01阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/2 0:33:58阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/2 1:32:11阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/2 1:50:13阅读更多 →