【RocketMQ】消息重试、重试次数设置、死信队列

2023-11-13

1. 死信队列

上一篇【RocketMQ】消息重试中我们提到当一条消息消费失败时,RocketMQ会进行一定次数的重试。重试的结果也很简单,无非就是在第N次重试时,被成功消费。或者就是经过M次重试后,仍然没有被成功消费。这通常是由于消费者在正常情况下无法正确地消费该消息。此时,RocketMQ不会立即将消息丢弃,而是将其发送到该消费者对应的特殊队列中去。

在RocketMQ中,这种正常情况下无法被消费的消息被称为死信消息(Dead-Letter Message),存储死信消息的特殊队列称为死信队列(Dead-Letter Queue)。

1.1 死信特性

(1)死信消息具有以下特性:

  • 不会再被消费者正常消费。
  • 有效期与正常消息相同,均为 3 天,3 天后会被自动删除。因此,请在死信消息产生后的 3 天内及时处理。

(2)死信队列具有以下特性:

  • 一个死信队列对应一个 Group ID, 而不是对应单个消费者实例。
  • 如果一个 Group ID 未产生死信消息,消息队列 RocketMQ 不会为其创建相应的死信队列。
  • 一个死信队列包含了对应 Group ID 产生的所有死信消息,不论该消息属于哪个 Topic。

1.2 查看死信消息

(1)在控制条查询出现死信队列的主题信息
在这里插入图片描述

(2)在消费界面根据主题查询死信消息
在这里插入图片描述
(3)选择重新发送消息

一条消息进入死信队列,意味着某些因素导致消费者无法正常消费该消息。因此,通常需要我们对其进行特殊处理。排查可疑因素并解决问题后,可以在消息队列 RocketMQ 控制台重新发送该消息,让消费者重新消费一次。

2.重试次数参数

RocketMQ的重试机制涉及发送端重试和消费端重试,消费端重试关联死信队列

2.1 Producer端重试

生产者端的消息失败,也就是Producer往MQ上发消息没有发送成功,比如网络抖动导致生产者发送消息到MQ失败。

这种消息失败重试我们可以手动设置发送失败重试的次数,看一下代码:

public class DefaultMQProducer  {
	//设置消息发送失败时的最大重试次数
	public void setRetryTimesWhenSendFailed(int retryTimesWhenSendFailed) {
	   this.retryTimesWhenSendFailed = retryTimesWhenSendFailed;
	}

在这里插入图片描述

2.2 Consumer端重试

注:只有在消息模式为MessageModel.CLUSTERING集群模式时,Broker才会自动进行重试,广播消息是不会重试的。

消费者消费消息后,需要给Broker返回消费状态。以MessageListenerConcurrently监听器为例,Consumer消费完成后需要返回ConsumeConcurrentlyStatus并发消费状态。查看源码,ConsumeConcurrentlyStatus是一个枚举,共有两种状态:

public enum ConsumeConcurrentlyStatus {
   //消费成功
   ConsumeConcurrentlyStatus,

   //消费失败,一段时间后重试
   RECONSUME_LATER;
}

Consumer端的重试包括两种情况

  • 异常重试:由于Consumer端逻辑出现了异常,导致返回了RECONSUME_LATER状态,那么Broker就会在一段时间后尝试重试。
  • 超时重试:如果Consumer端处理时间过长,或者由于某些原因线程挂起,导致迟迟没有返回消费状态,Broker就会认为Consumer消费超时,此时会发起超时重试。

因此,如果Consumer端正常消费成功,一定要返回ConsumeConcurrentlyStatus.ConsumeConcurrentlyStatus状态。

3.1 异常重试

RocketMQ可在broker.conf文件中配置Consumer端的重试次数和重试时间间隔,如下:

messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h

默认18时间间隔,表示重试18次,可以减少配置的数量吗?确切的说异常重试复用了延迟队列,因为如果失败了,立即重试,往往还是失败的,例如网络暂时中断,这样通过不断增加重试时间间隔,第一次失败,丢进1s的队列,第二次丢进5s的队列。利用延迟队列,保证了可以多次重试,并通过延迟时间确保业务尽量能成功。

如果用户没有配置,在有默认值(broker侧源码,不是客户端的源码),以rocketmq-all-4.7.1-source-release.zip为例(https://gitee.com/king_beijixiong/study-rocketmq/blob/master/rocketmq-all-4.7.1-source-release.zip):

public class MessageStoreConfig {
   private String messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h";
package org.apache.rocketmq.example.quickstart;

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.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;

import java.util.Date;
import java.util.List;

public class Consumer {

    public static void main(String[] args) throws InterruptedException, MQClientException {

        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group1");

        consumer.setNamesrvAddr("10.89.184.62:9876");
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);

        consumer.subscribe("TopicTest2", "*");

        consumer.registerMessageListener(new MessageListenerConcurrently() {

            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
                ConsumeConcurrentlyContext context) {

                System.out.println("date="+new Date()+" *******");

                for(MessageExt msg :msgs){
                    System.out.println("msg="+msg.getMsgId());
                    System.out.println("date="+new Date());
                    System.out.println("ReconsumeTimes="+msg.getReconsumeTimes());
                    System.out.println();
                }
                return ConsumeConcurrentlyStatus.RECONSUME_LATER;
                //  return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });


        consumer.start();

        System.out.printf("Consumer Started.%n");
    }
}

执行结果:

onsumer Started.
date=Fri Aug 05 14:08:52 CST 2022 *******
msg=0A28A4923EC018B4AAC217A272330000
date=Fri Aug 05 14:08:52 CST 2022
ReconsumeTimes=0                        '第一次处理'

date=Fri Aug 05 14:09:02 CST 2022 *******
msg=0A28A4923EC018B4AAC217A272330000
date=Fri Aug 05 14:09:02 CST 2022
ReconsumeTimes=1                       '第2次处理 与第一次间隔10s'

date=Fri Aug 05 14:09:33 CST 2022 *******
msg=0A28A4923EC018B4AAC217A272330000
date=Fri Aug 05 14:09:33 CST 2022
ReconsumeTimes=2						'第3次处理 与第2次间隔20s'

date=Fri Aug 05 14:10:33 CST 2022 *******
msg=0A28A4923EC018B4AAC217A272330000
date=Fri Aug 05 14:10:33 CST 2022
ReconsumeTimes=3                       '第4次处理 与第3次间隔1m'


.....后面还有,省略

从结果看,失败后会重试,并且每次间隔时间符合messageDelayLevel规律,当然跳过了1和5s,是从第三个开始的。

但是在大部分情况下,如果Consumer端逻辑出现异常,重试太多次也没有很大的意义,我们可以在代码中指定最大的重试次数。如下:

即提前返回成功状态,是假的成功,也不会进入死信队列。反之,捕获异常,每次返回RECONSUME_LATER,到18次就会进入死信队列

package william.rmq.consumer.quickstart;

import lombok.extern.slf4j.Slf4j;
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.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import william.rmq.common.constant.RocketMQConstant;

import javax.annotation.PostConstruct;
import java.util.List;

/**

* @Description:RocketMQ消息消费者
*/
@Slf4j
@Service
public class MessageConsumer implements MessageListenerConcurrently {
   @Value("${spring.rocketmq.namesrvAddr}")
   private String namesrvAddr;

   private final DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("DefaultConsumer");


   @PostConstruct
   public void start() {
       try {
           consumer.setNamesrvAddr(namesrvAddr);

           //从消息队列头部开始消费
           consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);

           //设置集群消费模式
           consumer.setMessageModel(MessageModel.CLUSTERING);

           //订阅主题
           consumer.subscribe("DefaultCluster", "*");

           //注册消息监听器
           consumer.registerMessageListener(this);

           //启动消费端
           consumer.start();

           log.info("Message Consumer Start...");
           System.err.println("Message Consumer Start...");
       } catch (MQClientException e) {
           log.error("Message Consumer Start Error!!",e);
       }

   }

   @Override
   public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
       if (CollectionUtils.isEmpty(msgs)) {
           return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
       }

       MessageExt message = msgs.get(0);
       try {
           //逐条消费
           String messageBody = new String(message.getBody(), RemotingHelper.DEFAULT_CHARSET);
           System.err.println("Message Consumer: Handle New Message: messageId: " + message.getMsgId() + ",topic: " +
                   message.getTopic() + ",tags: " + message.getTags() + ",messageBody: " + messageBody);

           //模拟业务异常
           int i = 1 / 0;
           return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
       } catch (Exception e) {
           log.error("Consume Message Error!!", e);
           //抛出异常时,返回ConsumeConcurrentlyStatus.RECONSUME_LATER,尝试重试。当重试指定次数后返回ConsumeConcurrentlyStatus.CONSUME_SUCCESS
           int reconsumeTimes = message.getReconsumeTimes();
           System.err.println("Now Retry Times: " + reconsumeTimes);
           if (reconsumeTimes >= RocketMQConstant.MAX_RETRY_TIMES) {
               return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
           }
           return ConsumeConcurrentlyStatus.RECONSUME_LATER;
       }
   }

}

可以看到控制台打印如下:

Now Retry Times: 3
Message Consumer: Handle New Message: messageId: 0A0E096CA14618B4AAC2562C6D5B0000,topic: DefaultCluster,tags: Tags,messageBody: Message-1
Now Retry Times: 3
Message Consumer: Handle New Message: messageId: C0A81FFA7FF318B4AAC24A37C32C0007,topic: DefaultCluster,tags: Tags,messageBody: Order-2-完成
Now Retry Times: 3
Now Retry Times: 3
Message Consumer: Handle New Message: messageId: C0A81FFA7FF318B4AAC24A37C3290006,topic: DefaultCluster,tags: Tags,messageBody: Order-2-支付
Now Retry Times: 3
Now Retry Times: 3

消息重试指定的次数后,就返回ConsumeConcurrentlyStatus.CONSUME_SUCCESS不再重试了。

3.2 超时重试

当Consumer处理时间过长,在超时时间内没有返回给Broker消费状态,那么Broker也会自动重试

package william.rmq.consumer.quickstart;

import lombok.extern.slf4j.Slf4j;
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.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import william.rmq.common.constant.RocketMQConstant;

import javax.annotation.PostConstruct;
import java.util.List;

/**
* @Auther: ZhangShenao
* @Date: 2018/9/7 11:06
* @Description:RocketMQ消息消费者
*/
@Slf4j
@Service
public class MessageConsumer implements MessageListenerConcurrently {
   @Value("${spring.rocketmq.namesrvAddr}")
   private String namesrvAddr;

   private final DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("DefaultConsumer");


   @PostConstruct
   public void start() {
       try {
           consumer.setNamesrvAddr(namesrvAddr);

           //从消息队列头部开始消费
           consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);

           //设置集群消费模式
           consumer.setMessageModel(MessageModel.CLUSTERING);

           //设置消费超时时间(分钟)
           consumer.setConsumeTimeout(RocketMQConstant.CONSUMER_TIMEOUT_MINUTES);

           //订阅主题
           consumer.subscribe("DefaultCluster", "*");

           //注册消息监听器
           consumer.registerMessageListener(this);

           //启动消费端
           consumer.start();

           log.info("Message Consumer Start...");
           System.err.println("Message Consumer Start...");
       } catch (MQClientException e) {
           log.error("Message Consumer Start Error!!",e);
       }

   }

   @Override
   public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
       if (CollectionUtils.isEmpty(msgs)) {
           return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
       }

       MessageExt message = msgs.get(0);
       try {
           //逐条消费
           String messageBody = new String(message.getBody(), RemotingHelper.DEFAULT_CHARSET);
           System.err.println("Message Consumer: Handle New Message: messageId: " + message.getMsgId() + ",topic: " +
                   message.getTopic() + ",tags: " + message.getTags() + ",messageBody: " + messageBody);

           //模拟耗时操作2分钟,大于设置的消费超时时间
           Thread.sleep(1000L * 60 * 2);
           return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
       } catch (Exception e) {
           log.error("Consume Message Error!!", e);
           return ConsumeConcurrentlyStatus.RECONSUME_LATER;
       }
   }

}

可以看到, Thread.sleep耗时超过最大超时时间,触发失败

参考

RocketMQ:死信队列和消息幂等
RocketMQ详解(12)——RocketMQ的重试机制
源码分析RocketMQ之消息消费重试机制 broker源码,含有16次最大重试次数源码

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【RocketMQ】消息重试、重试次数设置、死信队列 的相关文章

  • RocketMQ 安装

    镜像方式安装 首先再把上一接中提到的 RocketMQ 部署架构图看一下 从图中可以看出 RocketMQ的服务端分为两块 Name Server 和 Broker Name Server 是一个几乎无状态节点 可集群部署 在消息队列Roc
  • RocketMQ-Broker异常恢复后部分队列重新加载已消费消息问题解决

    问题描述 线上Broker所有在主机IO异常 导致Broker异常退出 主机问题解决后 重启Broker 发现group A的几个consumeQueue diff值有几十万 而通过查看日志信息发现该Group的consumeQueue只有
  • Docker 部署 RocketMQ

    文章目录 安装nameserver 拉取镜像 运行容器 出现问题卸载 安装broker 创建配置文件 运行容器 出现问题卸载 安装控制台 拉取镜像 运行容器 出现问题卸载 安装nameserver 拉取镜像 docker pull rock
  • Linux 安装 RocketMQ(Server)

    安装 linux版 官网下载地址 解压上传至 usr local 进入上传文件目录 cd usr local rocketmq all 4 7 0 source release bin 修改runbroker sh 修改runserver
  • 【Linux系统安装RocketMQ并整合到SpringBoot项目】

    Linux系统安装RocketMQ并整合到SpringBoot项目 一 基本概念 1 1 NameServer 1 2 Broker 1 3 Message 1 3 Topic 1 4 Tag 1 5 Queue 1 6 MessageId
  • rocketmq安装、启动

    1 下载 gt wget http mirror bit edu cn apache rocketmq 4 4 0 rocketmq all 4 4 0 source release zip gt unzip rocketmq all 4
  • RocketMQ Pull和Push

    在rocketmq里 consumer被分为2类 MQPullConsumer和MQPushConsumer 其实本质都是拉模式 pull 即consumer轮询从broker拉取消息 区别是 push方式里 consumer把轮询过程封装
  • centos安装rocketmq

    centos安装rocketmq 1 下载rocketmq二进制包 2 解压二进制包 3 修改broker conf 4 修改runbroker sh和runserver sh的JVM参数 5 启动NameServer和Broker 6 安
  • RocketMQ订阅关系一致性分析

    RocketMQ的消费者 在订阅topic的时候需要遵循 订阅关系一致性 原则 即 一个消费者分组 group 下的所有消费者实例的处理逻辑必须一致 一旦订阅关系不一致就会导致消费混乱 甚至消息丢失 对大多数分布式应用来说 一个group下
  • Flink RocketMQ Connector实现

    Flink内置了很多Connector 可以满足大部分场景 但是还是有一些场景无法满足 比如RocketMQ 需要消费RocketMQ的消息 需要自定时Source 一 自定义FlinkRocketMQConsumer 参考FlinkKaf
  • rocketMq消息队列原生api使用以及rocketMq整合springboot

    rocketMq消息队列 文章目录 rocketMq消息队列 一 RocketMQ原生API使用 1 测试环境搭建 2 RocketMQ的编程模型 3 RocketMQ的消息样例 3 1 基本样例 3 2 顺序消息 3 3 广播消息 3 4
  • 报错:ImportError: rocketmq dynamic library not found解决方法

    目录 一 ImportError rocketmq dynamic library not found 二 OSError librocketmq so cannot open shared object file No such file
  • 【RocketMQ】NameServer总结

    NameServer是一个注册中心 提供服务注册和服务发现的功能 NameServer可以集群部署 集群中每个节点都是对等的关系 没有像ZooKeeper那样在集群中选举出一个Master节点 节点之间互不通信 服务注册 Broker启动的
  • RocketMQ消费者端消息列队六种负载均衡算法分析

    在RocketMQ启动的时候会启动负载均衡线程 过程如下 DefaultMQPullConsumerImpl start mQClientFactory start 上面点进去 gt MQClientInstance start rebal
  • RocketMQ经典高频面试题大全(附答案)

    编程界的小学生 0 彩蛋 1 说说你们公司线上生产环境用的是什么消息中间件 2 多个mq如何选型 3 为什么要使用MQ 4 RocketMQ由哪些角色组成 每个角色作用和特点是什么 5 RocketMQ中的Topic和JMS的queue有什
  • Failed to execute goal on project rocketmq-console-ng: Could not resolve dependencies for project

    Apache RocketMQ安装部署 Failed to execute goal on project rocketmq console ng Could not resolve dependencies for project org
  • RocketMQ 消息过滤

    1 简介 RocketMQ分布式消息队列的消息过滤方式有别于其它MQ中间件 是在Consumer端订阅消息时 再做消息过滤的 RocketMQ这么做是在于其Producer端写入消息和Consumer端订阅消息采用分离存储的机制来实 现的
  • RocketMQ-源码解读与调试

    源码环境搭建 源码拉取 RocketMQ的官方Git仓库地址 GitHub apache rocketmq Mirror of Apache RocketMQ 可以用git把项目clone下来或者直接下载代码包 也可以到RocketMQ的官
  • 基于Jmeter实现Rocketmq消息发送

    在互联网企业技术架构中 MQ占据了越来越重要的地位 系统解耦 异步通信 削峰填谷 数据顺序保证等场景中 到处都能看到MQ的身影 而测试工程师在工作中 也经常需要和mq打交道 比如构造测试数据 触发某些业务场景 以及针对mq的性能测试等 目前
  • RocketMQ源码(26)—DefaultMQPushConsumer事务消息源码【一万字】

    事务消息是RocketMQ的一大特性 其被用来实现分布式事务 关于RocketMQ的事务消息的相关原理的介绍见这篇博客 RocketMQ的分布式事务机制 事务消息 关于事务消息的基本案例看这里 消息事务样例 本文主要介绍RocketMQ的事

随机推荐

  • Idea部署项目时遇到Errors occurred while compiling module的时候,可能遇到的问题

    xxx模块编译错误 java内部编辑器错误 问题原因 模块或项目java版本不一致 解决思路 1 首先检查pom文件制定的java版本是否与项目的一致 打开项目编辑器 快捷键Ctrl Alt Shilt S 2 再检查模块的java版本是否
  • 力扣之两数之和(题号1)

    题目叙述 给定一个整数数组 nums 和一个目标值 target 请你在该数组中找出和为目标值的那 两个 整数 并返回他们的数组下标 你可以假设每种输入只会对应一个答案 但是 你不能重复利用这个数组中同样的元素 示例 给定 nums 2 7
  • 在一个数组中找出两个数,这两个数之和为指定目标值,返回这两个数下标(leecode)(c++)

    本文主要总结在一个数组中取出两个数 这两个数满足条件为 两数之和为制定目标值target 并且函数返回这两个数下表 示例 给定 nums 5 6 7 8 9 10 target 19 因为 nums 4 nums 5 9 10 19 所以返
  • 在Windows下源码编译LLVM(MingW)

    前言 由于最近工作项目需要 需要在windows下基于mingw 即使用gcc编译器 非vc的编译器 编译LLVM 踩坑无数 仅此一记 环境 win10 64位专业版 准备 试过很多种编译方式 最终发现还是msys2比较靠谱 即在windo
  • R语言与机器学习中的回归方法学习笔记

    机器学习中的一些方法如决策树 随机森林 SVM 神经网络由于对数据没有分布的假定等普通线性回归模型的一些约束 预测效果也比较不错 交叉验证结果也能被接受 下面以R中lars包包含数据集diabetes为例说明机器学习中的回归方法 一 数据集
  • JAVA根据模板生成Word文档

    一 需要模板word文件和document xml模板配置文件 首先把word文件重命名后缀改为 zip然后打开 就能在word文件夹下就能找到document xml了 在document xml模板中需要赋值的地方配置好占位符 二 导入
  • CNN调参

    一 学习率 学习率决定了每步权重更新对当前权重的改变程度 其中E w 为我们优化的损失函数 是学习率 学习率太小 更新速度慢 学习率过大 可能跨过最优解 因此 在刚开始训练 距离最优解较远时可以采用稍大的学习率 随着迭代次数增加 在逼近最优
  • 自动化测试框架rf(Robot Framework)的安装

    2022了 还没自己装过rf 网上找了不少文章 或多或少都跟本地环境不太一下 作为新手 把安装过程做一次记录分享 仅供参考 首先 帖一下我自己电脑的基本情况 下面就开始吧 一 JAVA环境安装 现在基本都是java8以上了 所以建议到官网下
  • Node.js中gulp插件的安装使用

    1 Node js说明 gulp是用JavaScript语言编写的运行在Node js平台开发的前端构建工具 是前端开发人员自动处理日常任务的首选工具 gulp cli 启动构建工具的命令行接口 本地gulp 构建时实际运行的程序 gulp
  • [OLED] 利用stm32开发板控制OLED

    一 OLED的介绍 OLED 即有机发光二极管 Organic Light Emitting Diode 又称为有机电激光显示 Organic Electroluminesence Display OELD OLED由于同时具备自发光 不需
  • 连续时间、离散时间信号、模拟和数字信号辨析

    连续时间和离散时间信号 一个信号 它是在时间t的连续值上给出的 就是一个连续时间信号 而一个信号仅在t的离散值上给出则是一个离散时间信号 模拟和数字信号 凡一个信号的幅度在某一连续范围内能够取到任何值的信号就是模拟信号 这意味着一个模拟信号
  • 牛客 124G--组合游戏

    链接 https www nowcoder com acm contest 124 G来源 牛客网 题目描述 2018年4月8日星期日 小龙沉迷于一个叫做组合的游戏 游戏规则是这样的 原本有一个长度为A的大木板 现在把它分成了n份长度可能不
  • Excel如何排序?掌握3种排序方法!

    我是个刚开始学习Excel的新手 对很多Excel的知识都不太熟悉 今天使用Excel进行表格排序时我又遇到了一些问题 请问Excel如何排序呢 希望给我一些建议 在Excel中 排序是一种常见且有用的数据处理操作 它可以帮助您按照特定的规
  • Unbutn20+cuda11+Qt下配置

    首先装CUDA 具体查看其它博客 这里主要介绍如何配置 CONFIG console TARGET test Define output directories CUDA OBJECTS DIR This makes the cu file
  • 面了个阿里拿36K出来的,真是砂纸擦屁股,给我漏了一手

    今年的春招已经结束 很多小伙伴收获不错 拿到了心仪的 offer 各大论坛和社区里也看见不少小伙伴慷慨地分享了常见的面试题和八股文 为此咱这里也统一做一次大整理和大归类 这也算是划重点了 俗话说得好 他山之石 可以攻玉 多看多借鉴还是有帮助
  • js实现图片预加载

    什么是预加载 当页面打开图片提前加载 而且缓存在用户本地 需要用届时直接进行烘托 在浏览图片较多的网页 百度图库 淘宝京东等 能够有更好的用户体会 一张图片的预加载 var img new Image img addEventListene
  • pandas 导入excel_小白学 Python 数据分析(7):Pandas (六)数据导入

    人生苦短 我用 Python 前文传送门 小白学 Python 数据分析 1 数据分析基础 小白学 Python 数据分析 2 Pandas 一 概述 小白学 Python 数据分析 3 Pandas 二 数据结构 Series 小白学 P
  • echarts 生成的canvas只有100px的问题

    在开发中遇到一个问题 使用echarts的时候 生成的canvas宽度不是实际写入的宽度 后面发现 因为使用了el tabs 存在echarts的tab页在刚开始处于display none 所以echarts拿不到页面的宽度 解决办法 在
  • Burp suite ——爆破账户密码(含爆破token防爆破)

    此文章仅供交流学习使用 目录 爆破普通账户密码 设置环境 处理burp suite的抓包数据 开始爆破 爆破token防爆破账户密码 设置环境 处理抓包数据 开始爆破 爆破普通账户密码 设置环境 1 打开火狐访问此网站 更改代理 火狐浏览器
  • 【RocketMQ】消息重试、重试次数设置、死信队列

    文章目录 1 死信队列 1 1 死信特性 1 2 查看死信消息 2 重试次数参数 2 1 Producer端重试 2 2 Consumer端重试 3 1 异常重试 3 2 超时重试 参考 1 死信队列 上一篇 RocketMQ 消息重试中我