package com.study.rabbitmq.a132.confirm;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.TimeoutException; // 可靠生产
// https://www.rabbitmq.com/confirms.html
public class Producer { public static void main(String[] args) {
// 1、创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 2、设置连接属性
factory.setHost("192.168.100.242");
factory.setUsername("admin");
factory.setPassword("admin"); Connection connection = null;
Channel channel = null; try {
// 3、从连接工厂获取连接
connection = factory.newConnection("生产者");
// 4、从链接中创建通道
channel = connection.createChannel(); // 进入confirm模式, 每次发送消息,rabbtiqm处理之后会返回一个对应的回执消息
AMQP.Confirm.SelectOk selectOk = channel.confirmSelect();
// 增加监听器
ArrayList<String> queues = new ArrayList<>();
channel.addConfirmListener(new ConfirmListener() {
@Override
public void handleAck(long deliveryTag, boolean multiple) throws IOException {
// deliveryTag 同一个channel中此条消息的编号 。
// 业务..
System.out.println("受理成功 " + queues.get((int) deliveryTag) + " " + multiple);
} @Override
public void handleNack(long deliveryTag, boolean multiple) throws IOException {
// 失败重发
// queues.get((int) deliveryTag)
System.out.println("受理失败 " + deliveryTag);
}
});
// 定义fanout类型的交换器
channel.exchangeDeclare("ps_test", "fanout"); for (int i = 0; i < 10; i++) {
// 消息内容
String message = "Hello Confirm " + i;
queues.add(message);
// 发送消息到ps_test交换器上
AMQP.BasicProperties basicProperties = new AMQP.BasicProperties();
channel.basicPublish("ps_test", "", basicProperties, message.getBytes());
System.out.println("消息 " + message + " 已发送!");
} // 等待20秒
Thread.sleep(20 * 1000L);
} catch (Exception e) {
e.printStackTrace();
} finally {
// 7、关闭通道
if (channel != null && channel.isOpen()) {
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
} // 8、关闭连接
if (connection != null && connection.isOpen()) {
try {
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

package com.study.rabbitmq.a132.confirm;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException; /**
* 消息确认机制
*/ public class Consumer { private static Runnable receive = new Runnable() {
public void run() {
// 1、创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 2、设置连接属性
factory.setHost("192.168.100.242");
factory.setUsername("admin");
factory.setPassword("admin"); Connection connection = null;
Channel channel = null;
final String clientName = Thread.currentThread().getName(); try {
// 3、从连接工厂获取连接
connection = factory.newConnection("消费者");
// ###死信队列相关:专门用来存储 出错 出异常的数据
channel = connection.createChannel();
// 1、 创建一个exchange
channel.exchangeDeclare("dlq_exchange", "fanout");
// 2、 创建一个queue,和exchange绑定起来
channel.queueDeclare("dlq_queue1", false, false, false, null);
channel.queueBind("dlq_queue1", "dlq_exchange", "");
// ######死信队列结束 // 4、从链接中创建通道
channel = connection.createChannel();
// 代码定义交换器
channel.exchangeDeclare("ps_test", "fanout");
// 还可以定义一个临时队列,连接关闭后会自动删除,此队列是一个排他队列
String queueName = "queue1";
// 队列中有死信产生时,消息会转发到交换器 dlq_exchange。
Map<String, Object> args = new HashMap<String, Object>();
args.put("x-dead-letter-exchange", "dlq_exchange");
channel.queueDeclare(queueName, false, false, false, args);
// 将队列和交换器绑定
channel.queueBind(queueName, "ps_test", ""); // 监听队列
Channel finalChannel = channel;
channel.basicConsume(queueName, false, "消费者-手动回执",
new DefaultConsumer(finalChannel) {
@Override
public void handleDelivery(String consumerTag,
Envelope envelope,
AMQP.BasicProperties properties,
byte[] body)
throws IOException {
try {
System.out.println("收到消息: " + new String(body));
// TODO 业务处理
long deliveryTag = envelope.getDeliveryTag();
// 模拟业务处理耗时
Thread.sleep(1000L);
// 正常消费
// finalChannel.basicAck(deliveryTag, false);
// 异常消费
finalChannel.basicNack(envelope.getDeliveryTag(), false, false);
} catch (InterruptedException e) {
// 异常消费, requeue参数 true重发,false不重发(丢弃或者移到DLQ死信队列)
// finalChannel.basicNack(envelope.getDeliveryTag(), false, false);
e.printStackTrace();
}
}
}); System.out.println(clientName + " 开始接收消息");
System.in.read(); } catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
} finally {
// 8、关闭通道
if (channel != null && channel.isOpen()) {
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
} // 9、关闭连接
if (connection != null && connection.isOpen()) {
try {
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}; public static void main(String[] args) {
new Thread(receive, "c1").start();
} }

nack的数据都放在死信队列

dlq_queue的垃圾队列

RabbitMQ插件机制

消息中间件-RabbitMQ消息可靠性和插件化机制的更多相关文章

  1. RabbitMQ消息可靠性分析

    消息中间件的可靠性是指对消息不丢失的保障程度:而消息中间件的可用性是指无故障运行的时间百分比,通常用几个 9 来衡量.不存在绝对的可靠性只能尽量趋向完美.并且通常可靠性也意味着影响性能和付出更大的成本 ...

  2. RabbitMQ消息可靠性分析 - 简书

    原文:RabbitMQ消息可靠性分析 - 简书 有很多人问过我这么一类问题:RabbitMQ如何确保消息可靠?很多时候,笔者的回答都是:说来话长的事情何来长话短说.的确,要确保消息可靠不只是单单几句就 ...

  3. RabbitMQ消息可靠性分析和应用

    RabbitMQ流程简介(带Exchange) RabbitMQ使用一些机制来保证可靠性,如持久化.消费确认及发布确认等. 先看以下这个图: P为生产者,X为中转站(Exchange),红色部分为消息 ...

  4. 在.NET Core中使用简单的插件化机制

    前言 插件化,其实也并不是什么新东西了,像nopCommerce等开源项目都有类似的机制,而且功能比较完善和齐全. 相信大家都对接过不少支付方式,支付宝.微信以及各大银行或第三方的支付公司. 我们可以 ...

  5. RabbitMQ消息可靠性传输

    消息的可靠性投递是使用消息中间件不可避免的问题,不管是使用kafka.rocketMQ或者rabbitMQ,那么在RabbitMQ中如何保证消息的可靠性投递呢? 先再看一下RabbitMQ消息传递的流 ...

  6. [转载]RabbitMQ消息可靠性分析

    有很多人问过我这么一类问题:RabbitMQ如何确保消息可靠?很多时候,笔者的回答都是:说来话长的事情何来长话短说.的确,要确保消息可靠不只是单单几句就能够叙述明白的,包括Kafka也是如此.可靠并不 ...

  7. RabbitMQ消息可靠性、死信交换机、消息堆积问题

    目录 消息可靠性 生产者消息确认 示例 消费者消息确认 示例 死信交换机 例子 高可用问题 消息堆积问题 惰性队列 参考 消息可靠性 确保消息至少被消费了一次(不丢失) 消息丢失的几种情况: 消息在网 ...

  8. ASP.NET MVC 插件化机制

    概述 nopCommerce的插件机制的核心是使用BuildManager.AddReferencedAssembly将使用Assembly.Load加载的插件程序集添加到应用程序域的引用中.具 体实 ...

  9. ASP.NET MVC5 插件化机制简单实现

    一.前言 nopCommerce的插件机制的核心是使用BuildManager.AddReferencedAssembly将使用Assembly.Load加载的插件程序集添加到应用程序域的引用中.具体 ...

随机推荐

  1. Spring中的@Enable注解

    本文转载自SpringBoot中神奇的@Enable注解? 导语 在SpringBoot开发过程,我们经常会遇到@Enable开始的好多注解,比如@EnableEurekaServer.@Enable ...

  2. 关于Java中的对象、类、抽象类、接口、继承之间的联系

    关于Java中的对象.类.抽象类.接口.继承之间的联系: 导读: 寒假学习JavaSE基础,其中的概念属实比较多,关联性也比较大,再次将相关的知识点复习一些,并理顺其中的关系. 正文: 举个例子:如果 ...

  3. cxf实例异常

    基于CXF2.3.0 Caused by: java.lang.InstantiationException: org.apache.cxf.wstx_msv_validation.WoodstoxV ...

  4. 关于电脑硬盘的二三事(SATA接口)

    @ 目录 前言 接口分类 SATA3接口 机械硬盘 机械硬盘的特点和主要参数 西部数据机械盘分类 绿·蓝·黑盘 红盘 紫盘 金盘 希捷机械盘分类 酷狼 酷鱼 酷鹰 银河 SATA3接口的固态硬盘 固态 ...

  5. Error Code: 1366. Incorrect DECIMAL value: '0' for column '' at row -1 0.266 sec;

    Reference: https://stackoverflow.com/questions/35037288/incorrect-decimal-integer-value-mysql     Er ...

  6. python2与python3共存时的pip问题

    在树莓派上同时安装有python2和python3,初始的pip是9.01版本,用pip install django只能安装到1.11版本,但是我需要2.0的django. 于是升级pip: pyt ...

  7. Windows 环境下搭建 RocketMQ

    Apache 官网: http://rocketmq.apache.org/ RocketMQ 的 Github 地址: English:https://github.com/apache/rocke ...

  8. three.js cannon.js物理引擎之约束(二)

    今天郭先生继续讲cannon.js的物理约束,之前的一篇文章曾简单的提及过PointToPointConstraint约束,那么今天详细的说一说cannon.js的约束和使用方法.在线案例请点击博客原 ...

  9. 痞子衡嵌入式:FlexSPI复位方式不当会导致i.MXRT系列下OTFAD加密启动失败

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是FlexSPI复位方式不当会导致i.MXRT系列下OTFAD加密启动失败问题. 本篇是<系统时钟配置不当会导致i.MXRT1xxx ...

  10. Vmware虚拟机CentOS7、Ubuntu20系统设置静态IP,且主机和虚拟机系统能相互ping通。

    目录 前言 一.VMware虚拟系统centos7设置静态IP 1.1 打开VMware虚拟网络配置窗口 1.2 方法1:通过DHCP服务给主机动态分配IP,同时设置centos静态IP 1.2.1 ...