rocketmq(三 java操作rocket API, rocketmq 幂等性)
- JAVA操作rocketmq:
1.导入rocketmq所需要的依赖:
- <dependency>
- <groupId>com.alibaba.rocketmq</groupId>
- <artifactId>rocketmq-client</artifactId>
- <version>3.0.10</version>
- </dependency>
- <dependency>
- <groupId>com.alibaba.rocketmq</groupId>
- <artifactId>rocketmq-all</artifactId>
- <version>3.0.10</version>
- <type>pom</type>
- </dependency>
2.创建生产者
- package com.example.producer;
- import com.alibaba.rocketmq.client.exception.MQClientException;
- import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
- import com.alibaba.rocketmq.client.producer.SendResult;
- import com.alibaba.rocketmq.common.message.Message;
- public class Producer {
- public static void main(String[] args) throws MQClientException {
- DefaultMQProducer producer = new DefaultMQProducer("producer-group");
- producer.setNamesrvAddr("192.168.31.165:9876;192.168.31.144:9876");
- producer.setInstanceName("producer");
- producer.start();
- try {
- for (int i = 0; i < 10; i++) {
- // Thread.sleep(1000); // 每秒发送一次MQ
- Message msg = new Message("producer-topic", // topic 主题名称
- "msg", // pull 临时值 在消费者消费的时候 可以根据msg类型进行消费
- ("pushmsg-" + i).getBytes()// body 内容
- );
- SendResult sendResult = producer.send(msg);
- System.out.println(sendResult.toString());
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- producer.shutdown();
- }
- }
3.创建消费者
- package com.example.consumer;
- import java.util.List;
- import com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer;
- import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
- import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
- import com.alibaba.rocketmq.client.consumer.listener.MessageListenerConcurrently;
- import com.alibaba.rocketmq.client.exception.MQClientException;
- import com.alibaba.rocketmq.common.message.MessageExt;
- public class Consumer {
- public static void main(String[] args) throws MQClientException {
- DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumer-group");
- consumer.setNamesrvAddr("192.168.31.165:9876;192.168.31.144:9876");
- consumer.setInstanceName("consumer");
- consumer.subscribe("producer-topic", "msg");//此处是根据Message对象的参数来获取
- consumer.registerMessageListener(new MessageListenerConcurrently() {
- @Override
- public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
- for (MessageExt msg : msgs) {
- System.out.println("消息id:"+msg.getMsgId() + "---" + new String(msg.getBody()));
- }
- return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
- }
- });
- consumer.start();
- }
- }
4.运行结果:
生产者运行结果:
消费者运行结果:
- rocetmq幂等性问题:
在Activemq中 jms规范支持两种消息模型:点对点和发布订阅,在rocketmq中 有两种消费模式:广播消费,和集群消费。
在消费的过程中,如果消费者出现异常或者超时,导致mq没有及时的相应消费的状态,则可能让mq重试,重试机制就有可能导致出现幂等性,而rocketmq的幂等性 只会出现在集群消费(类似activemq中的点对点消息模型)
生产者:
- package com.example.producer;
- import com.alibaba.rocketmq.client.exception.MQClientException;
- import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
- import com.alibaba.rocketmq.client.producer.SendResult;
- import com.alibaba.rocketmq.common.message.Message;
- public class Producer {
- public static void main(String[] args) throws MQClientException {
- DefaultMQProducer producer = new DefaultMQProducer("producer-group");
- producer.setNamesrvAddr("192.168.31.169:9876;192.168.31.177:9876");
- producer.setInstanceName("producer");
- producer.start();
- try {
- for (int i = 0; i < 10; i++) {
- Message msg = new Message("topic", // topic 主题名称
- "msg", // pull 临时值 在消费者消费的时候 可以根据msg类型进行消费
- (i + "条消息").getBytes()// body 内容
- );
- SendResult sendResult = producer.send(msg);
- System.out.println(sendResult.toString());
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- producer.shutdown();
- }
- }
消费者:
- package com.example.consumer;
- import java.util.List;
- import com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer;
- import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
- import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
- import com.alibaba.rocketmq.client.consumer.listener.MessageListenerConcurrently;
- import com.alibaba.rocketmq.client.exception.MQClientException;
- import com.alibaba.rocketmq.common.message.MessageExt;
- public class Consumer {
- public static void main(String[] args) throws MQClientException {
- DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumer-group");
- consumer.setNamesrvAddr("192.168.31.169:9876;192.168.31.177:9876");
- consumer.setInstanceName("consumer");
- consumer.subscribe("topic1", "msg");
- consumer.registerMessageListener(new MessageListenerConcurrently() {
- @Override
- public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
- for (MessageExt msg : msgs) {
- System.out.println("消息id:" + msg.getMsgId() + "---" + new String(msg.getBody()));
- }
- // 超时的情况 或者程序异常
- int i = 2 / 0;
- return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
- }
- });
- consumer.start();
- }
- }
消费结果:
- 消息id:C0A81FB100002A9F00000000000268EC---5条消息
- 消息id:C0A81FB100002A9F000000000002686E---4条消息
- 消息id:C0A81FA900002A9F0000000000037E6A---1条消息
- 消息id:C0A81FB100002A9F000000000002696A---6条消息
- 消息id:C0A81FB100002A9F00000000000269E8---7条消息
- 消息id:C0A81FA900002A9F0000000000038062---9条消息
- 消息id:C0A81FA900002A9F0000000000037EE8---2条消息
- 消息id:C0A81FA900002A9F0000000000037FE4---8条消息
- 消息id:C0A81FA900002A9F0000000000037F66---3条消息
- 消息id:C0A81FA900002A9F0000000000037DEC---0条消息
- 消息id:C0A81FA900002A9F0000000000038704---1条消息
- 消息id:C0A81FA900002A9F000000000003880C---9条消息
- 消息id:C0A81FA900002A9F0000000000038914---2条消息
- 消息id:C0A81FA900002A9F0000000000038A1C---0条消息
- 消息id:C0A81FA900002A9F0000000000038B24---3条消息
- 消息id:C0A81FA900002A9F0000000000038C2C---8条消息
- 消息id:C0A81FB100002A9F0000000000026E7E---4条消息
- 消息id:C0A81FB100002A9F0000000000026F86---7条消息
- 消息id:C0A81FB100002A9F0000000000027196---5条消息
- 消息id:C0A81FB100002A9F000000000002708E---6条消息
在Activimq中,可以通过消息id 来作为全局变量,检测是不是重复消费。但是在rocketmq中消费重试的结果中,任意选出两条相同的消息,可以看出 重试的时候消息id是不同的,此时在用消息id作为全局变量判断是否重复消费显然是不可能的。rocketmq中提供了一个消息的key,可以将业务id作为该key。例如:订单号什么的。可以将消息设置的key 在第一次消费的时候存放到数据库之中
幂等性消费者:
- package com.example.consumer;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer;
- import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
- import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
- import com.alibaba.rocketmq.client.consumer.listener.MessageListenerConcurrently;
- import com.alibaba.rocketmq.client.exception.MQClientException;
- import com.alibaba.rocketmq.common.message.MessageExt;
- public class Consumer {
- public static Map<String, String> map = new HashMap<String, String>();// 模拟内存,实际情况可以将key放在redis之中
- public static void main(String[] args) throws MQClientException {
- DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumer-group");
- consumer.setNamesrvAddr("192.168.31.169:9876;192.168.31.177:9876");
- consumer.setInstanceName("consumer");
- consumer.subscribe("topic1", "msg");
- consumer.registerMessageListener(new MessageListenerConcurrently() {
- @Override
- public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
- for (MessageExt msg : msgs) {
- if (!map.containsKey(msg.getKeys())) {
- // 如果此时的业务逻辑是将收到的消息存放到数据库
- System.out.println("消息id:" + msg.getMsgId() + "---" + new String(msg.getBody()));
- map.put(msg.getKeys(), new String(msg.getBody()));
- } else {
- System.out.println("重复消费");
- return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
- }
- }
- // 超时的情况 或者程序异常
- int i = 2 / 0;
- return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
- }
- });
- consumer.start();
- }
- }
rocketmq(三 java操作rocket API, rocketmq 幂等性)的更多相关文章
- 利用 Java 操作 Jenkins API 实现对 Jenkins 的控制详解
本文转载自利用 Java 操作 Jenkins API 实现对 Jenkins 的控制详解 导语 由于最近工作需要利用 Jenkins 远程 API 操作 Jenkins 来完成一些列操作,就抽空研究 ...
- Elasticsearch Java Rest Client API 整理总结 (三)——Building Queries
目录 上篇回顾 Building Queries 匹配所有的查询 全文查询 Full Text Queries 什么是全文查询? Match 全文查询 API 列表 基于词项的查询 Term Term ...
- Java操作mongoDB2.6的常见API使用方法
对于mongoDB而言,学习方式和学习关系型数据库差不太多 開始都是学习怎样insert.find.update.remove,然后就是分页.排序.索引,再接着就是主从复制.副本集.分片等等 最后就是 ...
- zookeeper(三):java操作zookeeper
引入jar包 首先要使用java操作zookeeper,zookeeper的javaclient 使我们更轻松的去对zookeeper进行各种操作,我们引入zookeeper-3.4.5.jar 和 ...
- Java 8 集合之流式(Streams)操作, Streams API 详解
因为当时公司的业务需要对集合进行各种各样的业务逻辑操作,为了提高性能,就用到了这个东西,因为以往我们以前用集合都是需要去遍历(串行),所以效率和性能都不是特别的好,而Streams就可以使用并行的方式 ...
- Java 8 Stream Api 中的 peek 操作
1. 前言 我在Java8 Stream API 详细使用指南[1] 中讲述了 [Java 8 Stream API]( "Java 8 Stream API") 中 map 操作 ...
- HBase的java操作,最新API。(查询指定行、列、插入数据等)
关于HBase环境搭建和HBase的原理架构,请见笔者相关博客. 1.HBase对java有着较优秀的支持,本文将介绍如何使用java操作Hbase. 首先是pom依赖: <dependency ...
- Java操作Jxl实现数据交互。三部曲——《第三篇》
Java操作Jxl实现上传文本文件实现转PDF格式在线预览. 本文实现背景Web项目:前台用的框架是Easyui+Bootstrap结合使用,需要引入相应的Js.Css文件.页面:Jsp.拦截请求:S ...
- hadoop学习(三)HDFS常用命令以及java操作HDFS
一.HDFS的常用命令 1.查看根目录下的信息:./hadoop dfs -ls 2.查看根目录下的in目录中的内容:./hadoop dfs -ls in或者./hadoop dfs -ls ./i ...
随机推荐
- Linux~Archer 进化之路
使用过的linux系统有:Redhat.红旗Linux.Deepin.Ubuntu.Debian.Fedora.Kali.Parrot.manjaro.Mint.Arch,最早接触linux是从200 ...
- 3--TestNG多线程
第一: 注解方式 public class MultiThreadOnAnnotation{ @test(invocationCount=10,threadPoolSize=10) public vo ...
- iOS原生自动布局NSLayoutConstraint
AutoLayout概念是苹果自iOS6开始引入的概念. 目前为止,实现自动布局技术选型方面也可以使用xib和storyboard.在开发过程中通常登录.注册等变动可能性较小的视图,我会采用xib开发 ...
- Linux 环境下安装Mysql的步骤
一,以linux cent 6.9 安装mysql 5.6.39为例#下载安装包wget --no-check-certificate https://dev.mysql.com/get/Downlo ...
- ELK简单安装测试
1 介绍组件 Filebeat是一个日志文件托运工具,在你的服务器上安装客户端后,filebeat会监控日志目录或者指定的日志文件,追踪读取这些文件(追踪文件的变化,不停的读). Kafka是一种高吞 ...
- python-django-01
1.Python工具 - pip 1.作用 Python的软件包管理器,有一些python包被集成到了pip中.只要被集成到pip中的包,都允许通过pip直接安装 2.安装 pip sudo apt ...
- Hailstone冰雹序列问题
在复习数据结构,课程中提到Hailstone冰雹序列问题,问题如下 代码如下: public List<int> Hailstone(int n) { List<int> li ...
- sping配置头文件
spring配置文件头部xmlns配置精髓 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <beans xmlns="http://www.s ...
- 判断某个元素是否存在于某个 js 数组中
1.正则表达式 Array.prototype.in_array=function(e){ var r=new RegExp(','+e+','); return (r.test(','+this.j ...
- JPA、Hibernate框架、通用mapper之间的关系及通用mapper的具体实现
JPA是描述对象-关系表的映射关系,将运行期实体对象持久化到数据库中,提出以面向对象方式操作数据库的思想. Hibernate框架核心思想是ORM-实现自动的关系映射.缺点:由于关联操作提出Hql语法 ...