RabbitMQ/RocketMQ消息可靠性保证

2022-11-04 17:22:08 689

RabbitMQ

RabbitMQ刷盘机制

  1. 异步
写入文件前会有一个Buffer,大小为1M(1048576),数据在写入文件时,首先会写入到这个Buffer,如果Buffer已满,则会将Buffer写入到文件(此时写入到内核态缓存中, 未必刷到磁盘);有个固定的刷盘时间:25ms,也就是不管Buffer满不满,每隔25ms,Buffer里的数据及未刷新到磁盘的文件内容必定会刷到磁盘(调用系统fsync);每次消息写入后,如果没有后续写入请求,则会直接将已写入的消息刷到磁盘:使用Erlang的receive x after 0来实现,只要进程的信箱里没有消息,则产生一个timeout消息,而timeout会触发刷盘操作
  1. 同步
Broker接收到消息后立即同步到磁盘

RabbitMQ如何保证消息不丢失

  1. 发送者确认
对于rabbitMQ,发布者确认需要手动开启,默认是没有开启的,也就是说默认情况下我们消息发出去就完事儿了,但是服务端有没有成功处理并不一定,此时虽然消息发布成功但是broker可能并没有正确处理该消息导致消息丢失,所以为了消息的可靠性,我们需要开启发布确认;开启了发布确认后,在我们发布完消息后服务端会在接收到消息并成功处理后返回给我们一个ack,表示消息接收处理完毕(注意,只是broker端处理完毕,不是消费者消费完成)而broker的ack时机对于我们很关键,broker会在以下时机给我们返回ack:如果未开启消息持久化,则消息在被路由到各个队列(如果是镜像队列,这意味着所有镜像队列都成功接收到消息)后broker返回ack;如果开启消息持久化,则消息在被路由到各个队列并且所有需要持久化的队列持久化完成后返回ack;而如果其中某部分队列持久化未完成则broker会返回nack,表示服务端接收失败,需要生产者重新发布消息;注意:此时虽然部分队列持久化失败,但是持久化成功的那部分是不会回滚的,也就是说对于持久化成功的队列上绑定的消费者可能会重复收到消息,此时消费者应该去重;
可以看出,发布者确认可以解决消息异步持久化中的问题,这两项措施保证了我们的消息肯定会发布成功并且不会丢失,后续就是消费者的事情了; 注意:其实以上措施只能保证在硬件正常的情况下消息不会丢失,而如果broker是单点部署的,则这个broker的磁盘损坏仍然会导致数据丢失,而如果broker是集群部署的,如果集群中所有broker的磁盘都损坏,此时消息也会丢失,由于硬件故障是无法避免的,只能根据消息的重要性做集群,集群规模越大、磁盘可靠性越高,消息丢失的概率越小;
  1. 消费者确认
  2. 队列/交换机持久化
  3. 消息持久化

RocketMQ

刷盘机制

  1. 异步
写入缓存返回成功, 由异步线程进行刷盘
  1. 同步
写入磁盘返回成功

如何保证消息不丢失
思路与RabbitMQ一致

RocketMQ最佳实践
https://github.com/apache/rocketmq/blob/master/docs/cn/best_practice.md


排查记录: Java所有接口卡死

线上接口, 每天凌晨三四点后开始卡死, 重启后恢复调用后等待两分钟, 然后504两分钟正好是nginx反代的超时时间排查过程日志把nginx和应用日志都找出来看了下, 没发现什么问题应用机器状态看了下cpu占用率/内存, 没问题磁盘占用也没问题应用状态通过jps查找到java进程然后jstack 进
2024-11-07

RabbitMQ/RocketMQ消息可靠性保证

RabbitMQRabbitMQ刷盘机制异步写入文件前会有一个Buffer,大小为1M(1048576),数据在写入文件时,首先会写入到这个Buffer,如果Buffer已满,则会将Buffer写入到文件(此时写入到内核态缓存中, 未必刷到磁盘);有个固定的刷盘时间:25ms,也就是不管Buffer
2022-11-04

自定义rocketmq-spring-boot-starter

一般使用rocketmq-starter都会进行不同程度的封装, 在此分享一种封装思路基于rocketmq-spring-boot-starter <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rock
2022-09-26

RabbitMQ架构及特性

rabbitmq:3.9.2 spring-boot-starter-amqp:2.3.0.RELEASE 架构Producer 生产者消息成功发送到交换机, 会触发回调事件ConfirmCallback(需要配置)消息不能被交换机转发到队列中时, 会触发回调事件ReturnCallback(需要配
2021-08-18

RocketMQ解决消息发送与业务落库的一致性

在实际业务中, 经常有如下场景更新一条数据后, 需要发送一条消息异步通知其他服务进行后续处理比如用户完成激活, 发送一条消息通知第三方服务同步用户状态那么会有如下代码@Transactional public void enabled() { //更新用户状态 updateUser(
2021-04-21

RocketMQ架构及特性

架构RocketMQ包含四个组件NameServer, Broker, Consumer, ProducerNameServer类似注册中心, Broker接收存储消息, Consumer和Producer在项目内定义Broker向所有NameServer注册自己, 持续发送心跳包Consumer和
2024-10-23

freemarker 时间显示不正常 设置时区

项目在本地开发的时候显示正常,部署上服务器就一直差8个小时,最后发现freemarker官方文档有这样的说明time_zone:时区的名称来显示并格式化时间。 默认情况下,使用JVM的时区。 也可以是 Java 时区 API 接受的值,或者 "JVM default" (从 FreeMarker 2
2020-03-28
IDEA 2019.1 xml 不高亮

IDEA 2019.1 xml 不高亮

前几天更新了idea后,发现xml里的代码都没有了高亮,变得跟记事本一个德性了打开setting ,搜索 File Types,找到xml项, 查看下方的匹配格式,果然没有xml,(idea真是厉害)点击右方的+,输入*.xml,点击ok,解决问题
2020-03-28

npm install 淘宝镜像

npm install --registry=https://registry.npm.taobao.org
2020-03-28
Java中方法的参数传递机制

Java中方法的参数传递机制

来看一段代码 public class Man { private String name; private Integer age; public String getName() { return name; } publi
2020-03-28
基于自定义注解手写权限控制

基于自定义注解手写权限控制

方法一: AOP 方法二: 拦截器项目结构项目依赖<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-w
2020-03-28

Docker 部署 详细全过程 附代码

Docker 部署本站 全过程环境:CentOS7.61. 安装Docker其他版本CentOS可以参考这个https://help.aliyun.com/document_detail/187598.html查看本机内核版本,内核版本需高于 3.10uname -r 确保 yum 包最新yum u
2020-03-28

SpringBoot 启动普通java工程

引入依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.0.9</version> </dependency>
2020-03-28

Vue.js DOM操作

<template> <input type="button" @click="reply($event)" value="回复"> </template> export default { methods: { replyFun(e) {
2020-03-29
CentOS7编译调试OpenJDK12

CentOS7编译调试OpenJDK12

1. 下载源码https://hg.openjdk.java.net/jdk/jdk12点击左侧的browse,再点击zip,就可以下载zip格式的源码压缩包。unzip xxx.zip 解压文件2. 安装jdkyum install java-11-openjdk-devel -y3. 运行con
2020-04-23
编写自己的Spring Boot Starter

编写自己的Spring Boot Starter

1.新建一个maven项目命名规则统一是xxx-spring-boot-starter完整pom.xml<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"
2020-06-29