当前位置: 首页 > news >正文

聊聊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是什么&#xff1f;1.1[官网](https://seatunnel.apache.org/)1.2 项目地址 2.架构3.特性3.1 丰富且可扩展的连接器和插件机制3.2 支持分布式快照算法以确保数据一致性3.3 支持流、批数据处理&#xff0c;支持全量、增量和实时数…...

【开题报告】基于uniapp的IT资讯阅读小程序的设计与实现

1.研究背景 随着信息技术的飞速发展和互联网的普及&#xff0c;IT&#xff08;Information Technology&#xff09;行业成为了当今社会中最活跃和最具前景的领域之一。人们对于IT领域的资讯需求越来越高&#xff0c;希望能够第一时间获取到全面、准确、及时的IT资讯。 传统的…...

Java小案例-SpringBoot火车票订票购票票务系统

目录 前言 详细资料 源码获取 前言 SpringBoot火车票订票购票票务系统 前端使用技术&#xff1a;HTML5,CSS3、JavaScript、VUE等 后端使用技术&#xff1a;Spring boot&#xff08;SSM&#xff09;等 数据库&#xff1a;Mysql数据库 数据库管理工具&#xff1a;phpstud…...

关于获取高级电工职业技能等级证书一些避坑经历

有幸在今年9月份成功通过高级电工职业技能等级认证,以下是我遇到的一些常见问题,以及一些考点内容以及总结 什么是高级电工职业技能等级证书 电工职业技能等级证书是证明持证人电工知识和技能水平高低的&#xff0c;是持证人应聘、求职、任职、开业的资格凭证&#xff0c;是用…...

springboot(ssm在线课程管理系统 网课管理系统Java系统

springboot(ssm在线课程管理系统 网课管理系统Java系统 开发语言&#xff1a;Java 框架&#xff1a;ssm/springboot vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#xff1a;mysql 5.7&#xff08;或8.0&#xff09; 数…...

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 &#xff0c;矩阵 B 规模为 mp &#xff0c;现需要你求 AB 。 矩阵相乘的定义&#xff1a;nm 的矩阵与 mp 的矩阵相乘变成 np 的矩阵&#xff0c;令 aik 为矩阵 A 中的元素&#xff0c;bkj 为矩阵 B 中的元素&#xff0c;则相乘所得矩阵 C 中的…...

iOS问题记录 - iOS 17通过NSUserDefaults设置UserAgent无效

文章目录 前言开发环境问题描述问题分析解决方案最后 前言 最近维护一个老项目时遇到的问题。说起这老项目我就有点头疼&#xff0c;一个快十年前的项目&#xff0c;这么说你可能不觉得有什么&#xff0c;但是你想想Swift也才发布不到十年&#xff08;2014年6月发布&#xff0…...

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 源操作主机功能 自动化运维&#xff08;playbook剧本yaml&#xff09; 是基于python开发的一个配置管理和应用部署工具&#xff0c;在自动化运维中&#xff0c;现在还是异军突起 ansible能批量配置&#xff0c;部署&#xff0c;管理上千台主机&#xff0c;类似于xshell…...

记一次渗透测试信息收集-越权

目录 一、信息收集 子域名收集 存活探测 二、越权 越权一 越权二 一、信息收集 子域名收集 使用subfinder进行子域名收集 语法&#xff1a;subfinder.exe -d xx.com -all -o qq1.txt -v //结合自己渗透经验&#xff0c;多渠道收集子域名&#xff0c;汇总去重。 …...

Flink系列之:Table API Connectors之JSON Format

Flink系列之&#xff1a;Table API Connectors之JSON Format 一、JSON Format二、依赖三、创建一张基于 JSON Format 的表四、Format 参数五、数据类型映射关系 一、JSON Format JSON Format 能读写 JSON 格式的数据。当前&#xff0c;JSON schema 是从 table schema 中自动推…...

2018年第七届数学建模国际赛小美赛B题世界杯足球赛的赛制安排解题全过程文档及程序

2018年第七届数学建模国际赛小美赛 B题 世界杯足球赛的赛制安排 原题再现&#xff1a; 有32支球队参加国际足联世界杯决赛阶段的比赛。但从2026年开始&#xff0c;球队的数量将增加到48支。由于时间有限&#xff0c;一支球队不能打太多比赛。因此&#xff0c;国际足联提议改变…...

【为数据之道学习笔记】5-7五类数据主题联接的应用场景

在数字化转型的背景下&#xff0c;华为的数据消费已经不再局限于传统的报表分析&#xff0c;还要支持用户的自助分析、实时分析&#xff0c;通过数据的关联&#xff0c;支持业务的关联影响分析以及对目标对象做特征识别&#xff0c;进行特定业务范围圈定、差异化管理与决策等。…...

得帆信息创始人-张桐,受邀出席 BV百度风投AIGC主题论坛

近日&#xff0c;得帆信息创始人兼CEO张桐&#xff0c;作为百度风投被投代表企业创始人受邀出席“向未来&#xff0c;共成长” BV百度风投AIGC主题论坛。 与包括上海市徐汇区相关部门领导、百度集团相关事业部负责人及代表&#xff0c;以及来自国寿资本、中网投、麦顿投资的投资…...

云原生之深入解析减少Docker镜像大小的优化技巧

一、什么是 Docker&#xff1f; Docker 是一种容器引擎&#xff0c;可以在容器内运行一段代码&#xff0c;Docker 镜像是在任何地方运行应用程序而无需担心应用程序依赖性的方式。要构建镜像&#xff0c;docker 使用一个名为 Dockerfile 的文件&#xff0c;Dockerfile 是一个包…...

记一次java for循环改造多线程的操作

背景 今天在开发质量平台时需要获取某些数据&#xff0c;要请求公司某个工程的OpenAPI接口A。此接口为返回通用数据的接口&#xff0c;且接口本身的RT都在2&#xff5e;3秒之间。使用该接口&#xff0c;需要进行两次循环获取&#xff0c;然后对返回数据进行处理组装&#xff0…...

Java面试整理-Java复制

Java复制 在Java中,复制对象或数据通常涉及不同的场景和方法。以下是几种常见的复制情况及其相关方法: 基本数据类型的复制:基本数据类型(如int, double, char等)在Java中是通过值传递的。当你将一个基本数据类型的值赋给另一个变量时,实际上是创建了一个新的值。 int a …...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...