2、Spring Cloud Stream 函数式模型中 Supplier 是如何“主动推送”消息的?

Spring 源码硬核解析系列专题(二十八):Spring Cloud Function 的函数式编程源码解析 在前几期中,我们从 Spring 核心到 Spring Boot 的多个模块,再到 Spring Cloud Task,逐步揭示了 Spring 生态在微服务领域的广泛应用。Spring Cloud Function 提供了一个函数式编程模型,将业务逻辑抽象为函数,支持与消息系统、HTTP 等集成。本篇将深入 Spring Cloud Function 的源码,剖析其核心机制与实现原理,并补充 图示。 阅读详情

🔍 深度解析:Supplier 是如何“主动推送”消息的?频率?如何手动触发?

一、Supplier 是如何被“自动调用”的?—— 框架的“事件驱动”机制

✅ 核心结论:

Spring Cloud Stream 并非通过定时器轮询调用 Supplier,而是通过 Spring Integration 的 Polling Consumer 机制,在后台启动一个“轮询器”(Poller),周期性地调用 Supplier 的 get() 方法。

🧠 详细原理:

1. Supplier 是一个“消息源”(Message Source)

在 Spring Cloud Stream 中,Supplier<T> 被框架包装成一个 MessageSource<T> 实例,注册为 Spring Integration 的 Polling Consumer 的源。

  • 当你声明:
    @Bean
    public Supplier<Order> orderSupplier() {
        return () -> new Order("ORD-123", "iPhone", 9999L);
    }
    
  • 框架会自动创建一个 IntegrationFlow,结构如下:
IntegrationFlow flow = IntegrationFlow.from(orderSupplier, 
    c -> c.poller(Pollers.fixedDelay(5000))) // 默认5秒轮询
    .channel("orderSupplier-out-0")
    .get();

📌 关键点:Supplier 不是“事件驱动”(如 HTTP 请求触发),而是被动轮询(Polling)触发!

2. 轮询器(Poller)是核心
  • Spring Integration 默认使用 Poller(轮询器)定期调用 Supplier.get()。
  • 每次调用 get(),如果返回非 null 值,框架会将其封装为 Message<T>,并发送到绑定的输出通道(orderSupplier-out-0),最终写入 Kafka/RabbitMQ。
  • 如果返回 null,则不发送任何消息(相当于“跳过本次轮询”)。
3. 为什么不是“事件驱动”?
  • 消息队列(Kafka/RabbitMQ)是异步、解耦、持久化的系统。
  • “事件驱动”通常指外部事件(如 REST 请求、数据库变更)触发消息发送。
  • 而 Supplier 的设计目标是:周期性地产生事件(如定时上报心跳、定时生成统计、定时拉取数据)。
  • 如果你想“由外部事件触发”,你应该使用 StreamBridge(见后文)。

💡 类比:Supplier 就像一个“定时任务”(@Scheduled),只不过它自动把结果发到消息队列。


二、频率是怎样的?如何配置轮询间隔?

✅ 默认频率:5 秒

Spring Cloud Stream 的默认轮询间隔是 5000 毫秒(5秒)。

✅ 如何修改轮询频率?

方法 1:通过配置文件(推荐)
spring:
  cloud:
    stream:
      bindings:
        orderSupplier-out-0:
          destination: orders-created
          content-type: application/json
          producer:
            # ⬇️ 关键配置:设置轮询间隔(单位:毫秒)
            poller:
              fixed-delay: 2000   # 每2秒调用一次 Supplier.get()
              max-messages-per-poll: 1 # 每次轮询最多发送1条消息(默认1)

✅ producer.poller.fixed-delay 是控制 Supplier 调用频率的唯一方式!

方法 2:通过 Java 配置(高级,更灵活)

如果你需要更复杂的轮询策略(如固定速率、自定义错误处理),可以自定义 Poller:

@Bean
public Supplier<Order> orderSupplier() {
    return () -> new Order("ORD-" + System.currentTimeMillis(), "iPhone", 9999L);
}

@Bean
public IntegrationFlow orderSupplierFlow(Supplier<Order> supplier) {
    return IntegrationFlow.from(supplier, 
        c -> c.poller(Pollers.fixedDelay(1000) // 1秒
                      .maxMessagesPerPoll(1)
                      .errorHandler(error -> System.err.println("Supplier调用失败: " + error.getMessage()))))
        .channel("orderSupplier-out-0")
        .get();
}

⚠️ 注意:使用 Java 配置时,必须确保绑定名称与函数名一致(orderSupplier-out-0),否则框架会创建两个通道,导致消息重复或丢失。

✅ 常用轮询配置选项:
配置项说明示例
fixed-delay固定延迟轮询(推荐)2000(2秒)
fixed-rate固定速率轮询(从上一次开始计时)1000(每秒一次)
cron使用 Cron 表达式(如每天凌晨)"0 0 2 * * ?"(每天2点)
max-messages-per-poll每次轮询最多发送多少条5(批量发送)
trigger自定义触发器(如基于时间窗口)需实现 Trigger 接口

📌 推荐使用 fixed-delay:它确保每次调用完成后,等待指定时间再下一次调用,避免堆积。

✅ 示例:每天凌晨 2 点生成日统计报告
spring:
  cloud:
    stream:
      bindings:
        dailyReportSupplier-out-0:
          producer:
            poller:
              cron: "0 0 2 * * ?" # 每天2:00:00
@Bean
public Supplier<Report> dailyReportSupplier() {
    return () -> {
        // 生成昨日订单统计
        return new Report(LocalDate.now().minusDays(1), orderService.countYesterdayOrders());
    };
}

三、如何实现“手动发送消息”?—— 用 StreamBridge!

❌ 误区:不能直接调用 supplier.get() 手动触发!

你不能在 Controller 里这样写:

@RestController
class OrderController {

    @Autowired
    private Supplier<Order> supplier; // ❌ 错误!这是个函数,不是服务

    @PostMapping("/create-order")
    public void createOrder(@RequestBody Order order) {
        supplier.get(); // ❌ 这只会调用一次,但不会发送到 Kafka!
        // 因为 Supplier 的调用是被 Poller 控制的,你调用它不会触发绑定通道
    }
}

✅ 正确做法:使用 StreamBridge

StreamBridge 是 Spring Cloud Stream 提供的官方 API,用于在运行时、手动、按需向绑定通道发送消息。

1. 注入 StreamBridge
@RestController
@RequestMapping("/api/orders")
public class OrderController {

    @Autowired
    private StreamBridge streamBridge; // ✅ 官方推荐的“手动发送”工具

    @PostMapping
    public ResponseEntity<String> createOrder(@RequestBody Order order) {
        // ✅ 手动发送消息到名为 "orders-created" 的绑定通道
        boolean sent = streamBridge.send("orders-created", order);

        if (sent) {
            return ResponseEntity.ok("订单已发送到消息队列");
        } else {
            return ResponseEntity.status(500).body("发送失败");
        }
    }
}
2. 为什么 StreamBridge 能手动发送?
  • StreamBridge 内部封装了 Spring Integration 的 MessageChannel。
  • 它直接调用 messageChannel.send(message),绕过轮询器,实现即时、同步、按需发送。
  • 它不依赖 Supplier,完全独立。
3. StreamBridge 支持多种发送方式:
方法用途
send(String bindingName, Object payload)发送普通对象(自动序列化)
send(String bindingName, Message<?> message)发送完整 Message(可自定义 header)
send(String bindingName, Object payload, Map<String, Object> headers)发送带自定义 header 的消息
✅ 示例:发送带自定义 Header 的消息(用于追踪)
@PostMapping("/create-order-with-trace")
public ResponseEntity<String> createOrderWithTrace(@RequestBody Order order) {
    Map<String, Object> headers = Map.of(
        "trace-id", UUID.randomUUID().toString(),
        "source", "order-service"
    );

    boolean sent = streamBridge.send("orders-created", order, headers);

    return ResponseEntity.ok(sent ? "已发送" : "失败");
}
✅ 示例:发送 Message 对象(完全控制)
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;

@PostMapping("/create-order-as-message")
public ResponseEntity<String> createOrderAsMessage(@RequestBody Order order) {
    Message<Order> message = MessageBuilder
        .withPayload(order)
        .setHeader("correlation-id", "C12345")
        .setHeader("priority", 1)
        .build();

    boolean sent = streamBridge.send("orders-created", message);
    return ResponseEntity.ok(sent ? "成功" : "失败");
}

四、Supplier vs StreamBridge:使用场景对比

场景推荐方案原因
✅ 定时生成事件(如每分钟上报系统状态)Supplier自动轮询,无需人工干预
✅ 每日生成统计报表Supplier + cron配置简单,适合定时任务
✅ 用户下单后立即发送订单事件StreamBridge必须“立即”响应,不能等5秒
✅ REST API 触发事件StreamBridge用户请求 → 立即发消息
✅ 数据库变更后发送 CDC 事件(如 Debezium)StreamBridge由监听器触发,非周期性
✅ 批量处理后发送多条消息StreamBridge + 循环可控制发送时机和数量

✅ 黄金法则:

  • 周期性、自动化 → 用 Supplier
  • 用户触发、即时响应 → 用 StreamBridge

五、实战:结合 Supplier + StreamBridge 构建完整订单系统

// 1. 定时生成测试订单(Supplier)
@Bean
public Supplier<Order> orderSupplier() {
    return () -> {
        // 模拟每3秒生成一个测试订单(用于演示)
        return new Order("TEST-" + System.nanoTime(), "测试商品", 100L);
    };
}

// 2. 手动创建真实订单(StreamBridge)
@RestController
public class OrderController {

    @Autowired
    private StreamBridge streamBridge;

    @PostMapping("/orders")
    public ResponseEntity<String> createOrder(@RequestBody Order order) {
        // ✅ 手动发送真实订单事件
        boolean sent = streamBridge.send("orders-created", order);
        if (sent) {
            return ResponseEntity.ok("订单已创建,事件已发送");
        }
        return ResponseEntity.status(500).body("发送失败");
    }
}

// 3. 消费者(统一处理所有订单)
@Bean
public Consumer<Order> orderConsumer() {
    return order -> {
        System.out.println("✅ 收到订单: " + order);
        // 扣库存、发通知、写数据库...
    };
}

✅ 配置文件(application.yml)

spring:
  cloud:
    stream:
      bindings:
        orderSupplier-out-0:
          destination: orders-created
          producer:
            poller:
              fixed-delay: 3000  # 每3秒生成一个测试订单

        # 注意:Supplier 和 StreamBridge 使用同一个 destination
        # orderConsumer-in-0 也绑定到 orders-created
        orderConsumer-in-0:
          destination: orders-created
          group: order-consumer-group

      kafka:
        binder:
          brokers: localhost:9092
          configuration:
            auto.create.topics.enable: true
            key.serializer: org.apache.kafka.common.serialization.StringSerializer
            value.serializer: org.springframework.kafka.support.serializer.JsonSerializer
            key.deserializer: org.apache.kafka.common.serialization.StringDeserializer
            value.deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
            spring.json.trusted.packages: com.example.model

📊 运行效果:

  • 每3秒:Supplier 自动发送一条 TEST-xxx 订单
  • 你调用 POST /orders:发送一条真实订单
  • 所有订单都被同一个 orderConsumer 消费

✅ 你实现了“自动 + 手动”双通道事件生产,完美解耦!


六、进阶:如何实现“只在特定条件下发送”?

你可能希望:只有当订单金额 > 1000 时才发送。

✅ 方案1:在 Supplier 中过滤(适用于周期性场景)

@Bean
public Supplier<Order> orderSupplier() {
    return () -> {
        Order order = generateRandomOrder(); // 生成随机订单
        return order.price() > 1000 ? order : null; // ✅ 只发送高价值订单
    };
}

✅ 方案2:在 Controller 中判断(适用于手动触发)

@PostMapping("/orders")
public ResponseEntity<String> createOrder(@RequestBody Order order) {
    if (order.price() < 1000) {
        return ResponseEntity.badRequest().body("订单金额需大于1000");
    }
    boolean sent = streamBridge.send("orders-created", order);
    return ResponseEntity.ok(sent ? "发送成功" : "发送失败");
}

✅ 业务逻辑应放在 Controller 或 Service 层,而不是绑定层。


七、性能与注意事项

问题建议
Supplier 轮询太频繁?避免低于 1000ms,防止 Kafka 压力过大
StreamBridge 发送失败?默认是同步发送,若 Kafka 不可达会抛异常 → 建议加 try-catch 或使用异步发送
如何异步发送?streamBridge.send() 是同步的。若需异步,可包装在 @Async 方法中
如何监控发送成功率?启用 Actuator,查看 stream.outbound.orders-created.messages 指标
Supplier 返回 null 会怎样?框架忽略,不发送消息,不报错,不计数
多个 Supplier?每个 Supplier 必须有唯一绑定名(supplier1-out-0, supplier2-out-0)

✅ 总结:Supplier 的真相与最佳实践

问题答案
Supplier 是怎么被调用的?由 Spring Integration 的 Poller 周期性调用,不是事件驱动,也不是定时器注解(@Scheduled)
默认频率是多少?5 秒(可通过 producer.poller.fixed-delay 修改)
如何手动发送?使用 StreamBridge.send("bindingName", payload),这是官方推荐方式
Supplier 和 StreamBridge 如何选择?定时任务 → Supplier;用户请求/外部事件 → StreamBridge
能用 @Scheduled 替代 Supplier 吗?可以,但不推荐 —— Supplier 更符合 Stream 的抽象模型,且自动集成监控和绑定
Supplier 返回 null 会被记录吗?不会,不会发送消息,也不会计入指标
如何实现“只在条件满足时发送”?在 Supplier 中返回 null,或在 Controller 中校验后调用 StreamBridge

🚀 最佳实践总结(一句话版)

“用 Supplier 做定时事件,用 StreamBridge 做即时事件,别混用,别手动调 Supplier.get()。”


🔗 推荐阅读


Spring Cloud Stream:构建消息驱动的微服务应用 Spring Cloud Stream是用于构建消息驱动的的微服务程序的框架。Spring Cloud Stream以Spring Boot为基础,可以构建独立的、生产级别的Spring应用程序。它通过Spring Integration可以支持多种消息中间件,并且屏蔽了不同消息中间件的底层操作,可以用同种方式来操作不同的消息中间件,同时引入了持久的发布-订阅、消费者组和分区的概念。 阅读详情

相关推荐

实战教程:用DETR+超分辨率搞定红外小目标检测(附完整代码)

本文提供了一套完整的红外小目标检测实战方案,通过融合EDSR超分辨率技术与改进型DETR深度学习算法,有效解决了红外图像中小目标检测的难题。文章详细介绍了从环境搭建、数据预处理、模型定制(如引入EMA注意力与S2特征层)到训练调优的全流程,并附有完整代码,旨在帮助开发者将前沿算法高效落地于安防、自动驾驶等实际场景。

weixin_29057163的博客 531

java stream supplier_Java8之Stream流(六)收集

我们前面的五篇文章基本都是在说将一个集合转成一个流,然后对流进行操作,其实这种操作是最多的,但有时候我们也是需要从流中收集起一些元素,并以集合的方式返回,我们把这种反向操作称为收集。流API也给我们提供了相应的方法。如何在流中使用收集功能?我们先看一看流API给我们提供的方法:public interface Stream extends BaseStream> {//...忽略那些不重要的...

weixin_39874809的博客 1158

Hypermesh联合ABAQUS—Sets的建立和编辑

打开part copy对话框在对话框的最上面位置可以输入copy后的名称,然后将最下面的Separate disconnected regions into parts(将不连续的区域分割成parts)选项的前面方框勾选上。打开abaqus软件界面,File→import→model,将file filter选为inp格式,找到要导入的有限元文件,单击OK导入文件。HyperWorks新建Set时,会在Model Browser显示,打开Create Set对话框显示详细信息。快捷键,高亮set的内容。

动力资料屋的博客 1289

Java:Stream三部曲(一):函数式接口的理解与常用示例(Runnable、Comparator、Callable、Consumer、Predicate、Supplier、Function)

Stream流处理器入门第一步——函数式接口。本文主要包含关于函数式接口的简略基础概念、个人学习过程中的一些理解以及对当前JDK中内置的主要函数式接口的用法解析(包括Runnable、Comparator、Callable、Consumer、Predicate、Supplier、Function)。

whx6666666的博客 3032

WPS Office 2019 For Linux二次开发全流程:从源码下载到Demo运行

本文详细介绍了在Linux环境下进行WPS Office 2019 C++二次开发的全流程,涵盖从开发环境准备、源码获取、核心依赖(Qt与WPS)安装配置,到最终编译运行官方Demo的完整步骤。文章重点解析了环境搭建中的常见问题与解决方案,旨在帮助开发者快速上手WPS二次开发。

weixin_29001423的博客 388

【VS Code+Verilog+Vivado使用】(1)常用插件

VS Code + Verilog + Vivado联合使用说明

XDUryan的博客 5635

[译] 一文带你玩转 Java8 Stream 流,从此操作集合 So Easy

本文翻译自 winterbe.com/posts/2014/… 作者: @Winterbe 欢迎关注个人微信公众号: 小哈学Java,即可免费无套路领取10G面试学习资料哦,文末资料截图。 个人网站: www.exception.site/java8/java8… Stream 流可以说是 Java8 新特性中用起来最爽的一个功能了,有了它,从此操作集合告别繁琐的 for 循环。但是还有很多小...

weixin_33908217的博客 455

vivado下ECO操作-不重新综合实现修改属性并生成.bit

ECO即engineer change order,即工程变更指令,可以对设计做局部小改动并只对改动部分重新布局布线并生成.bit。在一个工程动辄编译几个小时情况下,可以在调试中节省大量时间。比如我们在调试中,需要改变时钟占空比或者相位,需要改变寄存器初值等等,此时用ECO暂时改动,待验证后在重新编译无疑是最有效率的方法。 实现ECO通常有两种方式,一是通过vivado界面完成,另一种方法就是tcl脚本。所有的ECO操作都可以通过tcl操作完成,有的操作用vivado界面无法完成,只能通过tcl。以下主要

4656

Stream流的使用详解(以及Optional类型,Supplier,Stream.generate(),Collectors.groupingBy(),通用函数接口)

内容转自:https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/ 流的使用详解 简单说,对 Stream 的使用就是实现一个 filter-map-reduce 过程,产生一个最终结果,或者导致一个副作用(side effect)。 流的构造与转换 构造流的几种常见方法: // 1. Individual values Str...

学习中 8581

知识推理——TransE(知识表示、知识嵌入)

知识图谱嵌入/表示方法 TransE

missyoudaisy的博客 1831

Unreal Engine Profiler:动画系统性能分析教程_2024-07-23_03-05-38.Tex

Unreal Engine Profiler 是一个内置的性能分析工具,它可以帮助开发者识别和解决游戏中的性能瓶颈。Profiler 提供了详细的性能数据,包括 CPU 使用率、GPU 负载、内存使用情况等,特别针对动画系统,可以查看动画蓝图的执行时间、骨骼动画的计算成本、以及动画混合和重定向的效率。通过这些数据,开发者可以定位到具体的问题,比如哪些动画状态消耗了过多的 CPU 时间,或者哪些动画资源导致了内存泄漏。

823

java8之stream

本文采用实例驱动的方式,对JAVA8的stream API进行一个深入的介绍。虽然JAVA8中的stream API与JAVA I/O中的InputStream和OutputStream在名字上比较类似,但是其实是另外一个东西,Stream API是JAVA函数式编程中的一个重要组成部分。 本文描述如何使用JAVA8的Stream API。通过本文,你可以了解Stream API的执行顺序,不同的...

Humbinal's Blog 592

YOLO11涨点优化:注意力魔改 | 引入Deformable Attention (可变形注意力),灵活感受野自适应复杂形变目标

Deformable Attention为YOLO11带来的不仅是2.6个百分点的mAP提升,更是一种全新的“形变感知”范式。标准卷积的固定感受野在非刚性目标、多尺度变化和遮挡场景下力不从心——Deformable Attention恰好填补了这一空白。从架构设计到代码实现,从竞品对比到部署方案,从生态工具到安全风险,本文覆盖了将Deformable Attention引入YOLO11所需的全部知识链路。

2601_95807009的博客 284

1、Spring Cloud Stream 官方函数式编程模型完全指南

Spring Cloud Stream 函数式编程指南 核心要点 框架定位:Spring Cloud Stream 是消息驱动微服务的统一编程模型,支持 Kafka/RabbitMQ 等中间件,实现业务与消息系统的解耦 编程模型:3.0+版本全面采用函数式接口(Supplier/Function/Consumer),替代传统注解方式 核心价值: ✅ 中间件无关性 ✅ 自动处理绑定/序列化/重试 ✅ 内置云原生特性(监控/弹性) 适用场景:事件驱动架构、服务解耦、削峰填谷、数据同步等异步处理场景 函数式开发模

python15397的博客 1383

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

spring cloud stream 使用rocket笔记

趁着打算重新找工作,刚好把之前的笔记整理整理,这篇笔记是当初在使用stream 连接rocketmq时的一些笔记 当时我们用的spring cloud stream 版本是3.1,当我去向往常一样去用注解绑定通道时@EnableBinding(),我的编译器亲切的告诉我这个注解已经被废弃了?way? Enables the binding of targets annotated with Input and Output to a broker, according to the list of inte

z357904947的博客 1105

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Spring cloud stream实现Kafka的消息收发

用Spring cloud stream可以很方便的实现对Kafka消息的收发,以下是我按照Spring官网的例子实现的一个Kafka的应用。 这个例子是实现一个电信公司收集用户消费电信服务,并计算费用的场景。包括了三个应用程序。

2367

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

spring cloud stream 3.1 @StreamListener 官方不建议使用了

零、前言 这又是学习尚硅谷 spring cloud中遇到的一个坑 因为之前有一个 所以这里索引从2开始 2、spring cloud stream 3.1 @StreamListener 官方不建议使用了 在使用stream 整合rabbitMQ的时候 突然发现新版本不建议使用@Binding(Source.class) 、@StreamListener(Sink.class) 查看了 [官方文档][https://docs.spring.io/spring-cloud-stream/docs/3.1.0

qq_35799668的博客 1万+

spring cloud stream 学习

spring cloud stream 学习 基于《spring cloud stream 3.1.x》 在学习spring cloud stream 之前, 先要了解一下 spring cloud function 模块, 新版采用 function 函数 引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-star

面朝大海,春暖花开 2274

Spring cloud stream 3.1 rocketmq踩坑记录

spring cloud stream 新绑定方式 新版spring cloud stream文档 新版提倡用函数式进行发送和消费信息 定义返回类型为Supplier, Function or Consumer的bean提供消息发送和消费的bean 看看绑定名称命名规则 input - + -in- + output - + -out- + 在配置文件中指定spring.cloud.function.definition的名称后会把这个bean绑定到对应的消费者和提供者上. 如下定义 会把bea

qq_42830797的博客 2635

Spring Cloud Stream

核心概念 应用模型 应用通过Binder与消息队列绑定在一起,Binder由SpringCloud实现或第三方实现,例如:Spring Cloud Alibaba RocketMQ Binder, 你的代码通过inputs和outputs(它们都称为bindings,下文做详细介绍)与Binder相连接。 destination binder 与外部消息系统通信的组件,为构造 Binding提供了 2 个方法,分别是 bindConsumer 和 bindProducer ,它们分别用于构造生产者和消费者

qq_19266669的博客 605

Spring Cloud Stream:微服务流式数据处理的抽象层与实战指南

在微服务架构中,服务间通信是核心挑战之一。传统的同步调用模式在处理高吞吐、低延迟的实时数据流时,往往面临性能瓶颈和紧密耦合的问题。流式数据处理技术通过异步、解耦的消息传递机制,让数据能够像水流一样持续、可靠地在服务间流动,从而支撑起事件驱动架构、实时分析等关键场景。Spring Cloud Stream作为Spring生态中的关键抽象框架,通过统一的编程模型屏蔽了Kafka、RabbitMQ等不同消息中间件的底层差异,让开发者能够专注于业务逻辑的实现。本文深入解析其核心抽象模型,并结合函数式编程、消费者组、

weixin_33892359的博客 448

Spring Cloud Stream使用

Spring Cloud Stream对Spring Cloud体系中的Mq进⾏了很好的上层抽象,可以让我们与具体消息中间件解耦合,屏蔽掉了底层具体MQ消息中间件的细节差异,就像Hibernate屏蔽掉了具体数据库(Mysql/Oracle⼀样)。如此⼀来,我们学习、开发、维护MQ都会变得轻松。⽬前Spring Cloud Stream原生⽀持RabbitMQ和Kafka,阿里在这个基础上提供了RocketMQ的支持,简单使用Spring Cloud Stream 构建基于RocketMQ的生产者和消费者。

cristianoxm的博客 2033

Spring Cloud Function 是 Spring 生态中用于将业务逻辑封装为函数式编程模型的模块

Spring Cloud Function 是 Spring 生态中用于将业务逻辑封装为函数式编程模型的模块,它支持将函数(Function)、消费者(Consumer)和供应者(Supplier)作为一等公民进行开发,并能够轻松部署到云原生环境(如 FaaS 平台:AWS Lambda、Azure Functions、Google Cloud Functions 等)。

[Blog][Domain] programb.blog.youkuaiyun.com 396

Spring Cloud Stream 函数式编程整合 kafka/rabbit

Spring Cloud Stream 是一个用于构建与共享消息传递系统连接的高度可伸缩的事件驱动微服务的框架。 该框架提供了一个灵活的编程模型,该模型基于已经建立和熟悉的 Spring 习惯用法和最佳实践,包括对持久化的 pub/sub 语义、消费者组和有状态分区的支持。 这里记录下Spring Cloud Stream 3.1版本的实现。@StreamListener 等注解在3.1版本后不建议使用推荐使用,摸索官方文档发现使用新的写法,使用java.util.function.[Supplier/Fu

小七的编程日志 3422

Spring Cloud Stream 作为 Spring 生态的分布式消息驱动框架,其 **函数式编程模型** 与 **响应式编程能力** 的深度融合

Spring Cloud Stream 作为 Spring 生态的分布式消息驱动框架,其 **函数式编程模型** 与 **响应式编程能力** 的深度融合,彻底革新了微服务间异步通信的开发模式。这种融合既保留了函数式的简洁性(无感知绑定消息通道),又具备响应式的高吞吐、非阻塞特性(适配海量数据流场景),完美匹配交通行业(如高速公路收费数据同步、施工路段传感器数据采集)的核心需求。以下从 **技术融合原理、实战指南、交通行业落地场景** 三个维度展开结构化解析,附可直接复用的配置模板与性能优化方案:

[Blog][Domain] programb.blog.youkuaiyun.com 607

spring Cloud Stream 实战应用深度讲解

spring cloud stream是一个框架,用于构建与共享消息传递系统连接的高度可扩展的事件驱动微服务。该框架提供了一个灵活的编程模型,该模型建立在已经建立和熟悉的 Spring 习惯用语和最佳实践之上,包括对持久发布/订阅语义、消费者组和有状态分区的支持。核心模块。

大头讲架构的博客 3239
上一篇: 1、Spring Cloud Stream 官方函数式编程模型完全指南
下一篇: 3、Spring Cloud Stream + RocketMQ 高级消息特性完全指南
龙茶清欢
博客等级 码龄7年 3720粉丝 375原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值