草庐IT

读Java实战(第二版)笔记17_反应式编程

躺柒 2023-03-28 原文

1. 再次出现在聚光灯下的原因

1.1. 基本思想已经有二三十年的历史

1.2. 大数据

1.2.1. 以PB计量的大数据

1.2.2. 当前互联网中流量最大的部分是移动流量

1.2.3. 物联网(Internet of things, IoT)流量取代移动流量成为互联网流量的主流,这种情况还会进一步加剧

1.3. 异构环境

1.3.1. 移动设备

1.3.2. 运行着数千个多核处理器的云端集群

1.4. 使用模式

1.4.1. 用户期望毫秒级的响应时间

1.4.2. 希望应用百分之百时时刻刻都在线

2. 反应式编程

2.1. 一种利用反应式流的编程技术

2.1.1. 以异步方式处理潜在无边界数据流的标准技术

2.2. 以异步的方式处理、整合来自不同系统和源头的数据流

2.2.1. 比线程更轻量级

2.2.2. 提升了创建并发以及异步应用的抽象层次

2.2.3. 任务能以异步的方式运行

2.3. 可以构建单一组件或者应用

2.4. 协调多个组件,将它们搭建成一个反应式系统

2.5. 主线程池中运行的线程执行的都为无阻塞的操作

2.5.1. 确保所有的CPU核都能得到最充分的利用

2.6. 不要在主事件循环中添加可能阻塞的操作

2.6.1. 所有I/O密集型的操作

2.6.1.1. 访问数据库或文件系统

2.6.1.2. 调用远程服务

2.6.2. 无法预测何时能够结束

2.6.3. 可能消耗比较长时间的事件

2.7. 开辟独立的线程池用于执行阻塞式操作

2.7.1. 为CPU密集型和I/O密集型的操作分别创建单独的线程池

2.7.2. 更精细地监控不同类型任务的性能

2.7.3. 更好地配置和调整线程池的规模

2.7.4. 更好地适应业务的需求

2.8. 背压

2.8.1. 发表-订阅模式下的一种常见的流量控制机制

2.8.2. 提供了一种协议,可以在不阻塞线程的情况下,避免数据接收方被压垮

2.8.3. 避免流中事件处理的消费者由于处理速度较慢,被一个或多个快速的生产者压垮

2.8.4. 组件需要一种方式来向上游生产者反馈,让它们减缓生产速度

2.8.5. 告诉生产者它在接收更多数据之前,在给定的时间内能够接受和处理多少事件

3. Flow类

3.1. java.util.concurrent.Flow

3.1.1. Java 9

3.2. 所有实现该接口的库需要遵守的合约

3.2.1. 使构建于不同的反应式库之上的应用间能相互协调、相互理解沟通的通用语言

3.2.2. 接口可以帮助你更好地构建你的程序思维

3.2.3. 并不能帮你更快地完成程序设计

3.3. 标准化使得不同库之间互通和调用成为可能

3.3.1. Akka

3.3.2. RxJava

3.4. 发布-订阅”模型

3.4.1. 发布者(Publisher)

3.4.1.1. 顺序事件的提供者

3.4.1.2. 事件的数量可能没有上限

3.4.1.3. 受背压机制的制约

3.4.1.4. 按照Subscriber的反馈进行元素的生产

3.4.1.5. Java函数式接口

3.4.2. 订阅者(Subscriber)

3.4.2.1. 把自己注册为该事件的监听方从而完成对Publisher事件的注册

3.4.3. 订阅(Subscription)

3.4.3.1. 流量控制,包括Publisher与Subscriber之间的背压都是由Subscription管理的

3.4.3.2. cancel()方法的实现必须是幂等和线程安全的

3.4.3.2.1. 调用它一次与重复调用多次的效果是同样的
3.4.3.2.2. 任何对Subscription的额外调用都不会有副作用

3.4.4. 处理者(Processor)

3.4.4.1. 反应式流中事件的转化阶段

3.4.4.2. 转换数据

3.4.5. 所有方法都返回void,从而确保它们能以完全异步的方式实现

4. RxJava

4.1. 应用最广泛的反应式库

4.1.1. 诞生于Netflix

4.1.2. 对微软.Net环境中反应式扩展(reactive extension, Rx)项目的迁移

4.1.3. 比Java 9的Flow API更方便

4.1.3.1. 更加丰富的函数集

4.1.3.2. 更灵活地对流进行整合、创建以及过滤操作

4.2. io.reactivex.Observable

4.2.1. 不支持背压

4.2.2. 适用于

4.2.2.1. 用户接口事件(譬如鼠标移动)

4.2.2.2. 流元素不超过一千个

4.2.2.3. 基于图形用户界面的事件流

4.2.2.4. 无法背压或不常发生的事件时

4.2.3. onSubscribe方法需要一个Disposable参数

4.2.4. 只在需要Observable的额外结构时使用Observable,否则就应该继续使用它的Publisher接口

4.3. Subscriber可以通过request(Long.MAX_VALUE)调用关闭背压功能

4.4. just()工厂方法

4.4.1. 将一个或多个元素转换为Observable

4.5. interval工厂方法

4.5.1. 按照固定的时间间隔发出事件

4.6. blockingSubscribe方法

4.6.1. 调用当前线程(在这个例子中就是main函数所在的线程)的回调函数

4.7. 弹珠图

5. 反应式宣言

5.1. 2013年至2014年间发起

5.2. 开发反应式应用和系统的规范

5.3. Jonas Bonér、Dave Farley、Roland Kuhn和Martin Thompson

5.4. 响应性

5.4.1. 反应式系统的响应时间很快

5.4.2. 响应时间应该是稳定且可预测的

5.4.2.1. 用户才能明确地设定他的预期

5.4.2.2. 增强用户的信心

5.5. 韧性

5.5.1. 系统在出现失败时依然能继续响应服务

5.5.1.1. 组件运行时复制

5.5.1.2. 从时间(发送方和接受方都拥有相互独立的生命周期)和空间(发送方和接收方运行于不同的进程)维度对组件进行解耦

5.5.1.3. 任何一个组件都能以异步的方式向其他组件分发任务

5.6. 弹性

5.6.1. 应用的工作负载

5.6.2. 有能力自动地适配和服务更大的负荷

5.7. 消息驱动

5.7.1. 组件间的松耦合

5.7.2. 组件隔离

5.7.3. 位置透明性

5.7.3.1. 实现韧性的决定性要素

5.7.3.2. 使得系统能够依据当前的负荷情况,对应用进行复制或者自动地水平扩展

5.7.3.3. 位置无关的扩展也是反应式应用(异步、并发、即时松耦合)与反应式系统(凭借位置透明性从空间角度解耦)之间的另一个区别

6. 反应式应用

6.1. 主要对临时数据流进行处理

6.2. 事件驱动型

6.2.1. 事件会被所有注册了该事件的组件接收

6.3. 异步、并发、即时松耦合

7. 反应式系统

7.1. 多个独立应用可以像一个单一系统那样步调一致地工作,同时其又具备良好的扩展性

7.2. 各个应用也是充分解耦的

7.2.1. 即使其中某一个应用发生失效,也不会拖垮整个系统

7.3. 用于构造应用以及协调组件间的通信

7.3.1. 以异步的方式发送和接收的,这种方式有效地解耦了发送方与接收方

7.4. 消息驱动系统

7.4.1. 消息往往是直接发送给某个单一目标的

7.5. 组件间完全的解耦合既是实现有效隔离的必要前提,也是保障系统在遭遇失效(韧性)和超大负荷(弹性)时仍能保持响应的基础

7.6. 韧性更偏向于容错

7.6.1. 系统不只要能优雅地降级,更重要的是能通过隔离失效组件,将系统重新拉回健康状

7.6.2. 失效节点的管理可以不受失效组件自身的影响,在一个安全的上下文中进行

7.7. 凭借位置透明性从空间角度解耦

7.7.1. 反应式系统的所有组件都可以和其他任何服务通信,无须顾忌接收方在什么位置

有关读Java实战(第二版)笔记17_反应式编程的更多相关文章

  1. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  2. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  3. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  4. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  5. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

    这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

  6. 【Java 面试合集】HashMap中为什么引入红黑树,而不是AVL树呢 - 2

    HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候

  7. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  8. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  9. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

  10. java - 为什么 ruby​​ modulo 与 java/other lang 不同? - 2

    我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.

随机推荐