零、前言
这又是学习尚硅谷 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/reference/html/spring-cloud-stream.html#spring_cloud_function],和一些网站 摸索了一会发现了这个新的写法,使用java.util.function.[Supplier/Function/Consumer]
的方式
下面通过代码来细说:有些需要注意的地方在代码下方单独提出来了
这里的前提需要大家先把rabbitMQ安装好 这里就不赘述怎么安装的了
2.1、首先是消息提供者8801
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>com.sxt.sc2021</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-stram-rabbitmq-consumer8802</artifactId>
<dependencies>
<!-- 整合了rabbitMQ和stream-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
<!-- web的starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 想要使用图形化监控 那么这个依赖一定要有-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 服务注册中心eureka-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 开发热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 这个是自己的api 可以不引入没啥问题-->
<dependency>
<groupId>org.example</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
yaml
server:
port: 8801
spring:
application:
name: cloud-stream-privider #端口和微服务名称 老两样
#中间cloud部分和8802一样
cloud:
stream:
binders: #自此处配置要绑定的rabbitmq的服务信息
defaultRabbit: #表示定义的名称,用于binding整合
type: rabbit #消息组件类型
environment: # 设置rabbitmq的相关的环境配置 stream3.1只需要配置这些即可
spring:
rabbitmq:
host: localhost
port: 5672 #mq调用的端口为5672
username: guest
password: guest
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
lease-expiration-duration-in-seconds: 5 #如果现在超过了5秒的间隔
lease-renewal-interval-in-seconds: 2 #设置心跳的时间间隔
instance-id: send-8801.com
prefer-ip-address: true #访问的路径变为IP地址
service
package com.peach.springcloud.service;
import java.util.function.Supplier;
public interface IMessage {
void sendMethod();
}
serviceImpl
package com.peach.springcloud.impl;
import com.peach.springcloud.service.IMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.function.StreamBridge;
import org.springframework.stereotype.Component;
import java.util.UUID;
@Component
public class MessageProviderImpl implements IMessage {
//这里直接装配一个桥 用来连接rabbit或者kafka
@Autowired
StreamBridge streamBridge;
@Override
public void sendMethod() {
String message = UUID.randomUUID().toString();
//这里说明一下这个 streamBridge.send 方法的参数 第一个参数是exchange或者topic 就是主题名称
//默认的主题名称是通过
//输入: <方法名> + -in- + <index>
//输出: <方法名> + -out- + <index>
//这里我们接收的时候就要用send方法 参数是consumer<String>接收 详情看8802的controller
//consumer的参数类型是这里message的类型
streamBridge.send("send-in-0", message);
System.out.println("************发送了message:"+message);
}
}
controller
package com.peach.springcloud.controller;
import com.peach.springcloud.impl.MessageProviderImpl;
import com.peach.springcloud.service.IMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.function.StreamBridge;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class SendMessageController {
@Resource
private MessageProviderImpl messageProvider;
@RequestMapping("/send")
public void send(){
messageProvider.sendMethod();
}
}
2.2 然后是8802 消息消费者
pom 和上面一样
yaml 除了端口和eureka实例其他的和8801一样
server:
port: 8802
spring:
application:
name: cloud-stream-privider
#中间cloud部分和8802一样
cloud:
stream:
binders: #自此处配置要绑定的rabbitmq的服务信息
defaultRabbit: #表示定义的名称,用于binding整合
type: rabbit #消息组件类型
environment: # 设置rabbitmq的相关的环境配置 stream3.1只需要配置这些即可
spring:
rabbitmq:
host: localhost
port: 5672 #mq调用的端口为5672
username: guest
password: guest
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
lease-expiration-duration-in-seconds: 5 #如果现在超过了5秒的间隔
lease-renewal-interval-in-seconds: 2 #设置心跳的时间间隔
instance-id: send-8802.com
prefer-ip-address: true #访问的路径变为IP地址
controller
package com.peach.springcloud.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import java.util.function.Consumer;
@Component
public class ReceiveMessageController {
@Value("${server.port}")
private String serverPort;
@Bean
//这里接收rabbitmq的条件是参数为Consumer 并且 方法名和supplier方法名相同
//这里的返回值是一个匿名函数 返回类型是consumer 类型和提供者的类型一致
//supplier发送的exchange是 send-in-0 这里只需要用send方法名即可
Consumer<String> send() {
return str -> {
System.out.println("我是消费者"+serverPort+",我收到了消息:"+str);
};
}
}
先启动注册中心和8801 8802 之后访问我们的15672 也就是rabbitMQ的管理页面看看有没有这个exchange
展示效果:
看来是没问题的 名字和我们想的一样
绑定信息也有了
然后我们访问supplier的send方法发几个消息先,之后看8801控制台
8802控制台
之后看管理页面
也可以看到峰值的变动
2.3总结一下
1、在stream3.1中 我们不需要像以前一样用@Binding @StreamListener来监听了 这样少写了很多代码和配置 我们可以使用StreamBrige来进行发送
2、StreamBrige.send() 方法的参数拼写规则:
可以直接看官方文档[命名规则][https://docs.spring.io/spring-cloud-stream/docs/3.1.0/reference/html/spring-cloud-stream.html#_binding_and_binding_names]
//输入: <方法名> + -in- + <index>
//输出: <方法名> + -out- + <index>
3、接收的时候直接用前面的方法名即可
4、看官方文档还是有些用的,虽然有时候看不懂但是是成为大佬的必经之路