RabbitMQ--集成Springboot--3.2--消息确认机制

2023-10-27

RabbitMQ–集成Springboot–3.2–消息确认机制


代码位置

https://gitee.com/DanShenGuiZu/learnDemo/tree/master/rabbitMq-learn/rabbitMq-01

1、介绍

  1. 消息确认有2种,如下所示
    1. 生产者 消息确认
    2. 消费者 消息确认
  2. 要使用消息确认,还需要修改配置文件

1.1、修改配置文件

server:
  port: 8080
spring:
  #给项目来个名字
  application:
    name: rabbitmq-learn
  #配置rabbitMq 服务器
  rabbitmq:
    host: 192.168.187.171
    port: 5672
    username: root
    password: root
    #虚拟host 可以不设置,使用server默认host
    virtual-host: test
    #确认消息已发送到队列(Queue)
    publisher-returns: true
    #确认消息已发送到交换机(Exchange)
    publisher-confirm-type: correlated

在这里插入图片描述

2、生产者 消息确认

2.1、配置 消息确认回调函数

在这里插入图片描述


/**
 * MQ发送确认
 *
 * @author <a href="920786312@qq.com">周飞</a>
 * @class: ConfirmCallbackImpl
 * @date 2021/9/8 9:51
 * @Verson 1.0 -2021/9/8 9:51
 * @see
 */
public class ConfirmCallbackImpl implements RabbitTemplate.ConfirmCallback {
    Logger logger = LoggerFactory.getLogger(getClass());
    
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        // 消息没有发送成功
        
        if (ack) {
            logger.info("ConfirmCallbackImpl  消息发送成功,ack:" + ack);
            return;
        }
        logger.error("ConfirmCallbackImpl  消息发送失败,ack:" + ack);
        logger.error("ConfirmCallbackImpl  相关数据:" + correlationData);
        logger.error("ConfirmCallbackImpl  确认情况:" + "确认情况:" + ack);
        logger.error("ConfirmCallbackImpl  原因:" + cause);
        
    }
}
/**
 * 发送回调函数,发送消息成功是不会执行这个回调函数的
 *
 * @author <a href="920786312@qq.com">周飞</a>
 * @class: ReturnCallbackImpl
 * @date 2021/9/8 9:51
 * @Verson 1.0 -2021/9/8 9:51
 * @see
 */
public class ReturnCallbackImpl implements RabbitTemplate.ReturnCallback {
    Logger logger = LoggerFactory.getLogger(getClass());
    
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        logger.error("ReturnCallbackImpl 消息:" + message);
        logger.error("ReturnCallbackImpl 回应码:" + replyCode);
        logger.error("ReturnCallbackImpl 回应信息:" + replyText);
        logger.error("ReturnCallbackImpl 交换机:" + exchange);
        logger.error("ReturnCallbackImpl 路由键:" + routingKey);
        
    }
}

/**
 * 配置Rabbit
 **/
@Configuration
public class RabbitConfig {

    /**
     * 配置RabbitMQ 模板
     **/
    @Bean
    public RabbitTemplate createRabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(connectionFactory);
        // 设置开启Mandatory,才能触发回调函数,无论消息推送结果怎么样都强制调用回调函数
        rabbitTemplate.setMandatory(true);

        //配置回调函数
        rabbitTemplate.setConfirmCallback(new ConfirmCallbackImpl());
        rabbitTemplate.setReturnCallback(new ReturnCallbackImpl() );
        return rabbitTemplate;
    }
    
}

到这里,生产者推送消息的消息确认调用回调函数已经完毕。

2.2、消息确认回调函数 的 触发场景

  1. 消息推送到server,但是在server里找不到交换机
  2. 消息推送到server,找到交换机了,但是没找到队列
  3. 消息推送到sever,交换机和队列啥都没找到
  4. 消息推送成功

2.2.1、代码

@Configuration
public class ACK_Config {
    
    // 声明队列
    // @param1 队列名称
    // @param2 是否持久化 持久化:RabbitMQ服务器重启,队列还存在;反之,不存在。
    // 持久化的队列中的消息会存盘,不会随着服务器的重启会消失
    // @param3 排他性 是否独占一个队列(一般不会),true:只能被当前创建的连接使用,而且当连接关闭后队列即被删除
    // @param4 是否自动删除 随着最后一个消费者消费消息完毕后,是否自动删除这个队列
    // @param5 携带一些附加信息 供其它消费者获取
    @Bean
    public Queue ack_direct_queue() {
        return new Queue("ack_direct_queue", true, false, false, null);
        
    }
    
    // 声明交换机
    @Bean
    public DirectExchange ack_direct_exchange() {
        return new DirectExchange("ack_direct_exchange");
    }
    
    // 声明交换机与队列之间的关系
    @Bean
    public Binding bindingAck_direct_queue(Queue ack_direct_queue, DirectExchange ack_direct_exchange) {
        return BindingBuilder.bind(ack_direct_queue).to(ack_direct_exchange).with("ack");
    }
    
    @Bean
    // 验证 消息推送到server,找到交换机了,但是没找到队列
    DirectExchange lonelyDirectExchange() {
        return new DirectExchange("lonelyDirectExchange");
    }
}

@Component
public class ACK_Consumer {
    
    @RabbitListener(queues = { "ack_direct_queue" })
    public void receive(Message message, Channel channel) throws Exception {
        // 消息id
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        System.out.println("ack_direct_queue队列消息:" + new String(message.getBody()));
    }
    
}
@RestController
@RequestMapping("/ack")
public class ACK_Producer {
    
    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    @RequestMapping("/sendMsg")
    public String sendMsg() {
        String msg = "消息推送到server,但是在server里找不到交换机";
        rabbitTemplate.convertAndSend("non-existent-exchange", "ack", msg);
        return "ok";
    }
    
    @RequestMapping("/sendMsg2")
    public String sendMsg2() {
        String msg = "消息推送到server,找到交换机了,但是没找到队列";
        rabbitTemplate.convertAndSend("lonelyDirectExchange", "ack", msg);
        return "ok";
    }
    
    @RequestMapping("/sendMsg3")
    public String sendMsg3() {
        String msg = "消息推送到sever,交换机和队列啥都没找到";
        rabbitTemplate.convertAndSend("non-existent-exchange", "non-routingkey", msg);
        return "ok";
    }
    
    @RequestMapping("/sendMsg4")
    public String sendMsg4() {
        String msg = "消息推送成功";
        rabbitTemplate.convertAndSend("ack_direct_exchange", "ack", msg);
        return "ok";
    }
}

2.2.2、测试

2.2.2.1、消息推送到server,但是在server里找不到交换机
http://127.0.0.1:8080/ack/sendMsg1
日志
2022-08-27 16:52:12.104 ERROR 72720 --- [68.187.171:5672] o.s.a.r.c.CachingConnectionFactory       : Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'non-existent-exchange' in vhost 'test', class-id=60, method-id=40)
2022-08-27 16:52:12.105 ERROR 72720 --- [nectionFactory1] f.z.r.b.a.c.p.ConfirmCallbackImpl        : ConfirmCallbackImpl  消息发送失败,ack:false
2022-08-27 16:52:12.105 ERROR 72720 --- [nectionFactory1] f.z.r.b.a.c.p.ConfirmCallbackImpl        : ConfirmCallbackImpl  相关数据:null
2022-08-27 16:52:12.105 ERROR 72720 --- [nectionFactory1] f.z.r.b.a.c.p.ConfirmCallbackImpl        : ConfirmCallbackImpl  确认情况:确认情况:false
2022-08-27 16:52:12.105 ERROR 72720 --- [nectionFactory1] f.z.r.b.a.c.p.ConfirmCallbackImpl        : ConfirmCallbackImpl  原因:channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'non-existent-exchange' in vhost 'test', class-id=60, method-id=40)




  1. 报错原因,没有找到交换机’non-existent-exchange’,因为我们就没有配置这个交换机
  2. 这种情况触发的是 ConfirmCallback 回调函数。
2.2.2.2、消息推送到server,找到交换机了,但是没找到队列
http://127.0.0.1:8080/ack/sendMsg2
日志
2022-08-27 16:53:53.108  INFO 72720 --- [nectionFactory3] f.z.r.b.a.c.p.ConfirmCallbackImpl        : ConfirmCallbackImpl  消息发送成功,ack:true
2022-08-27 16:53:53.108 ERROR 72720 --- [nectionFactory4] f.z.r.b.a.c.producer.ReturnCallbackImpl  : ReturnCallbackImpl 消息:(Body:'消息推送到server,找到交换机了,但是没找到队列' MessageProperties [headers={}, contentType=text/plain, contentEncoding=UTF-8, contentLength=0, receivedDeliveryMode=PERSISTENT, priority=0, deliveryTag=0])
2022-08-27 16:53:53.108 ERROR 72720 --- [nectionFactory4] f.z.r.b.a.c.producer.ReturnCallbackImpl  : ReturnCallbackImpl 回应码:312
2022-08-27 16:53:53.108 ERROR 72720 --- [nectionFactory4] f.z.r.b.a.c.producer.ReturnCallbackImpl  : ReturnCallbackImpl 回应信息:NO_ROUTE
2022-08-27 16:53:53.108 ERROR 72720 --- [nectionFactory4] f.z.r.b.a.c.producer.ReturnCallbackImpl  : ReturnCallbackImpl 交换机:lonelyDirectExchange
2022-08-27 16:53:53.109 ERROR 72720 --- [nectionFactory4] f.z.r.b.a.c.producer.ReturnCallbackImpl  : ReturnCallbackImpl 路由键:ack
  1. 消息是成功推送到服务器了,所以ConfirmCallback对消息确认情况是true
  2. 报错原因:消息是推送到了交换机成功了,但是在路由分发给队列的时候,找不到队列,所以报了错误 NO_ROUTE。
    1. 找不到队列的原因是我们配置 lonelyDirectExchange交换机,就没配置绑定队列
  3. 这种情况触发的是 ConfirmCallback和RetrunCallback两个回调函数。
2.2.2.3、消息推送到sever,交换机和队列啥都没找到
http://127.0.0.1:8080/ack/sendMsg3
日志

2022-08-27 16:57:24.035 ERROR 72720 --- [68.187.171:5672] o.s.a.r.c.CachingConnectionFactory       : Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'non-existent-exchange' in vhost 'test', class-id=60, method-id=40)
2022-08-27 16:57:24.035 ERROR 72720 --- [nectionFactory6] f.z.r.b.a.c.p.ConfirmCallbackImpl        : ConfirmCallbackImpl  消息发送失败,ack:false
2022-08-27 16:57:24.035 ERROR 72720 --- [nectionFactory6] f.z.r.b.a.c.p.ConfirmCallbackImpl        : ConfirmCallbackImpl  相关数据:null
2022-08-27 16:57:24.035 ERROR 72720 --- [nectionFactory6] f.z.r.b.a.c.p.ConfirmCallbackImpl        : ConfirmCallbackImpl  确认情况:确认情况:false
2022-08-27 16:57:24.035 ERROR 72720 --- [nectionFactory6] f.z.r.b.a.c.p.ConfirmCallbackImpl        : ConfirmCallbackImpl  原因:channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'non-existent-exchange' in vhost 'test', class-id=60, method-id=40)

  1. 报错原因,没有找到交换机’non-existent-exchange’,因为我们就没有配置这个交换机
  2. 这种情况触发的是 ConfirmCallback 回调函数。
2.2.2.4、消息推送成功
http://127.0.0.1:8080/ack/sendMsg4

日志

2022-08-27 16:59:58.176  INFO 72720 --- [nectionFactory7] f.z.r.b.a.c.p.ConfirmCallbackImpl        : ConfirmCallbackImpl  消息发送成功,ack:true

3、消费者 消息确认

3.1、确认机制主要存在三种模式

3.1.1、自动确认

  1. 默认的消息确认机制
  2. RabbitMQ成功将消息发出后(将消息成功写入TCP Socket中),就认为本次投递已经被正确处理,不管消费者端是否成功处理本次投递。
  3. 如果消费端消费逻辑抛出异常,也就是消费端没有处理成功这条消息,那么就相当于丢失了消息。

3.1.2、根据情况确认

这个不做介绍

3.1.3、手动确认

  1. 手动ACK
  2. 消费者收到消息后,手动调用以下方法后,RabbitMQ收到这些消息后,才认为本次投递成功。
    1. basic.ack
    2. basic.nack
    3. basic.reject

3.2、手动确认确认方法

3.2.1、basic.ack(deliveryTag, false)

  1. 表示消息已经被正确处理
  2. 第1个参数:消息id
  3. 第2个参数:表示是指是否针对多条消息
    1. true:小于 当前这条消息的delivery_tag 的所有消息,都确认
    2. false:只确认当前这条消息

3.2.2、channel.basicNack(deliveryTag, false, true)

  1. 用于否定确认
  2. 第1个参数:消息id
  3. 第2个参数:表示是指是否针对多条消息
    1. true:小于 当前这条消息的delivery_tag 的所有消息,都拒绝确认
    2. false:只拒绝当前这条消息
  4. 第3个参数:是否重新入列
    1. true
      1. 消息重新丢回队列里,下次还会消费这消息
      2. 这个配置要谨慎,要考虑 消费-入列-消费-入列 这样循环情况,会导致消息积压。
    2. false
      1. 消息不丢回队列里,服务器丢失这条消息

3.2.3、channel.basicReject(deliveryTag, false)

  1. 拒绝消费当前消息
  2. 与basic.nack相比有一个限制:一次只能拒绝单条消息
  3. 第1个参数:消息id
  4. 第2个参数:是否重新入列
    1. true
      1. 消息重新丢回队列里,下次还会消费这消息
      2. 这个配置要谨慎,要考虑 消费-入列-消费-入列 这样循环情况,会导致消息积压。
    2. false
      1. 消息不丢回队列里,服务器丢失这条消息

3.3、代码

在这里插入图片描述


@Configuration
public class MessageListenerConfig {
    
    @Autowired
    private CachingConnectionFactory connectionFactory;
    @Autowired
    // 消息接收处理类
    private MyAckReceiver myAckReceiver;
    
    @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer() {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
        // 设置当前消费者数量
        container.setConcurrentConsumers(1);
        // 设置最大并发消费者数量
        container.setMaxConcurrentConsumers(1);
        // RabbitMQ默认是自动确认,这里改为手动确认消息
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        // 设置 监听的队列
        container.setQueueNames("ack_direct_queue");
        // 如果同时设置多个如下: 前提是队列都是必须已经创建存在的
        // container.setQueueNames("TestDirectQueue","TestDirectQueue2","TestDirectQueue3");
        
        // 另一种设置队列的方法,如果使用这种情况,那么要设置多个,就使用addQueues
        // container.setQueues(new Queue("TestDirectQueue",true));
        // container.addQueues(new Queue("TestDirectQueue2",true));
        // container.addQueues(new Queue("TestDirectQueue3",true));
        
        // 设置监听处理类
        container.setMessageListener(myAckReceiver);
        
        return container;
    }
    
}


/**
 *
 * 监听处理类
 * @author <a href="920786312@qq.com">周飞</a>
 * @class: MyAckReceiver
 * @date 2021/9/7  19:51
 * @Verson 1.0 -2021/9/7  19:51
 * @see
 */

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;

import com.rabbitmq.client.Channel;

@Component

public class MyAckReceiver implements ChannelAwareMessageListener {
    Logger logger = LoggerFactory.getLogger(getClass());
    
    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        // 获取消息
        String msg = message.toString();
        // 消费者队列
        String consumerQueue = message.getMessageProperties().getConsumerQueue();
        try {
            
            logger.info("消息队列:" + consumerQueue + ",消费的消息:" + msg);
            
            // 手动ACK
            // 第2个参数,手动确认是否可以被批处理
            // 当该参数为 true,小于 当前这条消息的delivery_tag 的所有消息,都确认
            // 当该参数为 false,只确认当前这条消息
            channel.basicAck(deliveryTag, true);
            
        } catch (Exception e) {
            logger.error("消息消费失败,消息队列:" + consumerQueue + ",消费的消息:" + msg);
            // 第2个参数:是否重新入列
            // true:消息重新丢回队列里,下次还会消费这消息
            // false:消息不丢回队列里,服务器丢失这条消息
            
            channel.basicReject(deliveryTag, false);
            e.printStackTrace();
        }
    }
    
}

3.4、测试

http://127.0.0.1:8080/ack/sendMsg4

在这里插入图片描述

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

RabbitMQ--集成Springboot--3.2--消息确认机制 的相关文章

  • 如何在 Node js 中保持分叉的子进程处于活动状态

    我想创建一个像带有node的foreverjs一样运行的rabbitmq cli 它可以生成 child process 并使其在后台运行 并且可以随时与 child process 进行通信 我面临的问题是 当主 cli 程序退出时 ch
  • 谁能告诉我 python 中的 pika 和 kombu 消息传递库有什么区别?

    我想在我的应用程序中使用消息传递库与rabbitmq交互 谁能解释一下 pika 和 kombu 库之间的区别吗 Kombu 和 pika 是两个不同的 Python 库 它们从根本上服务于相同的目的 向消息代理发布消息和使用消息代理发送消
  • 在 RabbitMQ 监听器中隐藏运行时异常

    在某些故意发生的情况下 我使用了一些异常来拒绝消息 但在控制台中显示了乍一看似乎不太正常的异常 如何在登录控制台 文件时隐藏该特定异常 我正在使用 spring boot 和默认记录器 public static class Undispa
  • 列出与rabbitmq java客户端API交换的绑定

    我似乎在文档中找不到任何信息 所以我想知道是否可以通过某种方式使用 java RabbitMQ API 获取与交换相关的所有绑定 我在查询 api bindings 时正在寻找类似 http api 结果的内容 api definition
  • 何时使用 RabbitMQ 而不是 Kafka? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我被要求评估 RabbitMQ 而不是 Kafka 但发现很难找到消息队列比 Kafka 更合适的情况 有谁知道消息队列在吞吐量 耐用性 延迟或
  • 为什么需要消息队列来与 Web 套接字聊天?

    我在互联网上看到了很多使用 Web 套接字和 RabbitMQ 进行聊天的示例 https github com videlalvaro rabbitmq chat https github com videlalvaro rabbitmq
  • Celery 任务状态取决于 CELERY_TASK_RESULT_EXPIRES

    据我所知 任务状态完全取决于 CELERY TASK RESULT EXPIRES 设置的值 如果我在任务完成执行后检查此间隔内的任务状态 则返回的状态为 AsyncResult task id state 是正确的 如果没有 状态将不会更
  • springrabbitmq:无法将id设置为属性?

    我有一个属性文件 其中包含队列 其值为queue name 如果我在其他请使用该属性 那么它可以工作 但如果我在 id 上使用它 那么它会失败
  • 如何使用 Celery、RabbitMQ 和 Django 确保每个用户的任务执行顺序?

    我正在运行 Django Celery 和 RabbitMQ 我想要实现的是确保与一个用户相关的任务按顺序执行 具体来说 一次执行一个 我不希望每个用户执行任务并发 每当为用户添加新任务时 它应该取决于最近添加的任务 如果此类型的任务已为此
  • 在 Windows 10 和 PHP 7.3 中安装 AMQP

    我想在 Windows 10 中使用 PHP 7 3 安装 AMQP 以便在 symfony 4 中使用 Windows 不使用任何 apache iis nginx 并直接由 symfony 运行 一切还好 直到 我决定在项目中使用rab
  • 如何重置rabbitmq管理用户

    使用rabbitmq 我们可以安装管理插件 然后我们通过浏览器访问http localhost 55672 使用访客 访客 问题是 我无法再登录 因为我更改了密码并为角色输入了空白 有没有办法重置rabbitmq管理的用户 您可以通过以下方
  • AMQPRuntimeException:读取数据时出错。收到 0 而不是预期的 7 字节

    它曾经有效 但现在不再有效了 我正在使用 php amqplib 和 RabbitMQ 当我尝试创建新的 AMQP 连接时 connection new AMQPConnection localhost 5672 username pass
  • RabbitMQ:如何创建和恢复备份

    我是 RabbitMQ 的新手 我需要一些帮助 如何备份和恢复到RabbitMQ 以及我需要保存哪些重要数据 谢谢 如果您安装了管理插件 您可以在Overview页 在底部你会看到导入 导出定义您可以使用它来下载代理的 JSON 表示形式
  • 将 sensu-client 连接到服务器时 AMQP 连接的 bad_header

    我已经安装了 sensu 和厨师社区食谱 但是 sensu客户端无法连接到服务器 导致rabbitmq连接错误 尝试连接时消息超时 这是详细的客户端日志 来自 sensu client log 的日志 timestamp 2014 07 0
  • 服务器在 pika.exceptions.StreamLostError: Stream 连接丢失后关闭

    我的队列中有一些图像 我将每个图像传递到我的 Flask 服务器 在其中完成图像处理 并在我的rabbitmq 服务器中收到响应 收到响应后 我收到此错误 pika exceptions StreamLostError 流连接丢失 104
  • rabbitmq 的 REST API

    有没有办法从 ajax 向 RabbitMQ 发送数据 我的应用程序由数千个 Web 客户端 用 js 编写 和 WCF REST 服务组成 现在我试图弄清楚如何为我的应用程序创建可扩展点 这个想法是有一个rabbitmq实例 它从放置在一
  • RabbitMQ 中 Pub/Sub 与工作队列的混合

    我正在评估使用 RabbitMQ 作为消息队列 消息总线 并一直在查看示例教程 https www rabbitmq com getstarted html在 RabbitMQ 页面上 我正在寻找教程中未涵盖的特定场景 并且我不确定是否以及
  • Django Celery 和多个数据库(Celery、Django 和 RabbitMQ)

    是否可以设置与 Django Celery 一起使用的不同数据库 我有一个配置了多个数据库的项目 并且不希望 Django Celery 使用默认数据库 如果我仍然可以使用 django celery 管理页面并读取存储在这个不同数据库中的
  • RabbitMQ HTTP API 请求 401 未经授权

    我正在尝试访问 RabbitMQ Rest 但收到 401 未经授权的错误 我想访问队列信息并获取消息编号 我发现这是一个解决方案 DefaultHttpClient httpClient new DefaultHttpClient Htt
  • 使用 Spring Boot 的多个 Rabbitmq 队列

    来自 Spring Boot 教程 https spring io guides gs messaging rabbitmq https spring io guides gs messaging rabbitmq 他们给出了创建 1 个队

随机推荐

  • 2023年最新Python所有方向的学习路线图,让Python初学者少走弯路

    在放学习路线之前 我先来讲一下这个学习路线图有什么作用 避免有些新手看得云里雾里的 学习路线图上面写的是某个方向建议学习和掌握的知识点汇总 举个例子 如果你要学习爬虫 那么你就去学Python爬虫学习路线图上面的知识点 这样学下来之后 你的
  • Android http安全之网络编程和证书

    最近面试上市大公司遇到的问题 网络安全底层与fiddler证书 我只想吐槽果然不缺人 上篇劫持的第二篇研究总结 如果通常网络我们使用常用的开源框架 然后设置通用的异步同步通信等格式 但是底层呢 这个我们常说只有面试的时候会用到 那如果想要黑
  • 开发参考资料

    一 开发环境 Ubuntu gt 20 04 x64 arm64 Visual Studio gt 2019 二 参考资料 OpenCV 官方文档 https opencv org releases Qt6 下载地址 https mirro
  • Vue中使用原生js创建元素样式不生效解决办法

    在Vue项目中也会遇到需要动态创建DOM的情况 但是采用指定className的方式给创建的DOM元素指定样式不起作用 在调试界面能看到类名被解析 但是样式未加载 三天里尝试了N种方法 终于填了这个大坑 有需要的可以参考一下 measure
  • 概念解析

    注1 本文系 概念解析 系列之一 致力于简洁清晰地解释 辨析复杂而专业的概念 本次辨析的概念是 CLIP和BLIP模型 揭秘视觉与语言交叉模型 CLIP和BLIP的介绍 LB 0 45836 BLIP CLIP CLIP Interroga
  • 让你的微信小程序具有在线支付功能

    最近需要在微信小程序中用到在线支付功能 于是看了一下官方的文档 发现要在小程序里实现微信支付还是很方便的 如果你以前开发过服务号下的微信支付 那么你会发现其实小程序里的微信支付和服务号里的开发过程如出一辙 下面我就具体说一下小程序里微信支付
  • JS限制Textarea文本域字符个数

  • overlay(VLAN,VxLAN)、underlay网络、大二层概述

    一 网络类型 1 第一种网络 网络分为物理网络和虚拟网络 物理网络就是对物理交换机 物理路由器 物理防火墙 物理负载均衡器 物理行为管理设备组成的网络 就叫做物理网络 虚拟网络 一般指虚拟交换机 虚拟路由器 虚拟防火墙 虚拟负载均衡器 虚拟
  • 企业子网划分详解

    一 IP协议 1 IP协议简介 IP协议是TCP IP协议族的基石 它为上层提供无状态 无连接 不可靠的服务 也是Socket网络编程的基础之一 IP协议特点 无状态 指IP通信双方不同步传输数据的状态信息 因此所有IP数据报的发送 传输
  • 如果XML文件太大(10M),打开方式选择

    用UltraEdit打开 其他的例如Editplus和notepad 根本打不开上百M的文件 一打开就死了
  • 小白入门必看——idea中JAVA配置

    java基础篇 首先需要大家下载idea 这里楼主为大家提供idea官网 供大家使用 idea官网 点这里 文章目录 java基础篇 前言 一 为什么要安装jdk 二 配置步骤 1 创建时配置 2 创建好后导入JDK 总结 前言 在idea
  • Ubantu使用kubeadm部署kubernetes1.25.10+cri-docker

    基于Ubantu系统的k8s集群搭建 文章目录 前言 一 Kubernetes是什么 二 环境准备 依赖添加 三节点操作 三 修改初始化文件 配置初始化 Master节点 Node节点 四 安装Calio网络插件 Master节点 总结 前
  • vant 做表格_Vant Cell 单元格

    引入import Vue from vue import Cell CellGroup from vant Vue use Cell Vue use CellGroup 代码演示 基础用法 Cell可以单独使用 也可以与CellGroup搭
  • 服务器组装 华硕主板,专业组装服务器 华硕主板P9D-C/4L热销

    中关村在线西安行情 华硕P9D C 4L是一款新推出的高性能主板 小编了解到在商家 西北服务器配件批发中心 正在热销中 报价仅1980元 用兴趣的朋友不妨与商家联系 图为 华硕P9D C 4L 华硕P9D C 4L产品简介 出色的 I O扩
  • 实战:win10安装docker并用docker-compose构建运行容器

    文章目录 前言 Docker Desktop Hyper V 安装 Docker Desktop for Windows 下载docker desktop Docker安装目录软连接 运行Docker Desktop安装文件 Docker
  • SpringBoot中静态变量注入方案,一网打尽

    前言 Hi 大家好 我是麦洛 昨天同事来找我 说自己想使用 Value注解来注入值 但是发现注入不进去 想让我帮忙看看 研究了一番 最后发现是 Value注解无法注入静态变量 下面我们一起来回顾一下本次的bug 普通变量 首先我们来看看 如
  • 微信小程序获取位置权限用户拒绝授权后重新引导用户授权

    微信小程序获取位置权限用户拒绝授权后重新引导用户授权 解决问题 微信小程序获取位置权限 用户点击允许后直接地图选点 或者用户拒绝授权后引导用户到设置页面重新授权 需要代码可直接滑至页面底部 调用方法 1 利用uni getSetting 获
  • 支持m1的视频无损放大软件:Topaz Video Enhance AI Mac版

    Topaz Video Enhance AI for Mac是一款专业的AI视频无损放大软件 topaz video enhance ai mac版使用时间信息有效提高视频质量和细节 从而达到最好的视频放大 去隔行 降噪和还原效果 另外to
  • 微信退款申请成功异步通知使用AES解密问题

    在微信退款申请成功后异步通知会返回一段加密串 在req info字段里 按照微信文档的做法是 1 对返回的加密串req info做base64解码 得到另一个加密串 byte b Base64Util decode map get req
  • RabbitMQ--集成Springboot--3.2--消息确认机制

    RabbitMQ 集成Springboot 3 2 消息确认机制 代码位置 https gitee com DanShenGuiZu learnDemo tree master rabbitMq learn rabbitMq 01 1 介绍