真实面经题目 · 原创解析
日志服务如何异步写入,避免影响主流程?
这题考异步化、背压和可靠性分级,回答要说明日志不阻塞主流程的同时不能无限丢失或无限占内存。
真实面经题目 · 原创解析
这题考异步化、背压和可靠性分级,回答要说明日志不阻塞主流程的同时不能无限丢失或无限占内存。
我会把日志写入拆成业务线程和后台日志线程。业务线程只做轻量字段采集和入队,不做慢格式化、磁盘 fsync 或网络发送;后台消费者批量格式化、压缩、刷盘或发送到日志平台。队列必须有界,并按日志等级设计队列满策略:调试日志可采样或丢弃,错误日志尽量保留,审计日志可能要同步落盘或使用可靠消息。还要处理异常兜底、优雅关闭 flush、磁盘满、日志切割和监控告警。
业务线程不应在请求关键路径里做重格式化、同步磁盘写或网络发送。它只构造结构化日志事件,带上 traceId、时间、级别和必要上下文,然后快速写入缓冲队列。
日志线程从队列批量取数据,统一格式化、编码、压缩、刷盘或发送。批量写能减少锁竞争、系统调用和磁盘随机写,异步发送能降低对业务延迟的影响。
队列必须有容量上限。队列满时可以阻塞、丢弃低级别日志、采样、降级到本地文件或触发告警,具体取决于日志重要性和业务能否接受延迟。
普通 debug/info 日志可以损失一部分,错误日志要尽量保留,审计、交易、合规日志通常要更高可靠性,可能需要同步确认、可靠队列、落盘 WAL 或双写校验。
进程退出、崩溃、磁盘满、日志平台不可用和网络抖动都要有策略。正常退出要 flush 并设置超时;异常时要保留兜底文件、丢弃计数和告警,避免日志系统反过来拖垮业务。
不能无界扩容。要按级别选择阻塞、丢弃低级别、采样、降级本地写或告警;核心是明确业务延迟和日志丢失之间的取舍。
普通异步内存队列在进程崩溃时可能丢。关键日志需要更高可靠性,例如同步落盘、WAL、可靠消息或退出前 flush。
结构化字段延迟格式化、批量写、减少锁竞争、预分配缓冲、异步发送、采样低价值日志,并避免在日志参数中执行昂贵计算。
看队列长度、入队失败数、丢弃数、消费延迟、flush 耗时、磁盘剩余、发送失败和日志平台响应时间。