准备工作
说明
作者专注分享实用代码,原理性的东西就不分享了,大家自行查找。
spring-cloud-stream 3.1之后,弃用了 @EnableBinding @Input 和@Output等注解,改为采用函数式编程来实现。所以这里的案例是记录如何使用新的模式进行集成rocketMq。
依赖
基于spring-cloud 2020.0.4
<spring-cloud.version>2020.0.4</spring-cloud.version>
<dependencyManagement>
<dependencies>
<!--整合spring cloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--整合spring cloud alibaba-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 集成spring-cloud-starter-stream-rocketmq -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
</dependency>
普通消息发送
配置文件。简单说明一下,bindings的配置是基于spring.cloud.stream的,bindings是由binder来生成的,binder是由对接具体的消息中间件自己来实现的,我们这里集成的是rocketmq,所以需要配置spring.cloud.stream.rocketmq.binder
#使用spring-cloud-stream 来操作rocketmq
spring:
cloud:
stream:
default:
producer:
use-native-encoding: true
consumer:
use-native-encoding: true
bindings:
#channel 名称
sensor-out-0:
#destination = topic
destination: sensor-2
poller.fixed-delay: 10000
rocketmq:
binder:
#rocketMq的ip和端口地址;
name-server: xx.xx.xx.xx:xxx;
具体发送代码。使用StreamBridge 来发送消息
/**
* @author kdb
*/
@RestController
@RequestMapping("/test")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
@Api(value = "测试", tags = "测试")
public class TestController {
private final SysUserService sysUserService;
private final StreamBridge streamBridge;
@GetMapping("sendRocketMqMessage2")
@ApiOperation(value = "使用springcloudstream发送消息", notes = "传入id")
public ResultBean sendRocketMqMessage2(@ApiParam(name = "id",value = "id",required = true) Long id) {
SysUser user = sysUserService.get(id);
//user是测试类,不重要
//* sensor-out-0是通道的名称,跟yml里面配置的通知名称一致的
streamBridge.send("sensor-out-0",
MessageBuilder.withPayload(user)
.build());
return ResultBean.data(user);
}
}
接收消息
接收消息主要是通过function约定的配置,配合函数式编程来实现的
配置文件yml
#使用spring-cloud-stream 来操作rocketmq
spring:
cloud:
stream:
function:
definition: receive;receiveUser
# this default config avoids having to set the property on every binding (see commented section below)
default:
producer:
use-native-encoding: true
consumer:
use-native-encoding: true
bindings:
receive-in-0:
destination: sensor-2
# rocketmq一定要设置group(随便写) 其他的mq可留空
group: wqb2-group
receiveUser-in-0:
destination: send-user
group: user-group
consumer:
use-native-decoding: true
poller.fixed-delay: 10000
rocketmq:
binder:
#rocketMq的ip和端口地址;
name-server: xx.xx.xx.xx:xxx;
消费者代码. 重点说明一下 定义接收者的方法名称很重要,要跟yml里面的function名称一致才行。
import java.util.function.Consumer;
@Configuration
@Slf4j
public class StreamConsumer {
/**
* 方法名称就是通道 channel。
* 跟cloud.stream.function.definition里的值对应
*
* @return
*/
@Bean
Consumer<SysUser> receive() {
System.out.println("接收到信息了");
return s -> log.info("Received Sensor: {}", s);
}
@Bean
Consumer<SysUser> receiveUser() {
System.out.println("接收到信息了");
return s -> log.info("接收到了 send-user: {}", s);
}
}
yml 配置中的receive-in-0 和 receiveUser-in-0 是通道名称,其中receive跟上面的function中的receive是要配置的,至于后面的 ‘in-0’ 是有规则的,in是代表从消息中间消息流入应用程序,应用程序既是消费者。具体规则原理,可以参考下方链接,这里就不再赘述了。
参考: