spring cloud stream整合
spring cloud stream整体架构核心概念图:
图一:消息的发送端和接收端可以是不同的中间件

图二:

图三:在消息的发送之前和消息的接收端套了一层管道

- @Output:输出注释,用于定义发送消息接口
- @Input:输入注解,用于定义消息的消费者接口
- @StreamListener:用于定义监听方法的注解
springcloudstream框架有一个非常大的问题就是不能实现可靠性消息投递,会存在少量消息丢失的问题
这个原因是springcloudstream框架为了和kafka兼顾所以在实际工作中使用它的目的是针对高性能的消息通信的
这点就是当前版本的springcloudstream的定位
Barista接口是定义作为后面类的参数,这一接口来定义通道类型和通道名称(该名称可以自定义)
通道名称是作为配置用,通道类型则决定了app会使用这一通道进行发送消息还是从中接收消息
引入pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dwz</groupId>
<artifactId>rabbitmq-springcloudstream-producer</artifactId>
<version>0.0.1-SNAPSHOT</version> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
</properties> <dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.6.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp-client -->
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.7.3</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.0</version>
</dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.0</version>
</dependency> <!--spring boot热部署插件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-stream-rabbit -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
<version>2.1.4.RELEASE</version>
</dependency> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
生产者代码
配置application.properties
server.port=8001
server.servlet.context-path=/producer spring.application.name=producer
spring.cloud.stream.bindings.output_channel.destination=exchange-4
spring.cloud.stream.bindings.output_channel.group=queue-4
spring.cloud.stream.bindings.output_channel.binder=rabbit_cluster #表明使用的环境是rabbit
spring.cloud.stream.binders.rabbit_cluster.type=rabbit
spring.cloud.stream.binders.rabbit_cluster.environment.spring.rabbitmq.addresses=127.0.0.1:5672
spring.cloud.stream.binders.rabbit_cluster.environment.spring.rabbitmq.username=root_dwz
spring.cloud.stream.binders.rabbit_cluster.environment.spring.rabbitmq.password=123456
spring.cloud.stream.binders.rabbit_cluster.environment.spring.rabbitmq.virtual-host=/vhost_dwz
Barista接口
package com.dwz.rabbitmq.stream; import org.springframework.cloud.stream.annotation.Output;
import org.springframework.messaging.MessageChannel;
public interface Barista { String OUTPUT_CHANNEL = "output_channel"; //注解@Output表明了它是一个输出类型的通道类,名字output_channel。这一名字与app1中通道名一致,表明注入了
//一个名字为output_channel的通道
@Output(Barista.OUTPUT_CHANNEL)
MessageChannel logoutput();
}
发送消息的方法
package com.dwz.rabbitmq.stream; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service; @EnableBinding(Barista.class)
@Service
public class RabbitmqSender {
@Autowired
private Barista barista; //发送消息
public String sendMessage(Object message, Map<String, Object> properties) throws Exception {
try {
MessageHeaders mhs = new MessageHeaders(properties);
Message msg = MessageBuilder.createMessage(message, mhs);
boolean sendStatus = barista.logoutput().send(msg);
System.err.println("-------------------sending---------------------");
System.err.println("发送数据:" + message + ",sendStatus:" + sendStatus);
return null;
} catch (Exception e) {
System.err.println("---------------------error--------------------------");
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
}
测试代码
package com.dwz.rabbitmq; import java.util.Date;
import java.util.HashMap;
import java.util.Map; import org.apache.http.client.utils.DateUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import com.dwz.rabbitmq.stream.RabbitmqSender;
@RunWith(SpringRunner.class)
@SpringBootTest
public class Testdd { @Autowired
private RabbitmqSender rabbitmqSender; @Test
public void sendMessageTest1() {
for(int i = 0; i < 5; i++) {
try {
Map<String, Object> properties = new HashMap<>();
properties.put("SERIAL_NUMBER", "12345");
properties.put("BANK_NUMBER", "abc");
properties.put("PLAT_SEND_TIME", DateUtils.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss:SSS"));
rabbitmqSender.sendMessage("Hello, I am amqp sender num:" + i, properties);
} catch (Exception e) {
System.err.println("------------------error-------------------");
e.printStackTrace();
}
}
}
}
消费端代码
配置application.properties
server.port=8002
server.servlet.context-path=/consumer spring.application.name=consumer
spring.cloud.stream.bindings.input_channel.destination=exchange-4
spring.cloud.stream.bindings.input_channel.group=queue-4
spring.cloud.stream.bindings.input_channel.binder=rabbit_cluster
spring.cloud.stream.bindings.input_channel.consumer.concurrency=1
spring.cloud.stream.rabbit.bindings.input_channel.consumer.requeue-rejected=false
spring.cloud.stream.rabbit.bindings.input_channel.consumer.acknowledge-mode=manual
#设置断开重连
spring.cloud.stream.rabbit.bindings.input_channel.consumer.recovery-interval=3000
#启用持久化订阅
spring.cloud.stream.rabbit.bindings.input_channel.consumer.durable-subscription=true
#设置最大监听数
spring.cloud.stream.rabbit.bindings.input_channel.consumer.max-concurrency=5 spring.cloud.stream.binders.rabbit_cluster.type=rabbit
spring.cloud.stream.binders.rabbit_cluster.environment.spring.rabbitmq.addresses=127.0.0.1:5672
spring.cloud.stream.binders.rabbit_cluster.environment.spring.rabbitmq.username=root_dwz
spring.cloud.stream.binders.rabbit_cluster.environment.spring.rabbitmq.password=123456
spring.cloud.stream.binders.rabbit_cluster.environment.spring.rabbitmq.virtual-host=/vhost_dwz
Barista接口
package com.dwz.rabbitmq.stream; import org.springframework.cloud.stream.annotation.Input;
import org.springframework.messaging.SubscribableChannel; public interface Barista { String INPUT_CHANNEL = "input_channel"; //注解@Input声明了它是一个输入类型的通道,名字是input_channel
@Input(Barista.INPUT_CHANNEL)
SubscribableChannel loginput();
}
接收消息的方法
package com.dwz.rabbitmq.stream; import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component; import com.rabbitmq.client.Channel; @EnableBinding(Barista.class)
@Component
public class RabbitmqReceiver { @StreamListener(Barista.INPUT_CHANNEL)
public void receiver(Message message) throws Exception {
Channel channel = (Channel)message.getHeaders().get(AmqpHeaders.CHANNEL);
Long deliveryTag = (Long)message.getHeaders().get(AmqpHeaders.DELIVERY_TAG);
System.err.println("Input Stream 1 接受数据:" + message);
System.err.println("消费完毕---------------");
channel.basicAck(deliveryTag, false);
}
}
spring cloud stream整合的更多相关文章
- Spring Cloud Alibaba - Spring Cloud Stream 整合 RocketMQ
Spring Cloud Stream 简介 在微服务的开发过程中,可能会经常用到消息中间件,通过消息中间件在服务与服务之间传递消息,不管你使用的是哪款消息中间件,比如RabbitMQ.Kafka和R ...
- Spring Cloud Stream整合RabbitMQ
简介 Spring Cloud Stream是一个构建消息驱动微服务的框架,应用程序通过input(相当于consumer).output(相当于producer)来与Spring Cloud Str ...
- Spring Cloud Stream 整合 RabbitMQ
简介 Spring Cloud Stream是一个构建消息驱动微服务的框架,应用程序通过input(相当于consumer).output(相当于producer)来与Spring Cloud Str ...
- RabbitMQ与Spring的框架整合之Spring Cloud Stream实战
1.RabbitMQ与Spring Cloud Stream整合实战.SpringCloud Stream整体结构核心概念图,如下所示: 图示解释:Outputs输出,即消息的发送端.Inputs输入 ...
- 整合Spring Cloud Stream Binder与RabbitMQ进行消息发送与接收
我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 前言 Spring Cloud Stream专门用于事件驱动的微服务系统,使用消息中间件来收发信息.使用Spring ...
- 整合Spring Cloud Stream Binder与GCP Pubsub进行消息发送与接收
我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 前言 之前的文章<整合Spring Cloud Stream Binder与RabbitMQ进行消息发送与接收& ...
- Spring Cloud Stream消费失败后的处理策略(一):自动重试
之前写了几篇关于Spring Cloud Stream使用中的常见问题,比如: 如何处理消息重复消费 如何消费自己生产的消息 下面几天就集中来详细聊聊,当消息消费失败之后该如何处理的几种方式.不过不论 ...
- 第十章 消息驱动的微服务: Spring Cloud Stream
Spring Cloud Stream 是一个用来为微服务应用构建消息驱动能力的框架. 它可以基于Spring Boot 来创建独立的. 可用于生产的 Spring 应用程序. 它通过使用 Sprin ...
- SpringCloud---消息驱动的微服务---Spring Cloud Stream
1.概述 1.1 Spring Cloud Stream:用来 为微服务应用 构建 消息驱动能力的框架: 可基于SpringBoot来创建独立.可用于生产的Spring应用程序: 使用Sp ...
随机推荐
- 怎样禁止 html 中 <textarea> 标签可以拉伸改变大小 ?
1. 一般来说, 使用 <textarea> 这个标签都会禁用掉它的这个默认属性, 不然可能会被用户玩儿坏, 而且也不利于其他元素的展示, 使用到的属性是 resize , 改为 none ...
- Eclipse怎么升级版本
java工程上右键——选择Properties——Project Faces——右边java项选择相应的版本就OK了
- PMP - 风险识别之风险登记册
目录 PMP - 风险识别之风险登记册 1. 风险登记册 1.1 已识别风险的清单 1.2 潜在风险责任人 1.3 潜在风险应对措施清单 2. 相关习题 2.1 风险发生的时候,要实施 风险登记册 上 ...
- [转载]Flex的文件规则
原文在:https://blog.csdn.net/hczhiyue/article/details/20483209 文章中给的一个定义很明白,对于初学者来说很有帮助: 什么是 FLEX?它是一个自 ...
- LeetCode:175.组合两个表
题目链接:https://leetcode-cn.com/problems/combine-two-tables/ 题目 表1: Person +-------------+---------+ | ...
- 修改Vue中的 v-html 内的元素无效问题
其原因就是在 style 样式中没有去处scoped 因为 v-html 会把内容当成子组件,而scoped 会在本身的组件中起作用
- mac 下拉取svn代码
svn checkout https://113.108.97.187/svn/zkteco/zks-app --username=lucy --password=lucy66 svn checkou ...
- 03-【request对象获取请求的数据 & request对象存取值】
request概述(封装了客户端所有的请求数据) request是Servlet.service()方法的一个参数,类型为javax.servlet.http.HttpServletRequest.在 ...
- CentOS下安装软件
CentOS下安装软件,要看下载的软件安装包的后缀名是什么,一般为了方便安装,推荐下载以 rpm 结尾的软件包. 比如以下截图,有多种下载方式,推荐下载圈起来的链接. rpm包安装方式步骤: 找到相应 ...
- java线程基础巩固---数据同步引入并结合jconsole,jstack以及汇编指令认识synchronized关键字
对于多线程编程而言其实老生成谈的就是数据同步问题,接下来就会开始接触这块的东东,比较麻烦,但是也是非常重要,所以按部就班的一点点去专研它,下面开始. 数据同步引入: 这里用之前写过的银行叫号的功能做为 ...