之前项目中有个需求,在一个服务中,需要连接两个不同的rocketmq实例,查找了好久的资料,终于通过Google找出来了,以后有条件的还是使用Google吧,百度真的百度不出来
maven依赖:
注意: 只对以下依赖版本有效,其他的版本没试过,不同的版本可能不一样
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.boot.version>2.3.7.RELEASE</spring.boot.version>
<spring.cloud.version>Hoxton.SR9</spring.cloud.version>
<spring.cloud.alibaba.version>2.2.6.RELEASE</spring.cloud.alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
<version>2.2.9.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
server:
port: 10086
spring:
cloud:
stream:
binders:
binder1:
type: rocketmq
environment:
spring.cloud.stream.rocketmq:
binder:
name-server: localhost:9876
# accessKey: skXXXX
# secretKey: skXXXX
enable-msg-trace: false
group: demo-group-1
bindings:
topic-demo-out-0:
producer:
group: delayed-group-1
sync: true
handleDemoMsg-in-0:
consumer:
enable: true
broadcasting: false
orderly: false
handleCompletedMsg-in-0:
consumer:
enable: true
broadcasting: false
orderly: false
binder2:
type: rocketmq
environment:
spring.cloud.stream.rocketmq:
binder:
name-server: localhost:9876
# accessKey: akxxxxxxx
# secretKey: skxxxxxxx
enable-msg-trace: false
group: demo-group-2
bindings:
topic-demo2-out-0:
producer:
group: delayed-group-2
sync: true
default-binder: binder1
bindings:
topic-demo-out-0:
destination: topic-demo
topic-demo2-out-0:
destination: topic-demo2
binder: binder2 # 如果指定了binder,就走指定的,不指定就走默认的binder1,上边设置的: default-binder: binder1
handleDemoMsg-in-0:
content-type: application/json
destination: topic-demo
group: demo-group-1
function:
definition: handleDemoMsg,handleCompletedMsg
发送消息
package com.learning.config;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageConst;
import org.springframework.cloud.stream.function.StreamBridge;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.stereotype.Component;
import org.springframework.util.MimeTypeUtils;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
@Component
@Slf4j
public class MsgSender {
@Resource
private StreamBridge streamBridge;
//通用的消息发送,由调用方指定msg key
public void sendMsg(String bindingName, String msgKey, String tag, Integer delayTimeLevel, String msg) {
Map<String, Object> headers = new HashMap<>();
headers.put(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON);
headers.put(MessageConst.PROPERTY_TAGS, tag);
headers.put(MessageConst.PROPERTY_KEYS, msgKey);
if(null != delayTimeLevel) {
headers.put(MessageConst.PROPERTY_DELAY_TIME_LEVEL, delayTimeLevel);
}
final Message message = new GenericMessage(JSONObject.parseObject(msg), new MessageHeaders(headers));
streamBridge.send(bindingName, message);
log.info("消息发送成功,消息Key:{}", msgKey);
}
/**
* 发送普通消息,自动生成msg key
* @param bindingName
* @param msgObject
*/
public boolean sendMsg(String bindingName, Object msgObject) {
Map<String, Object> headers = new HashMap<>();
headers.put(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON);
headers.put(IDUtils.TraceId, IDUtils.getId());
headers.put(MessageConst.PROPERTY_KEYS, IDUtils.generateDatetimeUuidId());
final Message message = new GenericMessage(JSONObject.toJSON(msgObject), new MessageHeaders(headers));
boolean send = streamBridge.send(bindingName, message);
log.info("消息发送成功,消息Key:{}", IDUtils.getId());
return send;
}
//发送延时消息,自动生成msg key
public void sendDelayMsg(String bindingName, Integer delayTimeLevel, Object msgObject) {
Map<String, Object> headers = new HashMap<>();
headers.put(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON);
headers.put(IDUtils.TraceId, IDUtils.getId());
headers.put(MessageConst.PROPERTY_KEYS, IDUtils.generateDatetimeUuidId());
headers.put(MessageConst.PROPERTY_DELAY_TIME_LEVEL, delayTimeLevel);
final Message message = new GenericMessage(JSONObject.toJSON(msgObject), new MessageHeaders(headers));
streamBridge.send(bindingName, message);
log.info("消息发送成功,消息Key:{}", IDUtils.getId());
}
}
测试:
@RestController
public class RocletMqController {
@Resource
private MsgSender msgSender;
@GetMapping("/sendMsg")
public boolean sendMsgByStream() {
//sendMsg方法的第一个参数是配置文件中自定义的binder名称,
//第二个参数是object类型的消息体
return msgSender.sendMsg("topic-demo-out-0", "test1");
}
}
我也是根据kafka配置,照搬到rocketmq中,spring cloud stream的好处就是可以很方便的切换不同类型的消息队列,kafka,rabbit,rocketmq配置都差不多,不同的队列类型,引入不同的starter,即:spring-cloud-starter-stream-rocketmq依赖,很方便
参考:
1, https://cloud.spring.io/spring-cloud-stream/spring-cloud-stream.html#multiple-systems
2, https://solace.community/discussion/1398/multiple-binder-configuration
3, https://github.com/spring-cloud/spring-cloud-stream-samples/blob/main/multi-binder-samples/multi-binder-two-kafka-clusters/src/main/resources/application.yml