Project Reactor 深度解析 - 2. 响应式编程调试,FLow的概念设计以及实现(上)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Project Reactor 深度解析 - 2. 响应式编程调试,FLow的概念设计以及实现(上)

响应式编程的首要问题 - 不好调试


我们在分析传统代码的时候,在哪里打了断点,就能看到直观的调用堆栈,来搞清楚,谁调用了这个代码,之前对参数做了什么修改,等等。但是在响应式编程中,这个问题就很麻烦。来看下面的例子。


public class FluxUtil1 {
    public static Flux<Integer> test(Flux<Integer> integerFlux) {
        return FluxUtil2.test2(integerFlux.map(Object::toString));
    }
}
public class FluxUtil2 {
    public static Flux<Integer> test2(Flux<String> stringFlux) {
        return stringFlux.map(Integer::new);
    }
}
public class FluxTest {
    public static void main(String[] args) {
        Flux<Integer> integerFlux = Flux.fromIterable(List.of(1, 2, 3));
        FluxUtil1.test(integerFlux.log()).subscribe(integer -> {
            System.out.println(integer);
        });
    }
}


我们调试到 subscribe 订阅消费(这个后面会讲),我们一般会想知道我们订阅的这个东西,之前经过了怎样的处理,但是在System.out.println(integer)打断点,看到的却是:


微信图片_20220624191331.jpg


根本看不出来是FluxUtil1FluxUtil2处理过这个Flux。简单的代码还好,复杂起来调试简直要人命。官方也意识到了这一点,所以提供了一种在操作时捕捉堆栈缓存起来的机制。


这里我们先给出这些机制如何使用,后面我们会分析其中的实现原理。


1. 通过打开全局 Operator 堆栈追踪

设置reactor.trace.operatorStacktrace这个环境变量为 true,即启动参数中加入 -Dreactor.trace.operatorStacktrace=true,这样启动全局 Operator 堆栈追踪。


这个也可以通过代码动态打开或者关闭:

//打开
Hooks.onOperatorDebug();
//关闭
Hooks.resetOnOperatorDebug();

打开这个追踪之后,在每多一个 Operator,就会多出来一个 FluxOnAssembly(这个后面原理会详细说明)。通过这个 FluxOnAssembly,里面就有堆栈信息。怎么获取呢?可以通过Scannable.from(某个Flux).parents().collect(Collectors.toList())获取里面所有层的 Flux,其中包含了 FluxOnAssembly, FluxOnAssembly 就包含了堆栈信息。

我们这里,在System.out.println(integer)打断点,加入查看Scannable.from(FluxUtil1.test(integerFlux.log())).parents().collect(Collectors.toList()),就能看到:


微信图片_20220624191352.jpg


可以看出,每次map操作究竟发生在哪一行代码,都能看到。

如果使用的是专业版的 IDEA,还可以配置:



微信图片_20220624191411.jpg


然后可以在打断点 Debug 就能看到具体堆栈:



微信图片_20220624191427.jpg


2. 通过加入 ReactorDebugAgent 实现

添加依赖:

<dependency>
    <groupId>io.projectreactor</groupId>
    <artifactId>reactor-tools</artifactId>
    <version>略</version>
</dependency>

之后,可以通过这两个代码,开启

//启用
ReactorDebugAgent.init();
//如果有类没有生效,例如初始化没加载,后来动态加载的类,可以调用这个重新处理启用
ReactorDebugAgent.processExistingClasses();

这样,可以动态修改线上应用开启Debug模式,例如通过 Arthas 这个工具的 ognl 调用静态方法的功能(https://alibaba.github.io/arthas/ognl.html)。

如果使用的是专业版的 IDEA,还可以配置:


微信图片_20220624191442.jpg


然后可以在打断点 Debug 就能看到具体堆栈:



微信图片_20220624191459.jpg




相关文章
|
1月前
|
调度 开发者
核心概念解析:进程与线程的对比分析
在操作系统和计算机编程领域,进程和线程是两个基本而核心的概念。它们是程序执行和资源管理的基础,但它们之间存在显著的差异。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
62 4
|
3月前
|
机器学习/深度学习 自然语言处理 JavaScript
信息论、机器学习的核心概念:熵、KL散度、JS散度和Renyi散度的深度解析及应用
在信息论、机器学习和统计学领域中,KL散度(Kullback-Leibler散度)是量化概率分布差异的关键概念。本文深入探讨了KL散度及其相关概念,包括Jensen-Shannon散度和Renyi散度。KL散度用于衡量两个概率分布之间的差异,而Jensen-Shannon散度则提供了一种对称的度量方式。Renyi散度通过可调参数α,提供了更灵活的散度度量。这些概念不仅在理论研究中至关重要,在实际应用中也广泛用于数据压缩、变分自编码器、强化学习等领域。通过分析电子商务中的数据漂移实例,展示了这些散度指标在捕捉数据分布变化方面的独特优势,为企业提供了数据驱动的决策支持。
197 2
信息论、机器学习的核心概念:熵、KL散度、JS散度和Renyi散度的深度解析及应用
|
2月前
|
算法 Java 数据库连接
Java连接池技术,从基础概念出发,解析了连接池的工作原理及其重要性
本文详细介绍了Java连接池技术,从基础概念出发,解析了连接池的工作原理及其重要性。连接池通过复用数据库连接,显著提升了应用的性能和稳定性。文章还展示了使用HikariCP连接池的示例代码,帮助读者更好地理解和应用这一技术。
64 1
|
2月前
|
消息中间件 存储 负载均衡
Apache Kafka核心概念解析:生产者、消费者与Broker
【10月更文挑战第24天】在数字化转型的大潮中,数据的实时处理能力成为了企业竞争力的重要组成部分。Apache Kafka 作为一款高性能的消息队列系统,在这一领域占据了重要地位。通过使用 Kafka,企业可以构建出高效的数据管道,实现数据的快速传输和处理。今天,我将从个人的角度出发,深入解析 Kafka 的三大核心组件——生产者、消费者与 Broker,希望能够帮助大家建立起对 Kafka 内部机制的基本理解。
99 2
|
3月前
|
存储 NoSQL MongoDB
MongoDB 概念解析
10月更文挑战第12天
51 0
MongoDB 概念解析
|
3月前
|
机器学习/深度学习 人工智能 自然语言处理
Transformer图解以及相关的概念解析
前言 transformer是目前NLP甚至是整个深度学习领域不能不提到的框架,同时大部分LLM也是使用其进行训练生成模型,所以transformer几乎是目前每一个机器人开发者或者人工智能开发者不能越过的一个框架。接下来本文将从顶层往下去一步步掀开transformer的面纱。 transformer概述 Transformer模型来自论文Attention Is All You Need。 在论文中最初是为了提高机器翻译的效率,它使用了Self-Attention机制和Position Encoding去替代RNN。后来大家发现Self-Attention的效果很好,并且在其它的地
|
3月前
|
JSON 关系型数据库 API
ElasticSearch 的概念解析与使用方式(二)
ElasticSearch 的概念解析与使用方式(二)
46 1
|
3月前
|
存储 搜索推荐 Java
ElasticSearch 的概念解析与使用方式(一)
ElasticSearch 的概念解析与使用方式(一)
82 1
|
3月前
|
供应链 网络协议 数据安全/隐私保护
|
3月前
|
前端开发 JavaScript Shell
深入解析前端构建利器:webpack核心概念与基本功能全览
深入解析前端构建利器:webpack核心概念与基本功能全览—
38 0

推荐镜像

更多