RabbitMQ 死信队列实现

news2024/12/22 15:53:51
// consumer处理成功后,通知broker删除队列中的消息,如果设置multiple=true,表示支持批量确认机制以减少网络流量
channel.basicAck(deliveryTag, multiple);

// 拒绝deliveryTag对应的消息,第二个参数是否requeue,true则重新入队列,否则丢弃或者进入死信队列,该方法reject后,该消费者还是会消费到该条被reject的消息
channel.basicReject(deliveryTag, requeue);

// 不确认 deliveryTag 对应的消息,第二个参数是否应用于多消息,第三个参数是否requeue,与basic.reject区别就是同时支持多个消息,可以nack该消费者先前接收未ack的所有消息。nack后的消息也会被自己消费到。
channel.basicNack(deliveryTag, multiple, requeue);

// 是否恢复消息到队列,参数是是否requeue,true则重新入队列,并且尽可能的将之前recover的消息投递给其他消费者消费,而不是自己再次消费。false则消息会重新被投递给自己。
channel.basicRecover(false);

搭建项目

spring:
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
    listener:
      type: simple
      simple:
        default-requeue-rejected: false
        acknowledge-mode: manual

@Configuration
public class RabbitMQConfig {


    // 正常业务
    public static final String NORMAL_EXCHANGE_A = "normal-exchange-a";

    public static final String NORMAL_QUEUE_A = "normal-queue-a";

    public static final String NORMAL_ROUTING_KEY_A = "normal-routing-key-a";


    // 死信队列
    public static final String DEAD_EXCHANGE_A = "dead-exchange-a";

    public static final String DEAD_QUEUE_A = "dead-queue-a";

    public static final String DEAD_ROUTING_KEY_A = "dead-routing-key-a";


    // 声明交换机
    @Bean("businessExchange")
    public TopicExchange normalExchangeA() {
        return new TopicExchange(NORMAL_EXCHANGE_A);
    }

    @Bean("deadExchange")
    public DirectExchange deadExchange() {
        return new DirectExchange(DEAD_EXCHANGE_A);
    }


    // 声明队列

    @Bean("businessQueueA")
    public Queue businessQueueA() {
        HashMap<String, Object> args = new HashMap<>(3);
        args.put("x-dead-letter-exchange", DEAD_EXCHANGE_A);
        args.put("x-dead-letter-routing-key", DEAD_ROUTING_KEY_A);
        return QueueBuilder.durable(NORMAL_QUEUE_A).withArguments(args).build();
    }


    @Bean("deadQueueA")
    public Queue deadQueue() {
        return QueueBuilder.durable(DEAD_QUEUE_A).build();
    }


    // 声明绑定关系
    @Bean
    public Binding bindingA(@Qualifier("businessQueueA") Queue queue, @Qualifier("businessExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(NORMAL_ROUTING_KEY_A);
    }

    @Bean
    public Binding bindingDead(@Qualifier("deadQueueA") Queue queue, @Qualifier("deadExchange") DirectExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(DEAD_ROUTING_KEY_A);
    }
}
@Component
public class SmsListener {

    @RabbitListener(queues = RabbitMQConfig.NORMAL_QUEUE_A)
    public void smsListener(Message message, Channel channel) throws IOException {
        String body = new String(message.getBody());

        System.out.println("收到消息:" + body);
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        if (body.contains("dead")) {
            channel.basicNack(deliveryTag, false, false);
        }
        channel.basicAck(deliveryTag, false);
    }
}
@Component
public class DeadListener {

    @RabbitListener(queues = RabbitMQConfig.DEAD_QUEUE_A)
    public void deadListener(Message message, Channel channel) throws IOException {
        String body = new String(message.getBody());
        System.out.println("dead listener: " + body);
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }
}
@RestController
public class HelloController {

    @Resource
    private RabbitTemplate rabbitTemplate;

    @GetMapping("/hello")
    public Boolean hello(String msg) {
        rabbitTemplate.convertAndSend(RabbitMQConfig.NORMAL_EXCHANGE_A, RabbitMQConfig.NORMAL_ROUTING_KEY_A, msg);
        return true;
    }

}

使用注解

@Configuration
public class RabbitMQConfig {


    // 正常业务
    public static final String NORMAL_EXCHANGE_A = "normal-exchange-a";

    public static final String NORMAL_QUEUE_A = "normal-queue-a";

    public static final String NORMAL_ROUTING_KEY_A = "normal-routing-key-a";


    // 死信队列
    public static final String DEAD_EXCHANGE_A = "dead-exchange-a";

    public static final String DEAD_QUEUE_A = "dead-queue-a";

    public static final String DEAD_ROUTING_KEY_A = "dead-routing-key-a";


    // 声明交换机
    @Bean("businessExchange")
    public TopicExchange normalExchangeA() {
        return new TopicExchange(NORMAL_EXCHANGE_A);
    }


    // 声明队列
    @Bean()
    public Queue businessQueueA() {
        HashMap<String, Object> args = new HashMap<>(2);
        args.put("x-dead-letter-exchange", DEAD_EXCHANGE_A);
        args.put("x-dead-letter-routing-key", DEAD_ROUTING_KEY_A);
        return QueueBuilder.durable(NORMAL_QUEUE_A).withArguments(args).build();
    }


    // 声明绑定关系
    @Bean
    public Binding bindingA(@Qualifier("businessQueueA") Queue queue, @Qualifier("businessExchange") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(NORMAL_ROUTING_KEY_A);
    }


}

死信队列使用注解实现

@Component
public class DeadListener {

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = RabbitMQConfig.DEAD_QUEUE_A),
            exchange = @Exchange(value = RabbitMQConfig.DEAD_EXCHANGE_A, type = ExchangeTypes.DIRECT),
            key = RabbitMQConfig.DEAD_ROUTING_KEY_A
    ))
    public void deadListener(Message message, Channel channel) throws IOException {
        String body = new String(message.getBody());
        System.out.println("死信队列消费消息: " + body);
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }
}
@Component
public class SmsListener {

    @RabbitListener(queues = RabbitMQConfig.NORMAL_QUEUE_A)
//    @RabbitListener(bindings = @QueueBinding(
//            value = @Queue(value = RabbitMQConfig.NORMAL_QUEUE_A),
//            exchange = @Exchange(value = RabbitMQConfig.NORMAL_EXCHANGE_A, type = ExchangeTypes.TOPIC),
//            key = RabbitMQConfig.NORMAL_ROUTING_KEY_A
//    ))
    public void smsListener(Message message, Channel channel) throws IOException {
        String body = new String(message.getBody());

        System.out.println("正常消费消息:" + body);
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        if (body.contains("dead")) {
            channel.basicNack(deliveryTag, false, false);
//            return;
        }
        channel.basicAck(deliveryTag, false);
    }
}

报错:

Shutdown Signal: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - unknown delivery tag 1, class-id=60, method-id=80)
    
// 由于程序编写不严谨,在 basicNack 执行后没有退出方法,导致最后还执行了 basicAck,出现了上述错误
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = RabbitMQConfig.NORMAL_QUEUE_A),
            exchange = @Exchange(value = RabbitMQConfig.NORMAL_EXCHANGE_A, type = ExchangeTypes.TOPIC),
            key = RabbitMQConfig.NORMAL_ROUTING_KEY_A
    ))
    public void smsListener(Message message, Channel channel) throws IOException {
        String body = new String(message.getBody());

        System.out.println("正常消费消息:" + body);
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        if (body.contains("dead")) {
            channel.basicNack(deliveryTag, false, false);
            return;
        }
        channel.basicAck(deliveryTag, false);
    }
// 问题二: 控制台报错,但是也能正常消费mq消息,这里与第一种唯一的区别是在于 @RabbitListener, 我的推测是 自定义 bean 和注解生成的 bean 重复导致,看能不能使用注解绑定死信队列
2023-04-23 22:03:25.630 ERROR 8580 --- [ 127.0.0.1:5672] o.s.a.r.c.CachingConnectionFactory       : Shutdown Signal: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'x-dead-letter-exchange' for queue 'normal-queue-a' in vhost '/': received none but current is the value 'dead-exchange-a' of type 'longstr', class-id=50, method-id=10)
Broker not available; cannot force queue declarations during start: java.io.IOException
@Target({})
@Retention(RetentionPolicy.RUNTIME)
public @interface Exchange {
    String TRUE = "true";
    String FALSE = "false";

    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    String type() default "direct";

    String durable() default "true";

    String autoDelete() default "false";

    String internal() default "false";

    String ignoreDeclarationExceptions() default "false";

    String delayed() default "false";

    Argument[] arguments() default {};

    String declare() default "true";

    String[] admins() default {};
}
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = RabbitMQConfig.NORMAL_QUEUE_A),
            exchange = @Exchange(value = RabbitMQConfig.NORMAL_EXCHANGE_A, type = ExchangeTypes.TOPIC, arguments = {
                    @Argument(name = "x-dead-letter-exchange", value = RabbitMQConfig.DEAD_EXCHANGE_A),
                    @Argument(name = "x-dead-letter-routing-key", value = RabbitMQConfig.DEAD_ROUTING_KEY_A)
            }),
            key = RabbitMQConfig.NORMAL_ROUTING_KEY_A
    ))
    public void smsListener(Message message, Channel channel) throws IOException {
        String body = new String(message.getBody());

        System.out.println("正常消费消息:" + body);
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        if (body.contains("dead")) {
            channel.basicNack(deliveryTag, false, false);
            return;
        }
        channel.basicAck(deliveryTag, false);
    }

可以使用注解的方式来绑定 死信队列,但是还是会报上面的错误,继续修改 参数试试

java - How to set x-dead-letter-exchange in Rabbit? - Stack Overflow

但是使用注解绑定的话好像又不生效了,问题原因,tmd将死信参数绑到交换机上了,c

修改代码

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = RabbitMQConfig.NORMAL_QUEUE_A, durable = "false", arguments = {
                    @Argument(name = "x-dead-letter-exchange", value = RabbitMQConfig.DEAD_EXCHANGE_A),
                    @Argument(name = "x-dead-letter-routing-key", value = RabbitMQConfig.DEAD_ROUTING_KEY_A)
            }),
            exchange = @Exchange(value = RabbitMQConfig.NORMAL_EXCHANGE_A, durable = "false", type = ExchangeTypes.TOPIC),
            key = RabbitMQConfig.NORMAL_ROUTING_KEY_A
    ))
    public void smsListener(Message message, Channel channel) throws IOException {
        String body = new String(message.getBody());

        System.out.println("正常消费消息:" + body);
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        if (body.contains("dead")) {
            channel.basicNack(deliveryTag, false, false);
            return;
        }
        channel.basicAck(deliveryTag, false);
    }

 至于问题二是由于队列和交换机默认持久化,这样就导第二次启动项目时重复

Springboot纯注解版的RabbitMq 死信队列_注解声明私信队列_lopo呀的博客-CSDN博客

全注解版

spring:
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
    listener:
      type: simple
      simple:
        default-requeue-rejected: false
        acknowledge-mode: manual
// 正常业务
public static final String NORMAL_EXCHANGE_A = "normal-exchange-a";

public static final String NORMAL_QUEUE_A = "normal-queue-a";

public static final String NORMAL_ROUTING_KEY_A = "normal-routing-key-a";


// 死信队列
public static final String DEAD_EXCHANGE_A = "dead-exchange-a";

public static final String DEAD_QUEUE_A = "dead-queue-a";

public static final String DEAD_ROUTING_KEY_A = "dead-routing-key-a";
@Component
public class SmsListener {
    
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = RabbitMQConfig.NORMAL_QUEUE_A, durable = "false", arguments = {
                    @Argument(name = "x-dead-letter-exchange", value = RabbitMQConfig.DEAD_EXCHANGE_A),
                    @Argument(name = "x-dead-letter-routing-key", value = RabbitMQConfig.DEAD_ROUTING_KEY_A)
            }),
            exchange = @Exchange(value = RabbitMQConfig.NORMAL_EXCHANGE_A, durable = "false", type = ExchangeTypes.TOPIC),
            key = RabbitMQConfig.NORMAL_ROUTING_KEY_A
    ))
    public void smsListener(Message message, Channel channel) throws IOException {
        String body = new String(message.getBody());

        System.out.println("正常消费消息:" + body);
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        if (body.contains("dead")) {
            channel.basicNack(deliveryTag, false, false);
            return;
        }
        channel.basicAck(deliveryTag, false);
    }
}
@Component
public class DeadListener {

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = RabbitMQConfig.DEAD_QUEUE_A, durable = "false"),
            exchange = @Exchange(value = RabbitMQConfig.DEAD_EXCHANGE_A, durable = "false"),
            key = RabbitMQConfig.DEAD_ROUTING_KEY_A
    ))
    public void deadListener(Message message, Channel channel) throws IOException {
        String body = new String(message.getBody());
        System.out.println("死信队列消费消息: " + body);
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }
}
@GetMapping("/hello")
public Boolean hello(String msg) {
    System.out.println("发送消息:" + msg);
    rabbitTemplate.convertAndSend(RabbitMQConfig.NORMAL_EXCHANGE_A, RabbitMQConfig.NORMAL_ROUTING_KEY_A, msg);
    return true;
}
// conslog
发送消息:dead
正常消费消息:dead
死信队列消费消息: dead

明天在研究下回调啥的

springboot整合rabbitMQ confirm 确认模式 return 退回模式_weixin_44318244的博客-CSDN博客

回调

在使用 RabbitMQ 的时候,作为消息发送方希望杜绝任何消息丢失或者投递失败场景。 RabbitMQ 为我们提供了两种方式用来控制消息的投递可靠性模式。

  • confirm 确认模式

  • return 退回模式

rabbitmq 整个消息投递的路径为:producer—>rabbitmq broker—>exchange—>queue—>consumer

  • 消息从 producer 到 exchange 则会返回一个 confirmCallback 。

  • 消息从 exchange–>queue 投递失败则会返回一个 returnCallback

我们将利用这两个 callback 控制消息的可靠性投递

消息的可靠投递小结 ➢ 设置ConnectionFactory的publisher-confirms=“true” 开启 确认模式。 ➢ 使用rabbitTemplate.setConfirmCallback设置回调函数。当消息发送到exchange后回调confirm方法。在方法中判断ack,如果为true,则发送成功,如果为false,则发送失败,需要处理。

➢ 设置ConnectionFactory的publisher-returns=“true” 开启 退回模式。 ➢ 使用rabbitTemplate.setReturnCallback设置退回函数,当消息从exchange路由到 queue失败后,如果设置了rabbitTemplate.setMandatory(true)参数,则会将消息退回给producer。并执行回调函数returnedMessage。

确认模式

spring:
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
    listener:
      type: simple
      simple:
        default-requeue-rejected: false
        acknowledge-mode: manual
    publisher-confirm-type: correlated # 发布确认属性配置
    publisher-returns: true # 开启 退回模式
	public enum ConfirmType {

		/**
		 * Use {@code RabbitTemplate#waitForConfirms()} (or {@code waitForConfirmsOrDie()}
		 * within scoped operations.
		 SIMPLE值经测试有两种效果,其一效果和CORRELATED值一样会触发回调方法,其二在发布消息成功后使用rabbitTemplate调用waitForConfirms或		  			 waitForConfirmsOrDie方法等待broker节点返回发送结果,根据返回结果来判定下一步的逻辑,要注意的点是waitForConfirmsOrDie方法如果返回false则会			关闭channel,则接下来无法发送消息到broker;

		 */
		SIMPLE,

		/**
		 * Use with {@code CorrelationData} to correlate confirmations with sent  发布消息成功到交换器后会触发回调方法
		 * messsages.
		 */
		CORRELATED,

		/**
		 * Publisher confirms are disabled (default).
		 */
		NONE

	}
@Configuration
public class PublisherConfirmHandler implements RabbitTemplate.ConfirmCallback {

    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (ack){
            System.out.println("发送消息到交换机成功!MessageId: " + correlationData.getId());
        }else {
            System.out.println("发送消息到交换机失败!MessageId: " + correlationData.getId() + ", 退回原因:" + cause);
        }
    }
}
@Resource
private PublisherConfirmHandler publisherConfirmHandler;

rabbitTemplate.setConfirmCallback(publisherConfirmHandler);

回退模式  

@Configuration
public class ReturnsCallbackHandler implements RabbitTemplate.ReturnsCallback {
    @Override
    public void returnedMessage(ReturnedMessage returned) {
        System.out.println("return 执行了!" + returned);
    }
}

 

// 
rabbitTemplate.setMandatory(true);
rabbitTemplate.setReturnsCallback(returnsCallbackHandler);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/489357.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Inception模型实现孤立手语词的识别

实现孤立手语词的识别流程如下&#xff0c;在实际研究中&#xff0c;本章将着重研究第三阶段内容&#xff0c;也就是模型的设计与实现过程&#xff0c;目的是提高手语图像的识别准确率。 Inception模型实现 Inception模型是谷歌研究人员在2014年提出的一个深度卷…

网工Python:如何使用Netmiko的SCP函数进行文件传输?

在网络设备管理中&#xff0c;传输配置文件、镜像文件等是经常需要进行的操作。Netmiko是一个Python库&#xff0c;可用于与各种网络设备进行交互&#xff0c;提供了一些用于传输文件的函数&#xff0c;其中包括SCP&#xff08;Secure Copy Protocol&#xff09;函数。本文将介…

【软考备战·希赛网每日一练】2023年5月4日

文章目录 一、今日成绩二、错题总结第一题第二题第三题第四题三、知识查缺 题目及解析来源&#xff1a;2023年05月04日软件设计师每日一练 一、今日成绩 二、错题总结 第一题 解析&#xff1a; 修改Linux文件权限命令&#xff1a;chmod。 第二题 解析&#xff1a; 第三题 解析…

欧拉奔赴品牌2.0时代,女性汽车真实用户需求被定义?

每年的上海国际汽车工业展览会&#xff0c;不仅是各大汽车品牌的技术“秀场”&#xff0c;也是品牌的营销“修罗场”。今年上海车展出圈的营销事件特别多&#xff0c;热度甚至一再蔓延到汽车行业外&#xff0c;其中欧拉也贡献了不少流量。 据了解&#xff0c;在2023上海车展欧…

mount disk space from SAN

mount disk from FC-SAN 配置硬盘域、存储池、LUN、主机及LUN与与主机之间的映射。 fc-san多路径范例1 fc-san多路径2 mount disk from iSCSI [rootqionghai11g ~]# iscsiadm -m discovery -t sendtargets -p 192.16.10.188:3260 Starting iscsid: [ OK ] 192.16.10.188:32…

Yolov1 源码讲解 voc.py

先看结构 1.mean_rgb是voc2007专用的均值 voc2007分别是这样的 坐标格式&#xff08;X0&#xff0c;Y0&#xff0c;X1&#xff0c;Y1&#xff09;其中X0,Y0是左上角的坐标,X1,Y1是右下角的坐标。 coco,voc ,yolo数据集中的bbox的坐标格式_coco bbox格式_十二耳环的博客-CSDN…

Jmeter之BeanShell取出需要参数,传递给下个请求

一、事件背景&#xff1a; 上周同事用Jmeter录制脚本&#xff0c;录制成功回放后&#xff0c;并没有达到自己想要的结果。 他的真实需求是&#xff0c;想从数据库取出某个字段值&#xff0c;然后对数据库做操作。 也就是想实现做参数传递的效果&#xff0c;我心痒痒的&#…

ConcurrentHashMap底层源码解析

ConcurrentHashMap线程安全&#xff0c;底层数组链表红黑树。 思想&#xff0c;分而治之。 JDK7有Segment对象&#xff0c;分段锁 JDK8没有了这个对象 总结&#xff0c; 首先计算hash&#xff0c; 如果集合没有元素&#xff0c;开始initTable方法初始化&#xff0c;这里扩容讲…

有人说ChatGPT信息不新?

Hello ,我是小索奇&#xff0c;今天给大家分享一个插件&#xff0c;这个插件可以通过抓取网页获得最新内容&#xff0c;它可以有效的避免ChatGPT信息过时&#xff0c;获取不到最新的信息等等 演示-这里问它一些问题&#xff1a; 现在几点了呀 可以看到时间也是很准确的&#x…

Linux权限(+Linux基本指令(下))

目录 一.基本指令补充 1.date指令 2.find指令 3.tar指令 4.Linux下的常用热键 二.Linux权限 1.Shell 2.Linux权限的概念 一.基本指令补充 1.date指令 &#x1f606;date指令可以用于显示日期和时间戳&#x1f606;Linux的时间戳与Unix时间戳一致,指的是从1970年1月1日…

使用无标注的数据训练Bert

文章目录 1、准备用于训练的数据集2、处理数据集3、克隆代码4、运行代码5、将ckpt模型转为bin模型使其可在pytorch中运用 Bert官方仓库&#xff1a;https://github.com/google-research/bert 1、准备用于训练的数据集 此处准备的是BBC news的数据集&#xff0c;下载链接&…

Python | 人脸识别系统 — UI界面设计

本博客为人脸识别系统的UI界面设计代码解释 人脸识别系统博客汇总&#xff1a;人脸识别系统-博客索引 项目GitHub地址&#xff1a;【待】 注意&#xff1a;阅读本博客前请先参考以下博客 工具安装、环境配置&#xff1a;人脸识别系统-简介 阅读完本博客后可以继续阅读&#xff…

不用下载就能使用的4款轻量在线PS工具

PS是一种非常熟悉的设计工具&#xff0c;也是一种在设计领域占有重要地位的软件&#xff0c;如常见的产品设计、平面设计或摄影后期设计&#xff0c;几乎与PS的使用密不可分。PS本身也有很多功能&#xff0c;每个人的日常设计图纸、图纸修复等工作都可以用PS完成。 但PS有很多…

yolov8 OpenCV DNN 部署 推理报错

yolov8是yolov5作者发布的新作品 目录 1、下载源码 2、下载权重 3、配置环境 4、导出onnx格式 5、OpenCV DNN 推理 1、下载源码 git clone https://github.com/ultralytics/ultralytics.git 2、下载权重 git clone https://github.com/ultralytics/assets/releases/dow…

MySQL知识学习05(InnoDB存储引擎对MVCC的实现)

1、一致性非锁定读和锁定读 一致性非锁定读 对于 一致性非锁定读&#xff08;Consistent Nonlocking Reads&#xff09; &#xff0c;通常做法是加一个版本号或者时间戳字段&#xff0c;在更新数据的同时版本号 1 或者更新时间戳。查询时&#xff0c;将当前可见的版本号与对…

K8S资源-configmap创建六种方式

云原生实现配置分离重要实现方式 两者都是用来存储配置文件&#xff0c;configmap存储通用的配置文件&#xff0c;secret存储需要加密的配置文件。 将配置文件configmap挂在到pod上 创建configmap 1.基于配置文件目录创建configmap kubectl create cm cmdir --from-fileconf…

医学图像分割之U-Net

一、背景及问题 在过去两年中&#xff0c;在很多视觉识别任务重&#xff0c;深度卷积网络的表现优于当时最先进的方法。但这些深度卷积网络的发展受限于网络模型的大小以及训练数据集的规模。虽然这个限制有过突破&#xff0c;也是在更深的网络、更大的数据集中产生的更好的性能…

【redis】redis的缓存过期淘汰策略

【redis】redis的缓存过期淘汰策略 文章目录 【redis】redis的缓存过期淘汰策略前言一、面试题二、redis内存满了怎么办&#xff1f;1、redis默认内存是多少&#xff1f;在哪查看&#xff1f;如何修改?在conf配置文件中可以查看 修改&#xff0c;内存默认是0redis的默认内存有…

使用意图intent构建一个多活动的Android应用

安卓意图Intent是Android应用组件(Activity、Service、Broadcast Receiver)之间进行交互的一种重要方式。Intent允许启动一个活动、启动一个服务、传递广播等。Intent使应用能够响应系统及其他应用的动作。Intent使用的主要目的有: 1、 启动Activity:可以启动自己应用内的Activ…

DDPM--生成扩散模型

DDPM–生成扩散模型 Github: https://github.com/daiyizheng/Deep-Learning-Ai/blob/master/AIGC/Diffusion.ipynb DDPM 是当前扩散模型的起点。在本文中&#xff0c;作者建议使用马尔可夫链模型&#xff0c;逐步向图像添加噪声。 函数 q ( x t ∣ x t − 1 ) q(x_t | x_t-1…