1、配置文件

1、yml配置文件

rocketmq: #mq配置
producer:
iseffect: true
type: default # (transaction,default) transaction:TransactionMQProducer; default:DefaultMQProducer
groupName: testzjlGroup
topicName: test_topic
namesrvAddr: 192.168.244.128:9876
consumer:
iseffect: true
type: default # (transaction,default) transaction:TransactionMQProducer; default:DefaultMQProducer
groupName: testzjlGroup
topicName: test_topic
namesrvAddr: 192.168.244.128:9876

2、对应的java类

package com.gofun.customer.mq;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "rocketmq.producer")
public class RocketMqProducerProperties { private Boolean iseffect;
private String type;
private String groupName;
private String topicName;
private String namesrvAddr; public Boolean getIseffect() {
return iseffect;
} public void setIseffect(Boolean iseffect) {
this.iseffect = iseffect;
} public String getType() {
return type;
} public void setType(String type) {
this.type = type;
} public String getGroupName() {
return groupName;
} public void setGroupName(String groupName) {
this.groupName = groupName;
} public String getTopicName() {
return topicName;
} public void setTopicName(String topicName) {
this.topicName = topicName;
} public String getNamesrvAddr() {
return namesrvAddr;
} public void setNamesrvAddr(String namesrvAddr) {
this.namesrvAddr = namesrvAddr;
}
}

2、DefaultMQProducer生产者

1、生产者配置

package com.gofun.customer.mq;

import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; @Configuration
@EnableConfigurationProperties(RocketMqProducerProperties.class)
@ConditionalOnProperty(prefix = "rocketmq.producer", name = "iseffect", havingValue = "true")
public class RocketMqConfig {
@Autowired
private RocketMqProducerProperties rocketMqProperties; @Bean
@ConditionalOnProperty(prefix = "rocketmq.producer", name = "type", havingValue = "default")
public DefaultMQProducer defaultMQProducer() throws MQClientException {
DefaultMQProducer defaultMQProducer = new DefaultMQProducer(rocketMqProperties.getGroupName());
defaultMQProducer.setNamesrvAddr(rocketMqProperties.getNamesrvAddr());
defaultMQProducer.setVipChannelEnabled(false);
defaultMQProducer.setRetryTimesWhenSendAsyncFailed(10);
defaultMQProducer.start();
return defaultMQProducer;
} }
  1. 启动应用创建生产者
  2. 使用配置文件为RocketMqProducerProperties类
  3. 配置文件iseffect = true时生效该配置
  4. 配置文件 type=default 时生效 DefaultMQProducer 生产者

2、生产者工具类

package com.gofun.customer.mq;

import com.alibaba.fastjson.JSON;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; @Component
public class RocketMqProducer {
@Autowired
private DefaultMQProducer defaultMQProducer;
@Autowired
private RocketMqProducerProperties rocketMqProperties; public SendResult send(String topic, String tag, Object obj) {
String body = null;
if(obj == null){
return null;
}
if(obj instanceof String){
body = (String) obj;
}else{
body = JSON.toJSONString(obj);
}
Message msg = new Message(topic, tag, body.getBytes());
SendResult sendResult = null;
try {
sendResult = defaultMQProducer.send(msg);
} catch (Exception e) {
}
return sendResult;
} /**
* 延时消息
* @param topic
* @param tag
* @param obj
* @param delayTimeLevel 1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
* @return
*/
public SendResult send(String topic, String tag, Object obj,int delayTimeLevel) {
String body = null;
if(obj == null){
return null;
}
if(obj instanceof String){
body = (String) obj;
}else{
body = JSON.toJSONString(obj);
}
Message msg = new Message(topic, tag, body.getBytes());
msg.setDelayTimeLevel(delayTimeLevel);
SendResult sendResult = null;
try {
sendResult = defaultMQProducer.send(msg);
} catch (Exception e) {
}
return sendResult;
} public SendResult send(String tag, Object obj) {
return send(rocketMqProperties.getTopicName(), tag, obj);
} }

3、生产者发送消息

1、引入工具类调用 发送方法

@Autowired
private RocketMqProducer rocketMqProducer;
rocketMqProducer.send("testTag","测试mq发送消息。。。。");

4、问题

注意:
  1. mq设置autoCreateTopicEnable=false时需要手动创建topic
  2. 启动后后台一直报打印日志如:closeChannel: close the connection to remote address[] result: true  说明namesrvAddr 的ip 或 端口号配置错误
  3. 启动后后台一直报打印日志如:closeChannel: close the connection to remote address[192.168.244.128:9876] result: true  可能是jar包错误
  4. 要引入fastjson的jar包

3、消费者

1、DefaultMQPullConsumer 消费者

private static final Map<MessageQueue,Long> OFFSE_TABLE = new HashMap<MessageQueue,Long>();

    public void testDefaultMQPullConsumer() throws MQClientException {
DefaultMQPullConsumer consumer = new DefaultMQPullConsumer(rocketMqConsumerProperties.getGroupName());
consumer.setNamesrvAddr("192.168.244.128:9876;192.168.244.130:9876");
consumer.start();
// 从指定topic中拉取所有消息队列
Set<MessageQueue> mqs = consumer.fetchSubscribeMessageQueues("order-topic");
for(MessageQueue mq:mqs){
try {
// 获取消息的offset,指定从store中获取
long offset = consumer.fetchConsumeOffset(mq,true);
System.out.println("consumer from the queue:"+mq+":"+offset);
while(true){
PullResult pullResult = consumer.pullBlockIfNotFound(mq, null, getMessageQueueOffset(mq), 32);
putMessageQueueOffset(mq,pullResult.getNextBeginOffset());
switch(pullResult.getPullStatus()){
case FOUND:
List<MessageExt> messageExtList = pullResult.getMsgFoundList();
for (MessageExt m : messageExtList) {
System.out.println(new String(m.getBody()));
}
break;
case NO_MATCHED_MSG:
break;
case NO_NEW_MSG:
break;
case OFFSET_ILLEGAL:
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
consumer.shutdown();
} // 保存上次消费的消息下标
private static void putMessageQueueOffset(MessageQueue mq, long nextBeginOffset) {
OFFSE_TABLE.put(mq, nextBeginOffset);
} // 获取上次消费的消息的下标
private static Long getMessageQueueOffset(MessageQueue mq) {
Long offset = OFFSE_TABLE.get(mq);
if(offset != null){
return offset;
}
return 0l;
}

2、DefaultMQPushConsumer 消费者模板方法

RocketMqConsumerProperties 配置类 参见 消费者配置类。

package com.gofun.customer.mq;

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.beans.factory.annotation.Autowired; import java.util.List; public abstract class RocketMqDefaultConsumer {
@Autowired
private RocketMqConsumerProperties rocketMqConsumerProperties; public void listener(String topic, String tag) throws MQClientException {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(rocketMqConsumerProperties.getGroupName());
consumer.setNamesrvAddr(rocketMqConsumerProperties.getNamesrvAddr());
consumer.subscribe(topic, tag);
// 开启内部类实现监听
// consumer.registerMessageListener((MessageListenerConcurrently) (list, consumeConcurrentlyContext) -> RocketMqDefaultConsumer.this.dealBody(list));
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
return RocketMqDefaultConsumer.this.dealBody(list);
}
});
consumer.start();
} // 处理body的业务
public abstract ConsumeConcurrentlyStatus dealBody(List<MessageExt> msgs);
}
  1. 消费者需要继承此抽象类
  2. 传入topic 和 tag,添加监听, 开启消费者
  3. 定义抽象函数处理消息,实现类需要自已实现处理函数内容

3、DefaultMQPushConsumer 消费者实现

package com.gofun.customer.controller.test;

import com.gofun.customer.mq.RocketMqDefaultConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; import java.util.List; @Component
public class TestConsumer extends RocketMqDefaultConsumer implements InitializingBean {
private final String testtopic = "test_topic";
private final String testflag = "testTag"; @Override
public void afterPropertiesSet() throws Exception {
super.listener(testtopic, testflag);
} @Override
public ConsumeConcurrentlyStatus dealBody(List<MessageExt> msgs) {
if (!CollectionUtils.isEmpty(msgs)) {
for (MessageExt msg : msgs) {
byte[] body = msg.getBody();
String s = new String(body);
System.out.println("这是rocketmq消费者消费的消息:"+s);
}
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
} }
  1. 继承模板类定义自己的topic和tag
  2. 实现处理消息的方法
  3. 实现接口InitializingBean ,加载完成自动调用 afterPropertiesSet方法,父类模板添加监听

3、消费模式

在RocketMQ中,可以理解为没有ActiveMQ的createQueue()和createTopic()的用法,也就是并没有P2P和Pub/Sub类似的概念。RocketMQ不遵循JMS规范,而是使用了一套自定义的机制。可以理解为RocketMQ都是基于Pub/Sub发布订阅模式的,

在此基础上提供了集群消息和广播消息两种消息模式,可通过消费端方法consumer.setMessageModel()进行设置。

集群消息——MessageModel.CLUSTERING

这方方式可以实现类似ActiveMQ负载均衡客户端的功能,同一个ConsumerGroup下的所有Consumer已负载均衡的方式消费消息。比较特殊的是,这种方式可以支持生产端先发送消息到Broker,消费端再订阅主题进行消费,比较灵活。RocketMQ默认为该模式。

广播消息——MessageModel.BROADCASTING

在这种模式下,生产端发送到Topic下的消息,会被订阅了该Topic的所有Consumer消费,即使它们处于同一个ConsumerGroup。

原文链接:https://blog.csdn.net/weixin_34452850/article/details/82754419

3、顺序消息

SendResult sendResult = producer.send(msg, new MessageQueueSelector() {
@Override
public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
Integer id = (Integer) arg;
int index = id % mqs.size();
return mqs.get(index);
}
}, orderId);

参考https://www.jianshu.com/p/5260a2739d80

springboot整合RocketMq(非事务)的更多相关文章

  1. SpringBoot(17)---SpringBoot整合RocketMQ

    SpringBoot整合RocketMQ 上篇博客讲解了服务器集群部署RocketMQ 博客地址:RocketMQ(2)---Docker部署RocketMQ集群 这篇在上篇搭建好的基础上,将Spri ...

  2. Springboot整合RocketMQ解决分布式事务

    直接上代码: 代码结构如下: 依次贴出相关类: DataSource1Config: package com.example.demo.config;import org.apache.ibatis. ...

  3. MongoDB与SpringBoot整合(支持事务)

    1.创建SpringBoot工程,选择 Web.MonogDB 依赖,pom如下: <parent> <groupId>org.springframework.boot< ...

  4. SpringBoot整合RocketMQ

    1.RocketMQ的下载与配置 到官网选择想要的版本下载即可,https://rocketmq.apache.org/release_notes/ 下载速度会比较慢,这里提供目前最新版本4.9.3的 ...

  5. SpringBoot - 集成RocketMQ实现延迟消息队列

    目录 前言 环境 具体实现 前言 RocketMQ是阿里巴巴在2012年开源的分布式消息中间件,记录下SpringBoot整合RocketMQ的方式,RocketMQ的安装可以查看:Windows下安 ...

  6. 【SpringBoot】数据库操作之整合Mybaties和事务讲解

    ========================8.数据库操作之整合Mybaties和事务讲解 ================================ 1.SpringBoot2.x持久化数 ...

  7. SpringBoot整合Mybatis【非注解版】

    接上文:SpringBoot整合Mybatis[注解版] 一.项目创建 新建一个工程 ​ 选择Spring Initializr,配置JDK版本 ​ 输入项目名 ​ 选择构建web项目所需的state ...

  8. SpringBoot系列七:SpringBoot 整合 MyBatis(配置 druid 数据源、配置 MyBatis、事务控制、druid 监控)

    1.概念:SpringBoot 整合 MyBatis 2.背景 SpringBoot 得到最终效果是一个简化到极致的 WEB 开发,但是只要牵扯到 WEB 开发,就绝对不可能缺少数据层操作,所有的开发 ...

  9. @Transactional(事务讲解)和springboot 整合事务

    概述 事务在编程中分为两种:声明式事务处理和编程式事务处理 编程式事务处理:编码方式实现事务管理,常与模版类TransactionTemplate(推荐使用) 在业务代码中实现事务. 可知编程式事务每 ...

随机推荐

  1. 三、python之文件的处理

    1.文件的读取 1.1 读取整个文件 假设我们有一个叫做“hello.txt”的文件,文件内容如下: helloWorld helloPython helloJava 在该文件中,有三行字符串,接下来 ...

  2. unique(去重函数)

    去重排序(unique函数的使用) 2013年05月30日 11:05:45 阅读数:9689更多 个人分类: 字符串处理  出处:http://www.cnblogs.com/QQbai/archi ...

  3. MariaDB学习笔记(二)

    七 索引索引:索引是创建在表上的,是对数据库表中的一列或多列的值进行排序的一种结构.索引可以提高查询的速度.索引有两种存储类型: B型树索引 哈希索引I nnoDB和MyISAM支持B型树索引,MEM ...

  4. 发送xml数据

  5. JS异步事件顺序:setTimeout,async,promise

    为什么最近更新那么频繁,还不是因为笔试的时候瞎了? 先说异步事件执行顺序的规则: 1. 定时器异步队列和promise队列不是同一队列,promise优先级高于setTimeout; 2. 创建pro ...

  6. java当中的Timer定时器的4种使用方式

    import java.util.Calendar; import java.util.Date; import java.util.Timer; import java.util.TimerTask ...

  7. JavaSE---多线程---集合类

    1.概述 1.1 Java提供的ArrayList.LinkedList.HashMap等都是线程不安全的类,如何解决: 1.1 使用Collections类提供的方法将  其  包装成线程安全类: ...

  8. range类型(Python)

    range 不是 iterator >>> R = range(3) >>> next(R) Traceback (most recent call last): ...

  9. CodeForces 731D (差分+线段扫描)

    Description Archeologists have found a secret pass in the dungeon of one of the pyramids of Cyclelan ...

  10. Ruby 技能图谱

    # Ruby 技能图谱 说明: 本图谱只捡重点的列举,并非包含全部.文中所列举或没有列举的资源信息都可以在[awesome-ruby](https://github.com/markets/aweso ...