前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >10分钟入门响应式:Springboot整合kafka实现reactive

10分钟入门响应式:Springboot整合kafka实现reactive

作者头像
麒思妙想
发布于 2021-08-12 03:51:08
发布于 2021-08-12 03:51:08
2K00
代码可运行
举报
文章被收录于专栏:麒思妙想麒思妙想
运行总次数:0
代码可运行

Springboot引入Reactor已经有一段时间了,笔者潜伏在各种技术群里暗中观察发现,好像scala圈子的同仁们,似乎对响应式更热衷一点。也许是因为他们对fp理解的更深吧,所以领悟起来障碍性更少一些的原因吧。尽管webflux对于数据库的支持,还不那么完善,也不妨我们试上一试。

首先请允许我引用全部的反应式宣言作为开篇,接下来会介绍webflux整合kafka做一个demo。

反应式宣言

在不同领域中深耕的组织都在不约而同地尝试发现相似的软件构建模式。希望这些系统会更健壮、更具回弹性 、更灵活,也能更好地满足现代化的需求。

近年来,应用程序的需求已经发生了戏剧性的更改,模式变化也随之而来。仅在几年前, 一个大型应用程序通常拥有数十台服务器、 秒级的响应时间、 数小时的维护时间以及GB级的数据。而今,应用程序被部署到了形态各异的载体上, 从移动设备到运行着数以千计的多核心处理器的云端集群。用户期望着毫秒级的响应时间,以及服务100%正常运行(随时可用)。而数据则以PB计量。昨日的软件架构已经根本无法满足今天的需求。

我们相信大家需要一套贯通整个系统的架构设计方案, 而设计中必需要关注的各个角度也已被理清, 我们需要系统具备以下特质:即时响应性(Responsive)、回弹性(Resilient)、弹性(Elastic)以及消息驱动(Message Driven)。我们称这样的系统为反应式系统(Reactive System)。

反应式系统更加灵活、松耦合和 可伸缩。这使得它们的开发和调整更加容易。它们对系统的失败 也更加的包容, 而当失败确实发生时, 它们的应对方案会是得体处理而非混乱无序。反应式系统具有高度的即时响应性, 为用户提供了高效的互动反馈。

反应式系统的特质:

即时响应性: :只要有可能, 系统就会及时地做出响应。即时响应是可用性和实用性的基石, 而更加重要的是,即时响应意味着可以快速地检测到问题并且有效地对其进行处理。即时响应的系统专注于提供快速而一致的响应时间, 确立可靠的反馈上限, 以提供一致的服务质量。这种一致的行为转而将简化错误处理、 建立最终用户的信任并促使用户与系统作进一步的互动。

回弹性:系统在出现失败时依然保持即时响应性。这不仅适用于高可用的、 任务关键型系统——任何不具备回弹性的系统都将会在发生失败之后丢失即时响应性。回弹性是通过复制、 遏制、 隔离以及委托来实现的。失败的扩散被遏制在了每个组件内部, 与其他组件相互隔离, 从而确保系统某部分的失败不会危及整个系统,并能独立恢复。每个组件的恢复都被委托给了另一个(外部的)组件, 此外,在必要时可以通过复制来保证高可用性。(因此)组件的客户端不再承担组件失败的处理。

弹性: 系统在不断变化的工作负载之下依然保持即时响应性。反应式系统可以对输入(负载)的速率变化做出反应,比如通过增加或者减少被分配用于服务这些输入(负载)的资源。这意味着设计上并没有争用点和中央瓶颈, 得以进行组件的分片或者复制, 并在它们之间分布输入(负载)。通过提供相关的实时性能指标, 反应式系统能支持预测式以及反应式的伸缩算法。这些系统可以在常规的硬件以及软件平台上实现成本高效的弹性。

消息驱动:反应式系统依赖异步的消息传递,从而确保了松耦合、隔离、位置透明的组件之间有着明确边界。这一边界还提供了将失败作为消息委托出去的手段。使用显式的消息传递,可以通过在系统中塑造并监视消息流队列, 并在必要时应用回压, 从而实现负载管理、 弹性以及流量控制。使用位置透明的消息传递作为通信的手段, 使得跨集群或者在单个主机中使用相同的结构成分和语义来管理失败成为了可能。非阻塞的通信使得接收者可以只在活动时才消耗资源, 从而减少系统开销。

大型系统由多个较小型的系统所构成, 因此整体效用取决于它们的构成部分的反应式属性。 这意味着, 反应式系统应用着一些设计原则,使这些属性能在所有级别的规模上生效,而且可组合。世界上各类最大型的系统所依赖的架构都基于这些属性,而且每天都在服务于数十亿人的需求。现在,是时候在系统设计一开始就有意识地应用这些设计原则了, 而不是每次都去重新发现它们。

Springboot Webflux

引入springboot官网的一张图来解释Spring webflux和spring mvc的区别:

Spring MVC is built on the Servlet API and uses a synchronous blocking I/O architecture whth a one-request-per-thread model.

Spring MVC 构建在 Servlet API 之上,使用的是同步阻塞式 I/O 模型,什么是同步阻塞式 I/O 模型呢?就是说,每一个请求对应一个线程去处理。

Spring WebFlux is a non-blocking web framework built from the ground up to take advantage of multi-core, next-generation processors and handle massive numbers of concurrent connections.

Spring WebFlux 是一个异步非阻塞式的 Web 框架,它能够充分利用多核 CPU 的硬件资源去处理大量的并发请求。

我们不难看出,持久层上Webflux针对部分NoSQL有一定的支持,而对应传统的关系型数据库就不那么友善了,这也许就是目前大部分javaer还是做着Crud Boy吧,限制了他们响应式的梦想 ... ...

当然非阻塞IO并不是银弹,如果你想用它来提升应用的访问效率,那么还是放弃吧,引用下面一段话,作为回答

Reactive and non-blocking generally do not make applications run faster.

WebFlux 并不能使接口的响应时间缩短,它仅仅能够提升吞吐量和伸缩性

所以如果你的应用是 IO密集型,还是很建议你试一试的。好了国际惯例TICSMTC...

Talk Is Cheap, Show Me The Code

我们本次应用的流程大体如下:创建一个路由用于生产数据,写入kafka里,然后再由注册的kafka消费者,消费该数据

引入依赖

这次demo使用了gradle代替了maven

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
implementation group: 'io.projectreactor.kafka', name: 'reactor-kafka', version: '1.3.4'
implementation group: 'org.springframework.kafka', name: 'spring-kafka', version: '2.7.4'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: '2.5.2'

构建实体

该实体,用于在kafka中传输

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package wang.datahub.dto;

public class Warehouse {
    private Long id;
    private String name;
    private String label;
    private String lon;
    private String lat;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public String getLon() {
        return lon;
    }

    public void setLon(String lon) {
        this.lon = lon;
    }

    public String getLat() {
        return lat;
    }

    public void setLat(String lat) {
        this.lat = lat;
    }

    @Override
    public String toString() {
        return "Warehouse{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", label='" + label + '\'' +
                ", lon='" + lon + '\'' +
                ", lat='" + lat + '\'' +
                '}';
    }
}

构建service

用于mock数据,并将对象发送至kafka

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package wang.datahub.service;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.reactive.ReactiveKafkaProducerTemplate;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import reactor.kafka.sender.SenderResult;
import wang.datahub.dto.Warehouse;

import java.util.Random;

@Service
public class WarehouseService {

    public static final String[] WAREHOUSE_NAME = new String[]{"天津仓库","北京仓库","上海仓库","广州仓库","深圳仓库"};
    public static final String[] WAREHOUSE_LEVEL = new String[]{"A级","B级","C级","D级","E级"};


    public Warehouse mock(long id) {
        Random random = new Random();
        try {
            Thread.sleep(random.nextInt(2000));
        } catch (InterruptedException e) {
        }

        Warehouse warehouse = new Warehouse();
        warehouse.setId(id);
        warehouse.setName(WAREHOUSE_NAME[random.nextInt(WAREHOUSE_NAME.length)]);
        warehouse.setLabel(WAREHOUSE_LEVEL[random.nextInt(WAREHOUSE_LEVEL.length)]);
        warehouse.setLon(random.nextDouble()+"");
        warehouse.setLat(random.nextDouble()+"");
        return warehouse;
    }


    @Autowired
    private ReactiveKafkaProducerTemplate template;

    public static final String WAREHOUSE_TOPIC = "warehouse";

    public Mono<Boolean> add(Warehouse warehouse) {
        Mono<SenderResult<Void>> resultMono = template.send(WAREHOUSE_TOPIC, warehouse.getId(), warehouse);
        return resultMono.flatMap(rs -> {
            if(rs.exception() != null) {
                System.out.println("send kafka error" + rs.exception());
                return Mono.just(false);
            }
            return Mono.just(true);
        });
    }


}

构建handler 并 注册 route

构建handler

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package wang.datahub.handler;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import wang.datahub.dto.User;
import wang.datahub.dto.Warehouse;
import wang.datahub.service.WarehouseService;

@Component
public class WarehouseHandler {
    @Autowired
    WarehouseService warehouseService;
    private long i = 1;
    public Mono<ServerResponse> addWarehouse(ServerRequest request) {
        //mock 数据
        Warehouse warehouse = warehouseService.mock(i++);
        Mono<Boolean> tag = warehouseService.add(warehouse);
        return ServerResponse.ok().body(tag,Boolean.class);
    }
}

注册route,用于访问

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package wang.datahub.route;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import wang.datahub.handler.UserHandler;
import wang.datahub.handler.WarehouseHandler;

@Configuration
public class Routes {

    @Autowired
    UserHandler userHandler;

    @Autowired
    WarehouseHandler warehouseHandler;

    @Bean
    public RouterFunction<ServerResponse> routersFunction(){
        return RouterFunctions
                .route(RequestPredicates.GET("/api/warehouse"),warehouseHandler::addWarehouse);
    }
}

构建kafka消费者

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package wang.datahub.kafka.consumer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
import org.springframework.kafka.core.reactive.ReactiveKafkaConsumerTemplate;
import org.springframework.stereotype.Service;
import reactor.kafka.receiver.ReceiverOptions;
import wang.datahub.dto.Warehouse;
import wang.datahub.service.WarehouseService;

import javax.annotation.PostConstruct;
import java.util.Collections;

@Service
public class WarehouseConsumer {
    @Autowired
    private KafkaProperties properties;

    @PostConstruct
    public void consumer() {
        ReceiverOptions<Long, Warehouse> options = ReceiverOptions.create(properties.getConsumer().buildProperties());
        options = options.subscription(Collections.singleton(WarehouseService.WAREHOUSE_TOPIC));
        new ReactiveKafkaConsumerTemplate(options)
                .receiveAutoAck()
                .subscribe(record -> {
                    System.out.println("Warehouse Record:" + record);
                });
    }
}

配置springboot的kafka信息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
spring:
  kafka:
    producer:
      bootstrap-servers: 172.18.70.184:9092
      key-serializer: org.apache.kafka.common.serialization.LongSerializer
      value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
    consumer:
      bootstrap-servers: 172.18.70.184:9092
      key-serializer: org.apache.kafka.common.serialization.LongSerializer
      value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
      group-id: warehouse-consumers

构建完整应用

加载kafka配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package wang.datahub;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.core.reactive.ReactiveKafkaProducerTemplate;
import reactor.kafka.sender.SenderOptions;

@Configuration
public class KafkaConfig {
    @Autowired
    private KafkaProperties properties;

    @Bean
    public ReactiveKafkaProducerTemplate reactiveKafkaProducerTemplate() {
        SenderOptions options = SenderOptions.create(properties.getProducer().buildProperties());
        ReactiveKafkaProducerTemplate template = new ReactiveKafkaProducerTemplate(options);
        return template;
    }
}

启动应用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package wang.datahub;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.reactive.config.EnableWebFlux;

@SpringBootApplication
@EnableWebFlux
public class WebfluxApplication {

    public static void main(String[] args) {
        SpringApplication.run(WebfluxApplication.class, args);
    }
}

kafka no zookeeper

启动kafka还需要额外的zk配置,是不是让你很不爽呢?2.8开始,kafka已经开始准备着手去掉外部zk了,尽管现在还不推荐上生产环境,至少是一个好的开始,下面我们简单的看下,如何抛弃zk

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 ⚡ root@DESKTOP-2J030JA  /mnt/e/devlop/envs/kafka_2.13-2.8.0  bin/kafka-storage.sh random-uuid
dKcraOLdTH6PCYuGizZ1nw
 ⚡ root@DESKTOP-2J030JA  /mnt/e/devlop/envs/kafka_2.13-2.8.0  bin/kafka-storage.sh format -t dKcraOLdTH6PCYuGizZ1nw -c config/kraft/server.properties
Formatting /tmp/kraft-combined-logs
 ⚡ root@DESKTOP-2J030JA  /mnt/e/devlop/envs/kafka_2.13-2.8.0  bin/kafka-server-start.sh  config/kraft/server.properties

完整代码库地址:https://github.com/dafei1288/reactor_kafka_springboot_demo

写在最后

之所以写了这篇文章,也是因为最近在读的这本书,刚读了2章,就被其吸引了,对反应式也开始有了兴趣,尽管这本书里面的案例都是scala和akka的,但是还是挺推荐读一读的

同时感谢群里的几位大佬的催更以及指点,排名不分先后

@superleo @简单 @箱子 @龙叁 @Jacob_Bishop @tofu @星辰 @sfq

感谢你能看到这里,如果本文对您有一点点帮助,希望您与我交流,也期待您的转发和关注支持。

参考链接

https://www.reactivemanifesto.org/zh-CN

https://www.cnblogs.com/quanxiaoha/p/10713782.html

https://blog.csdn.net/qq_28423433/article/details/81221933?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.control

https://www.cnblogs.com/niechen/p/9303451.htmlhttps://www.jianshu.com/p/15d0a2bed6da

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-07-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 麒思妙想 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Spring-webflux 响应式编程
Spring 提供了两个并行堆栈。一种是基于带有 Spring MVC 和 Spring Data 结构的 Servlet API。另一个是完全反应式堆栈,它利用了 Spring WebFlux 和 Spring Data 的反应式存储库。在这两种情况下,Spring Security 都提供了对两种堆栈的支持。
鱼找水需要时间
2023/02/16
1.6K0
Spring-webflux 响应式编程
Java一分钟之-Spring WebFlux:响应式编程
在Java的世界里,Spring框架一直扮演着举足轻重的角色。随着技术的演进,Spring也与时俱进地推出了支持响应式编程模型的Spring WebFlux框架。本文将带你快速入门Spring WebFlux,探讨其核心概念、常见问题、易错点及规避策略,并通过代码示例让你直观感受响应式编程的魅力。
Jimaks
2024/06/16
4400
Spring Boot从入门到精通-使用WebFlux进行响应式编程(1)
例如,在以往的编程方式中,定义了一个变量a=b+c。b和c在以后的程序中发生了变化,但是a的值却还是开始的值;但是在响应式编程中a的值却依然可以根据b和c进行改变。
我的小熊不见了丶
2019/05/22
1.8K0
SpringBoot使用WebFlux响应式编程操作数据库
在之前一篇简单介绍了WebFlux响应式编程的操作,我们在来看一下下图,可以看到,在目前的Spring WebFlux还没有支持类似Mysql这样的关系型数据库,所以本文以MongoDb数据库为例。
dalaoyang
2018/09/18
1.1K0
SpringBoot使用WebFlux响应式编程操作数据库
5分钟理解SpringBoot响应式的核心-Reactor
关于 响应式 Reactive,前面的两篇文章谈了不少概念,基本都离不开下面两点:
美码师
2019/09/16
6K0
5分钟理解SpringBoot响应式的核心-Reactor
艿艿连肝了几个周末,写了一篇贼长的 Spring 响应式 Web 框架 WebFlux!市面第二完整~
摘要: 原创出处 http://www.iocoder.cn/Spring-Boot/WebFlux/ 「芋道源码」欢迎转载,保留摘要,谢谢!
芋道源码
2020/06/01
6.2K0
Spring Reactive:响应式编程与WebFlux的深度探索
在当今高并发、实时性要求越来越高的应用场景中,响应式编程成为了一种非常有吸引力的编程范式。本文将深入探讨Spring Reactive和WebFlux,介绍响应式编程的核心概念、用法以及如何构建非阻塞的Web应用。
猫头虎
2024/04/09
1K0
Spring Boot 中的响应式编程和 WebFlux 入门
Spring 5.0 中发布了重量级组件 Webflux,拉起了响应式编程的规模使用序幕。
纯洁的微笑
2019/05/06
3.9K0
Spring Boot 中的响应式编程和 WebFlux 入门
Spring Boot 2 快速教程:WebFlux 快速入门(二)
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢!
二哥聊运营工具
2021/12/17
2.5K0
Spring Boot 2 快速教程:WebFlux 快速入门(二)
5分钟理解SpringBoot响应式的核心-Reactor
关于 响应式 Reactive,前面的两篇文章谈了不少概念,基本都离不开下面两点:
Java3y
2019/11/09
1.9K0
5分钟理解SpringBoot响应式的核心-Reactor
Spring Boot 2.0 WebFlux 上手系列课程:快速入门(一)
Spring Boot (Boot 顾名思义,是引导的意思)框架是用于简化 Spring 应用从搭建到开发的过程。应用开箱即用,只要通过一个指令,包括命令行 java-jar 、 SpringApplication 应用启动类 、 Spring Boot Maven 插件等,就可以启动应用了。另外,Spring Boot 强调只需要很少的配置文件,所以在开发生产级 Spring 应用中,让开发变得更加高效和简易。目前,Spring Boot 版本是 2.x 版本。Spring Boot 包括 WebFlux。
二哥聊运营工具
2021/12/17
1.2K0
Spring Boot 2.0 WebFlux 上手系列课程:快速入门(一)
Spring MVC 与 Spring Webflux 性能测试
本文翻译自国外论坛 medium,原文地址:本文翻译自国外论坛 medium,原文地址:https://medium.com/deno-the-complete-reference/spring-boot-vs-spring-webflux-performance-comparison-for-hello-world-case-386da4e9c418
wayn
2023/09/12
7550
Spring MVC 与 Spring Webflux 性能测试
(5)Spring WebFlux快速上手——响应式Spring的道法术器「建议收藏」
如上图所示,左侧为基于spring-webmvc的技术栈,右侧为基于spring-webflux的技术栈,
全栈程序员站长
2022/07/25
4.7K0
(5)Spring WebFlux快速上手——响应式Spring的道法术器「建议收藏」
深入剖析 Spring WebFlux
WebFlux 是 Spring Framework5.0 中引入的一种新的反应式Web框架。通过Reactor项目实现Reactive Streams规范,完全异步和非阻塞框架。本身不会加快程序执行速度,但在高并发情况下借助异步IO能够以少量而稳定的线程处理更高的吞吐,规避文件IO/网络IO阻塞带来的线程堆积。
冬夜先生
2021/10/12
1.3K0
Spring Boot 集成 WebFlux 开发 Reactive Web 应用Spring Boot 集成 WebFlux 开发 Reactive Web 应用
IBM的研究称,整个人类文明所获得的全部数据中,有90%是过去两年内产生的。在此背景下,包括NoSQL,Hadoop, Spark, Storm, Kylin在内的大批新技术应运而生。其中以RxJava和Reactor为代表的响应式(Reactive)编程技术针对的就是经典的大数据4V( Volume,Variety,Velocity,Value)中的Velocity,即高并发问题,而在Spring 5中,引入了响应式编程的支持。 本章介绍 Spring Boot 如何集成Spring 5 中的WebFlux 开发响应式 Web 应用。 1.1 响应式宣言
一个会写诗的程序员
2018/08/17
1.6K0
webflux提供响应式API
        响应式编程或反应式编程(英语:Reactive programming)是一种面向数据流和变化传播的编程范式,直白的说就是:将变化的值通过数据流进行传播。
kinbug [进阶者]
2019/06/13
3K0
异步编程 - 11 Spring WebFlux的异步非阻塞处理
我们这里主要探讨Spring框架5.0中引入的新的WebFlux技术栈,并介绍其存在的价值与意义、并发模型与适用场景、如何基于WebFlux实现异步编程,以及其内部的实现原理。
小小工匠
2023/09/09
2.6K0
异步编程 - 11 Spring WebFlux的异步非阻塞处理
翻译:SpringBoot下Elasticsearch响应式编程
最新版本的 Spring Data 中引入的更显着的特性之一是对 Elasticsearch 的响应式支持。自 Spring Data Moore 以来,我们可以利用响应式模板和存储库。它建立在基于 Spring WebClient 的完全反应式 Elasticsearch REST 客户端之上。还值得一提的是对响应式 Querydsl 的支持,可以通过 ReactiveQueryPredicateExecutor 将其包含到您的应用程序中
用户1233856
2022/08/01
9150
Spring Boot中的WebFlux编程模型
在现代的Web应用程序开发中,响应式编程模型越来越受欢迎,特别是对于需要处理大量并发请求和高吞吐量的场景。Spring Framework 提供了一个基于 Reactor 的库,称为 Spring WebFlux,它使得在 Spring Boot 应用中实现响应式编程变得轻松和高效。本文将深入探讨 Spring Boot 中的 WebFlux 编程模型,包括其原理、优势以及如何在项目中应用。
程序猿川子
2025/01/20
2470
Spring Boot中的WebFlux编程模型
SpringBoot中的响应式web应用
在Spring 5中,Spring MVC引入了webFlux的概念,webFlux的底层是基于reactor-netty来的,而reactor-netty又使用了Reactor库。
程序那些事
2020/11/17
1.5K0
SpringBoot中的响应式web应用
推荐阅读
相关推荐
Spring-webflux 响应式编程
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档