聊聊reactor-logback的AsyncAppender
序
本文主要研究一下reactor-logback的AsyncAppender
AsyncAppender
reactor-logback/src/main/java/reactor/logback/AsyncAppender.java
public class AsyncAppender extends ContextAwareBaseimplements Appender<ILoggingEvent>, AppenderAttachable<ILoggingEvent>,CoreSubscriber<ILoggingEvent> {private final AppenderAttachableImpl<ILoggingEvent> aai =new AppenderAttachableImpl<ILoggingEvent>();private final FilterAttachableImpl<ILoggingEvent> fai =new FilterAttachableImpl<ILoggingEvent>();private final AtomicReference<Appender<ILoggingEvent>> delegate =new AtomicReference<Appender<ILoggingEvent>>();private String name;private WorkQueueProcessor<ILoggingEvent> processor;private int backlog = 1024 * 1024;private boolean includeCallerData = false;private boolean started = false;//......
}
AsyncAppender继承了ContextAwareBase,同时实现了Appender、AppenderAttachable、CoreSubscriber接口
CoreSubscriber
reactor/core/CoreSubscriber.java
public interface CoreSubscriber<T> extends Subscriber<T> {/*** Request a {@link Context} from dependent components which can include downstream* operators during subscribing or a terminal {@link org.reactivestreams.Subscriber}.** @return a resolved context or {@link Context#empty()}*/default Context currentContext(){return Context.empty();}/*** Implementors should initialize any state used by {@link #onNext(Object)} before* calling {@link Subscription#request(long)}. Should further {@code onNext} related* state modification occur, thread-safety will be required.* <p>* Note that an invalid request {@code <= 0} will not produce an onError and* will simply be ignored or reported through a debug-enabled* {@link reactor.util.Logger}.** {@inheritDoc}*/@Overridevoid onSubscribe(Subscription s);
}
CoreSubscriber继承了Subscriber接口,Subscriber接口定义了onSubscribe(Subscription s)、onNext、onError、onComplete方法
onSubscribe
public void onSubscribe(Subscription s) {try {doStart();}catch (Throwable t) {addError(t.getMessage(), t);}finally {started = true;s.request(Long.MAX_VALUE);}}protected void doStart() {}
onSubscribe方法执行doStart,标记started为true,同时触发s.request(Long.MAX_VALUE)
onNext
public void onNext(ILoggingEvent iLoggingEvent) {aai.appendLoopOnAppenders(iLoggingEvent);}
onNext调用AppenderAttachableImpl的appendLoopOnAppenders方法
onError
public void onError(Throwable t) {addError(t.getMessage(), t);}
onError主要是添加错误信息到logback的status
onComplete
public void onComplete() {try {Appender<ILoggingEvent> appender = delegate.getAndSet(null);if (appender != null){doStop();appender.stop();aai.detachAndStopAllAppenders();}}catch (Throwable t) {addError(t.getMessage(), t);}finally {started = false;}}protected void doStop() {}
onComplete则执行doStop、appender.stop()、aai.detachAndStopAllAppenders(),最后标记started为false
Appender.doAppend
public void doAppend(ILoggingEvent evt) throws LogbackException {if (getFilterChainDecision(evt) == FilterReply.DENY) {return;}evt.prepareForDeferredProcessing();if (includeCallerData) {evt.getCallerData();}try {queueLoggingEvent(evt);}catch (Throwable t) {addError(t.getMessage(), t);}}protected void queueLoggingEvent(ILoggingEvent evt) {if (null != delegate.get()) {processor.onNext(evt);}}
doAppend方法先判断是否需要DENY,是则直接返回,之后主要执行queueLoggingEvent,它在delegate不为null时执行processor.onNext(evt)
LifeCycle.start
public void start() {startDelegateAppender();processor = WorkQueueProcessor.<ILoggingEvent>builder().name("logger").bufferSize(backlog).autoCancel(false).build();processor.subscribe(this);}private void startDelegateAppender() {Appender<ILoggingEvent> delegateAppender = delegate.get();if (null != delegateAppender && !delegateAppender.isStarted()) {delegateAppender.start();}}public void addAppender(Appender<ILoggingEvent> newAppender) {if (delegate.compareAndSet(null, newAppender)) {aai.addAppender(newAppender);}else {throw new IllegalArgumentException(delegate.get() + " already attached.");}}
start方法执行startDelegateAppender,然后创建WorkQueueProcessor(
默认bufferSize为1024 * 1024),并subscribe当前实例;addAppender方法会设置delegate,并往AppenderAttachableImpl添加appender
stop
public void stop() {processor.onComplete();}
stop方法执行processor.onComplete()
小结
reactor-logback基于WorkQueueProcessor提供了另外一种AsyncAppender,它不是基于BlockingQueue而是基于RingBuffer来实现的。其onSubscribe方法执行doStart,标记started为true,同时触发s.request(Long.MAX_VALUE);onNext调用AppenderAttachableImpl的appendLoopOnAppenders方法;onComplete则执行doStop、appender.stop()、aai.detachAndStopAllAppenders(),最后标记started为false;doAppend方法先判断是否需要DENY,是则直接返回,之后主要执行queueLoggingEvent,它在delegate不为null时执行processor.onNext(evt)。
相关文章:
聊聊reactor-logback的AsyncAppender
序 本文主要研究一下reactor-logback的AsyncAppender AsyncAppender reactor-logback/src/main/java/reactor/logback/AsyncAppender.java public class AsyncAppender extends ContextAwareBaseimplements Appender<ILoggingEvent>, AppenderAttachable<ILogging…...
Apache SeaTunne简介
Apache SeaTunne简介 文章目录 1.Apache SeaTunne是什么?1.1[官网](https://seatunnel.apache.org/)1.2 项目地址 2.架构3.特性3.1 丰富且可扩展的连接器和插件机制3.2 支持分布式快照算法以确保数据一致性3.3 支持流、批数据处理,支持全量、增量和实时数…...
【开题报告】基于uniapp的IT资讯阅读小程序的设计与实现
1.研究背景 随着信息技术的飞速发展和互联网的普及,IT(Information Technology)行业成为了当今社会中最活跃和最具前景的领域之一。人们对于IT领域的资讯需求越来越高,希望能够第一时间获取到全面、准确、及时的IT资讯。 传统的…...
Java小案例-SpringBoot火车票订票购票票务系统
目录 前言 详细资料 源码获取 前言 SpringBoot火车票订票购票票务系统 前端使用技术:HTML5,CSS3、JavaScript、VUE等 后端使用技术:Spring boot(SSM)等 数据库:Mysql数据库 数据库管理工具:phpstud…...
关于获取高级电工职业技能等级证书一些避坑经历
有幸在今年9月份成功通过高级电工职业技能等级认证,以下是我遇到的一些常见问题,以及一些考点内容以及总结 什么是高级电工职业技能等级证书 电工职业技能等级证书是证明持证人电工知识和技能水平高低的,是持证人应聘、求职、任职、开业的资格凭证,是用…...
springboot(ssm在线课程管理系统 网课管理系统Java系统
springboot(ssm在线课程管理系统 网课管理系统Java系统 开发语言:Java 框架:ssm/springboot vue JDK版本:JDK1.8(或11) 服务器:tomcat 数据库:mysql 5.7(或8.0) 数…...
4.1 媒资管理模块 - Nacos与Gateway搭建
文章目录 媒资管理模块 - 媒资项目搭建一、需求分析1.1 介绍1.2 数据模型1.3 分析网关 二、 搭建Nacos2.1 服务发现中心2.2.1 Maven2.2.2 配置Nacos 2.2 配置中心2.2.1 介绍2.2.2 Maven 坐标2.2.3 配置 content-api 工程2.2.4 配置 content-service 工程2.2.5 配置 system-api …...
1641:【例 1】矩阵 A×B
【题目描述】 矩阵 A 规模为 nm ,矩阵 B 规模为 mp ,现需要你求 AB 。 矩阵相乘的定义:nm 的矩阵与 mp 的矩阵相乘变成 np 的矩阵,令 aik 为矩阵 A 中的元素,bkj 为矩阵 B 中的元素,则相乘所得矩阵 C 中的…...
iOS问题记录 - iOS 17通过NSUserDefaults设置UserAgent无效
文章目录 前言开发环境问题描述问题分析解决方案最后 前言 最近维护一个老项目时遇到的问题。说起这老项目我就有点头疼,一个快十年前的项目,这么说你可能不觉得有什么,但是你想想Swift也才发布不到十年(2014年6月发布࿰…...
linux的一些典型面试题解读
目录 前言1 Linux 文件系统2 Shell 编程3 进程管理4 用户和权限管理5 软件包管理6 网络配置7 系统监控和日志8 存储管理9 安全性10 常见命令11 系统启动流程12 Linux 进程间通信方式13 Linux 中的 I/O 多路复用14 Shell 脚本优化与调试15 Linux 文件权限与 ACL16 Linux 中的环境…...
tortoisesvn各版本下载链接
https://tortoisesvn.net 无法访问最新版本下载 TortoiseSVN download | SourceForge.net 所有版本下载 TortoiseSVN - Browse Files at SourceForge.net...
[自动化运维工具]ansible简单介绍和常用模块
ansible 源操作主机功能 自动化运维(playbook剧本yaml) 是基于python开发的一个配置管理和应用部署工具,在自动化运维中,现在还是异军突起 ansible能批量配置,部署,管理上千台主机,类似于xshell…...
记一次渗透测试信息收集-越权
目录 一、信息收集 子域名收集 存活探测 二、越权 越权一 越权二 一、信息收集 子域名收集 使用subfinder进行子域名收集 语法:subfinder.exe -d xx.com -all -o qq1.txt -v //结合自己渗透经验,多渠道收集子域名,汇总去重。 …...
Flink系列之:Table API Connectors之JSON Format
Flink系列之:Table API Connectors之JSON Format 一、JSON Format二、依赖三、创建一张基于 JSON Format 的表四、Format 参数五、数据类型映射关系 一、JSON Format JSON Format 能读写 JSON 格式的数据。当前,JSON schema 是从 table schema 中自动推…...
2018年第七届数学建模国际赛小美赛B题世界杯足球赛的赛制安排解题全过程文档及程序
2018年第七届数学建模国际赛小美赛 B题 世界杯足球赛的赛制安排 原题再现: 有32支球队参加国际足联世界杯决赛阶段的比赛。但从2026年开始,球队的数量将增加到48支。由于时间有限,一支球队不能打太多比赛。因此,国际足联提议改变…...
【为数据之道学习笔记】5-7五类数据主题联接的应用场景
在数字化转型的背景下,华为的数据消费已经不再局限于传统的报表分析,还要支持用户的自助分析、实时分析,通过数据的关联,支持业务的关联影响分析以及对目标对象做特征识别,进行特定业务范围圈定、差异化管理与决策等。…...
得帆信息创始人-张桐,受邀出席 BV百度风投AIGC主题论坛
近日,得帆信息创始人兼CEO张桐,作为百度风投被投代表企业创始人受邀出席“向未来,共成长” BV百度风投AIGC主题论坛。 与包括上海市徐汇区相关部门领导、百度集团相关事业部负责人及代表,以及来自国寿资本、中网投、麦顿投资的投资…...
云原生之深入解析减少Docker镜像大小的优化技巧
一、什么是 Docker? Docker 是一种容器引擎,可以在容器内运行一段代码,Docker 镜像是在任何地方运行应用程序而无需担心应用程序依赖性的方式。要构建镜像,docker 使用一个名为 Dockerfile 的文件,Dockerfile 是一个包…...
记一次java for循环改造多线程的操作
背景 今天在开发质量平台时需要获取某些数据,要请求公司某个工程的OpenAPI接口A。此接口为返回通用数据的接口,且接口本身的RT都在2~3秒之间。使用该接口,需要进行两次循环获取,然后对返回数据进行处理组装࿰…...
Java面试整理-Java复制
Java复制 在Java中,复制对象或数据通常涉及不同的场景和方法。以下是几种常见的复制情况及其相关方法: 基本数据类型的复制:基本数据类型(如int, double, char等)在Java中是通过值传递的。当你将一个基本数据类型的值赋给另一个变量时,实际上是创建了一个新的值。 int a …...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
