spring-cloud-stream-binder-rocketmq 不支持延时队列,需要使用原生的mq进行消息发送。
implementation 'com.alibaba.cloud:spring-cloud-stream-binder-rocketmq:2.1.0.RELEASE'
//消费信道
public interface PagePointSink {
String PAGE_POINT_INPUT = "page_point_input";
@Input(PAGE_POINT_INPUT)
SubscribableChannel pagepointInput();
}
//生产信道
public interface PagePointSource {
String PAGE_POINT_OUTPUT = "page_point_output";
@Output(PAGE_POINT_OUTPUT)
MessageChannel pagepointOutput();
}
spring.cloud.stream.bindings.page_point_output.destination=page_point
spring.cloud.stream.bindings.page_point_output.content-type=application/json
spring.cloud.stream.bindings.page_point_input.destination=page_point
spring.cloud.stream.bindings.page_point_input.content-type=application/json
spring.cloud.stream.bindings.page_point_input.group=page_point_input
import java.util.Date;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import cn.hutool.json.JSONUtil;
import cn.medbanks.trading.order.application.command.cmd.PagePointCommand;
import cn.medbanks.trading.order.infrastructure.db.dataobject.PagePointEntity;
import cn.medbanks.trading.order.infrastructure.db.repo.PagePointRepository;
import cn.medbanks.trading.order.infrastructure.event.PagePointEvent;
import cn.medbanks.trading.order.infrastructure.mq.channel.PagePointSource;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class PagePointCommandService {
@Autowired
private PagePointSource pagePointSource;
@Autowired
DefaultMQProducer defaultMQProducer;
@Override
public void send(PagePointCommand command) {
//延时发送
Message message = new Message("page_point", JSONUtil.toJsonStr(command).getBytes());
//messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
//4 指的是30s
message.setDelayTimeLevel(4);
message.setTags("test");
try {
defaultMQProducer.send(message);
} catch (MQClientException | RemotingException | MQBrokerException | InterruptedException ignored) {
}
}
}
package cn.medbanks.trading.order.infrastructure.mq.comsumer;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.support.ErrorMessage;
import org.springframework.stereotype.Component;
import cn.medbanks.trading.order.application.command.cmd.PagePointCommand;
import cn.medbanks.trading.order.infrastructure.mq.channel.PagePointSink;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
public class PagePointConsumer {
//condition = "headers['rocketmq_TAGS']=='test'" 表示只处理headers包含rocketmq_TAGS为test的消息
@StreamListener(value = PagePointSink.PAGE_POINT_INPUT, condition = "headers['rocketmq_TAGS']=='test'")
public void dealInput(@Payload PagePointCommand command, @Headers Map headers) {
// dosomething
}
}
#重试的初始时间间隔是1000豪秒,每次翻3倍,最大的间隔时间是15秒,进行5次重试
spring.cloud.stream.bindings.page_point_input.consumer.maxAttempts=5
spring.cloud.stream.bindings.page_point_input.consumer.backOffInitialInterval=1000
spring.cloud.stream.bindings.page_point_input.consumer.backOffMultiplier=3
spring.cloud.stream.bindings.page_point_input.consumer.backOffMaxInterval=15000
import java.util.Date;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import cn.hutool.json.JSONUtil;
import cn.medbanks.trading.order.application.command.cmd.PagePointCommand;
import cn.medbanks.trading.order.infrastructure.db.dataobject.PagePointEntity;
import cn.medbanks.trading.order.infrastructure.db.repo.PagePointRepository;
import cn.medbanks.trading.order.infrastructure.event.PagePointEvent;
import cn.medbanks.trading.order.infrastructure.mq.channel.PagePointSource;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class PagePointCommandService {
@Autowired
private PagePointSource pagePointSource;
@Autowired
DefaultMQProducer defaultMQProducer;
@Override
public void send(PagePointCommand command) {
//异常重试
Message message = new Message("page_point", JSONUtil.toJsonStr(command).getBytes());
message.setTags("test");
try {
defaultMQProducer.send(message);
} catch (MQClientException | RemotingException | MQBrokerException | InterruptedException ignored) {
}
}
}
package cn.medbanks.trading.order.infrastructure.mq.comsumer;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.support.ErrorMessage;
import org.springframework.stereotype.Component;
import cn.medbanks.trading.order.application.command.cmd.PagePointCommand;
import cn.medbanks.trading.order.infrastructure.mq.channel.PagePointSink;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
public class PagePointConsumer {
@StreamListener(value = PagePointSink.PAGE_POINT_INPUT, condition = "headers['rocketmq_TAGS']=='test'")
public void dealInput(@Payload PagePointCommand command, @Headers Map headers) {
throw new RuntimeException();
}
//在接收消息时,如果消息处理失败,Spring Cloud会把失败的消息转到名为..errors的Channel,
//并可通过@ServiceActivator方法进行接收。
@ServiceActivator(inputChannel = "page_point.page_point_input.errors")
public void handleConsumeUserError(ErrorMessage message) {
log.info("收到处理失败的消息{}", message.getPayload());
}
}