架构设计80-落地实践03-响应式编程01

简介: 架构设计80-落地实践03-响应式编程01

架构设计系列文章,请参见连接。

背景

响应式宣言

很早之前就想写Actor相关的介绍文章。怎奈没有好时机去介绍这部分内容。前几天准备研究一下Spring Cloud监控管理的内容,发现一个叫做Spring Boot Admin的项目。研究了一段时间后发现没有办法完美的解决我的问题,所以就准备研究一下改改代码。发现这个项目用了Spring的响应式编程的方法编写整个项目,所以这里就着这个机会把设计进行Actor介绍。

在接触Spring WebFlux之前,作者本人认为Actor其实是MapReduce的顶层的设计模式。可以为大量数据处理提供快速处理方案,并且解决线程管理工作。这两个问题都是程序员很难解决或者不愿解决的问题。后来想想其实在很多技术领域中都用到了这些概念。例如:JavaScript就是单线程事件驱动的模式完成了高吞吐量,libevent这种C语言的事件驱动库,基于libevent的memcached也是使用这种机制完成的,Nginx的实现方式也是基于这种模式去定义Work进程的。

  • 思考

从计算机被发明到现在,计算机主要处理两种问题:大量的吞吐和大量的计算。例如:在业界著名的C10K问题是关于大吞吐的问题,用户建模过程其实就是一个要求算力的问题。对于IO密集型和CPU密集型的处理方式和方法,需要进行思考与设计。在计算机专业的《算法导论》课上就是专门的解决这些问题的。对于通用型处理过程中的IO密集型和CPU密集型也需要有专业的解决方案以及统一的思维模式。故对于IO密集型和CPU密集型通用问题处理的思考:

Netty基于单线程设计的EventLoop能够同时处理成千上万的客户端连接的IO事件,缺点是单线程不能够处理时间过长的任务,这样会阻塞使得IO事件的处理被阻塞,严重的时候回造成IO事件堆积,服务不能够高效响应客户端请求。所谓时间过长的任务通常是占用CPU资源比较长的任务,也即CPU密集型,对于业务应用也可能是业务代码的耗时。这点和Node是极其相似的,我可以认为这是基于单线程的EventLoop模型的通病,我们不能够将过长的任务交给这个单线程来处理,也就是不适合CPU密集型应用。

那么问题怎么解决呢,参照Node的解决方案,当我们遇到需要处理时间很长的任务的时候,我们可以将它交给子线程来处理,主线程继续去EventLoop,当子线程计算完毕再讲结果交给主线程。这也是通常基于Netty的应用的解决方案,通常业务代码执行时间比较长,我们不能够把业务逻辑交给这个单线程来处理,因此我们需要额外的线程池来分配线程资源来专门处理耗时较长的业务逻辑,这是比较通用的设计方案。

换句话说,利用有限的线程,来充分利用多核的优势。

  • 方案

需要解决现实中的业务问题就需要进行。
事件驱动

设计模式

  • EventDelegate(事件委托)

在JavaScript和C#都有一种叫事件委托的编程方式。虽然这两种事件委托方式的机制不同,但是它为我们提供了关于发布/订阅的一种机制。提供了将事件发生和事件处理者之间进行隔离与解耦的机制,并为之后事件触发机制提供实现模式。

  • EventLoop(事件循环)

事件轮询和事件等待是事件处理的两种机制,事件循环的机制其实就是一种事件等待的机制。一般情况下使用*nix(linux,unix,win...)上提供的时间轮询机制降低CPU使用率又可以获取事件。对于EventLoop中由专门的事件接收处理,事件分发机制,事件业务处理。在单线程中进行相关的这三部分都在一个线程中完成。

  • Actor

Actor模型是1973年提出的一个分布式并发编程模式,在Erlang语言中得到广泛支持和应用。在Actor模型中,Actor参与者是一个并发原语,简单来说,一个参与者就是一个工人,与进程或线程一样能够工作或处理任务。可以将Actor想象成面向对象编程语言中的对象实例,不同的是Actor的状态不能直接读取和修改,方法也不能直接调用。Actor只能通过消息传递的方式与外界通信。每个参与者存在一个代表本身的地址,但只能向该地址发送消息。

  • Reactor

Reactor模式
Reactor模型:
1.向事件分发器注册事件回调
2.事件发生
3.事件分发器调用之前注册的函数
4.在回调函数中读取数据,对数据进行后续处理

  • Proactor

Proactor模式

Proactor模型:
1.向事件分发器注册事件回调
2.事件发生
3.操作系统读取数据,并放入应用缓冲区,然后通知事件分发器
4.事件分发器调用之前注册的函数
5.在回调函数中对数据进行后续处理

响应式编程的主流实现技术

目前,响应式编程的主流实现技术包括 Rxjava、 Akka Streams、Vert.x和Project Reactor等。

  • Rxjava

Reactive Extensions(Rx)是一个类库,它集成了异步基于可观察( Observable)序列的事件驱动编程,最早应用于微软的NET平台。而 Rxjava是 Reactive Extensions 的Java实现用于通过使用 Observable/ Flowable序列来构建异步和基于事件的程序库,目前有1x版本和2.x版本两套实现。

  • Akka Streams

Akka也是响应式流规范的初始成员,而 Akka Streams是以Akka为基础的响应式流的实现,在Akka现有的角色模型之上提供了一种更高层级的抽象,支持背压等响应式机制。

  • Vert.x

Vert.x是为了构建响应式系统而设计的,基于事件驱动架构, Vert x实现了非阻塞的任务处理机制。Vert.x中包含Vert.x Reactive Streams工具库,该工具库提供了Vert.x上响应式流规范的实现。我们可以通过Vert.x提供的可读流和可写流处理响应式流规范中的发布者和订阅者。

  • Project Reactor

Spring 5中引入了响应式编程机制,而Spring5中默认集成了 Project Reactor作为该机制的实现框架。 Reactor诞生较晚,可以认为是第二代响应式开发框架。所以,它是一款完全基于响应式流规范设计和实现的工具库。WebFlux是一个典型非阻塞异步的框架,它的核心是基于Reactor的相关API实现的。参考官网(https://projectreactor.io/

总结

响应式编程和事件驱动模式有着密切的关系。它有事件驱动的很多特点:高性能,异步处理等。并为我们提供了并发能力与分发能力,这部分是大部分程序员都无法管理的内容。有了响应式编程后可以解决很多关于性能,关于异步拆分的功能。本文只介绍了异步编程的一点概念,接下来会深入的进行响应式编程的讨论。

参考:

反应式宣言
IO设计模式:Actor、Reactor、Proactor
aio_write - asynchronous write
eventloop & actor模式 & Java线程模型演进 & Netty线程模型 总结
响应式架构:消息模式Actor实现与Scala、Akka应用集成
实战SpringCloud响应式微服务系列教程(第三章)
Reactor 指南中文版V2.0
使用 Akka Actor 和 Java 8 构建反应式应用
使用 Akka 的 Actor 模型和领域驱动设计构建反应式系统

目录
相关文章
|
17天前
|
API 持续交付 开发者
后端开发中的微服务架构实践与挑战
在数字化时代,后端服务的构建和管理变得日益复杂。本文将深入探讨微服务架构在后端开发中的应用,分析其在提高系统可扩展性、灵活性和可维护性方面的优势,同时讨论实施微服务时面临的挑战,如服务拆分、数据一致性和部署复杂性等。通过实际案例分析,本文旨在为开发者提供微服务架构的实用见解和解决策略。
|
18天前
|
弹性计算 Kubernetes Cloud Native
云原生架构下的微服务设计原则与实践####
本文深入探讨了在云原生环境中,微服务架构的设计原则、关键技术及实践案例。通过剖析传统单体架构面临的挑战,引出微服务作为解决方案的优势,并详细阐述了微服务设计的几大核心原则:单一职责、独立部署、弹性伸缩和服务自治。文章还介绍了容器化技术、Kubernetes等云原生工具如何助力微服务的高效实施,并通过一个实际项目案例,展示了从服务拆分到持续集成/持续部署(CI/CD)流程的完整实现路径,为读者提供了宝贵的实践经验和启发。 ####
|
7天前
|
Cloud Native 安全 API
云原生架构下的微服务治理策略与实践####
—透过云原生的棱镜,探索微服务架构下的挑战与应对之道 本文旨在探讨云原生环境下,微服务架构所面临的关键挑战及有效的治理策略。随着云计算技术的深入发展,越来越多的企业选择采用云原生架构来构建和部署其应用程序,以期获得更高的灵活性、可扩展性和效率。然而,微服务架构的复杂性也带来了服务发现、负载均衡、故障恢复等一系列治理难题。本文将深入分析这些问题,并提出一套基于云原生技术栈的微服务治理框架,包括服务网格的应用、API网关的集成、以及动态配置管理等关键方面,旨在为企业实现高效、稳定的微服务架构提供参考路径。 ####
29 5
|
10天前
|
监控 Go API
Go语言在微服务架构中的应用实践
在微服务架构的浪潮中,Go语言以其简洁、高效和并发处理能力脱颖而出,成为构建微服务的理想选择。本文将探讨Go语言在微服务架构中的应用实践,包括Go语言的特性如何适应微服务架构的需求,以及在实际开发中如何利用Go语言的特性来提高服务的性能和可维护性。我们将通过一个具体的案例分析,展示Go语言在微服务开发中的优势,并讨论在实际应用中可能遇到的挑战和解决方案。
|
8天前
|
负载均衡 监控 Cloud Native
云原生架构下的微服务治理策略与实践####
在数字化转型浪潮中,企业纷纷拥抱云计算,而云原生架构作为其核心技术支撑,正引领着一场深刻的技术变革。本文聚焦于云原生环境下微服务架构的治理策略与实践,探讨如何通过精细化的服务管理、动态的流量调度、高效的故障恢复机制以及持续的监控优化,构建弹性、可靠且易于维护的分布式系统。我们将深入剖析微服务治理的核心要素,结合具体案例,揭示其在提升系统稳定性、扩展性和敏捷性方面的关键作用,为读者提供一套切实可行的云原生微服务治理指南。 ####
|
8天前
|
消息中间件 缓存 Cloud Native
云原生架构下的性能优化实践与挑战####
随着企业数字化转型的加速,云原生架构以其高度解耦、弹性伸缩和快速迭代的特性,成为现代软件开发的首选模式。本文深入探讨了云原生环境下性能优化的关键策略与面临的主要挑战,通过案例分析,揭示了如何有效利用容器化、微服务、动态调度等技术手段提升应用性能,同时指出了在复杂云环境中确保系统稳定性和高效性的难题,为开发者和架构师提供了实战指南。 ####
21 3
|
8天前
|
运维 Kubernetes Cloud Native
深入理解云原生架构:从理论到实践
【10月更文挑战第38天】本文将引导读者深入探索云原生技术的核心概念,以及如何将这些概念应用于实际的软件开发和运维中。我们将从云原生的基本定义出发,逐步展开其背后的设计哲学、关键技术组件,并以一个具体的代码示例来演示云原生应用的构建过程。无论你是云原生技术的初学者,还是希望深化理解的开发者,这篇文章都将为你提供有价值的见解和实操指南。
|
8天前
|
Kubernetes Cloud Native 持续交付
云原生技术在现代应用架构中的实践与思考
【10月更文挑战第38天】随着云计算的不断成熟和演进,云原生(Cloud-Native)已成为推动企业数字化转型的重要力量。本文从云原生的基本概念出发,深入探讨了其在现代应用架构中的实际应用,并结合代码示例,展示了云原生技术如何优化资源管理、提升系统弹性和加速开发流程。通过分析云原生的优势与面临的挑战,本文旨在为读者提供一份云原生转型的指南和启示。
24 3
|
8天前
|
运维 Kubernetes Cloud Native
云原生技术在现代应用架构中的实践与挑战####
本文深入探讨了云原生技术的核心概念、关键技术组件及其在实际项目中的应用案例,分析了企业在向云原生转型过程中面临的主要挑战及应对策略。不同于传统摘要的概述性质,本摘要强调通过具体实例揭示云原生技术如何促进应用的灵活性、可扩展性和高效运维,同时指出实践中需注意的技术债务、安全合规等问题,为读者提供一幅云原生技术实践的全景视图。 ####
|
11天前
|
监控 API 持续交付
后端开发中的微服务架构实践与挑战####
本文深入探讨了微服务架构在后端开发中的应用,分析了其优势、面临的挑战以及最佳实践策略。不同于传统的单体应用,微服务通过细粒度的服务划分促进了系统的可维护性、可扩展性和敏捷性。文章首先概述了微服务的核心概念及其与传统架构的区别,随后详细阐述了构建微服务时需考虑的关键技术要素,如服务发现、API网关、容器化部署及持续集成/持续部署(CI/CD)流程。此外,还讨论了微服务实施过程中常见的问题,如服务间通信复杂度增加、数据一致性保障等,并提供了相应的解决方案和优化建议。总之,本文旨在为开发者提供一份关于如何在现代后端系统中有效采用和优化微服务架构的实用指南。 ####