RabbitMQ(2)

news2024/11/24 23:11:29

一、MQ的问题

基于上篇存在的问题

1. 问题说明

MQ在分布式项目中非常重要的,

它可以实现异步、削峰、解耦,但是在项目中引入MQ也会带来一系列的问题。

今天我们要解决以下几个常见的问题:

  • 消息可靠性问题:如何确保消息被成功送达消费者,并且被消费者成功消费掉

  • 延迟消息问题:如果一个消息,需要延迟15分钟再消费,像12306超时取消订单,如何实现消息的延迟投递

  • 消息堆积问题:如果消息无法被及时消费而堆积,如何解决百万级消息堆积的问题

  • MQ的高可用问题:如何避免MQ因为单点故障而不可用的问题

2. 准备代码环境

注意:为了后续的演示效果,暂不声明交换机、队列、绑定关系

创建project

  1. 删除project里的src文件夹

  2. 添加依赖坐标

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.9.RELEASE</version>
    <relativePath/>
</parent>

<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
</properties>

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <!--AMQP依赖,包含RabbitMQ-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
    <!--单元测试-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>
</dependencies>


创建生产者模块

依赖

不需要添加,直接继承父工程的依赖

配置

修改application.yaml,添加配置:

spring:
  rabbitmq:
    host: 192.168.200.137
    port: 5672
    virtual-host: /
    username: itcast
    password: 123321

引导类

package com.mqrebbit;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ProducerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProducerApplication.class,args);
    }
}

发消息测试类

package com.mqrebbit;

import org.junit.jupiter.api.Test;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class Demo01SimpleTest {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void test(){
        rabbitTemplate.convertAndSend("demo.exchange","demo","hello");
    }
}

创建消费者模块

依赖

不需要添加,直接继承父工程的依赖

配置

修改application.yaml,添加配置:

spring:
  rabbitmq:
    host: 192.168.200.137
    port: 5672
    virtual-host: /
    username: itcast
    password: 123321
    listener:
      simple:
        prefetch: 1

引导类

package com.mqrebbit;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class,args);
    }
}

创建Listener

package com.mqrebbit.listener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class DemoListener {
    @RabbitListener(queues = "demo.queue")
    public void handleDemoQueueMsg(String msg){
        log.info("从{}队列接收到消息:{}", "demo.queue", msg);
        System.out.println("模拟:处理消息中……");
        log.info("消息处理完毕");
    }
}

二、消息可靠性

1. 介绍

当我们的生产者发送一条消息后,这条消息最终会到达消费者

那么在这整个过程中任何一个环境出错,都可能会导致消息的丢失,而导致不够可靠

可能出问题的环节有:

  • 生产者发送消息到Broker时 丢失:

    消息未送达Exchange

    消息到达了Exchange,但未到达Queue

  • Broker收到消息后丢失:

    MQ宕机,导致未持久化保存消息

  • 消费者从Broker接收消息丢失:

    消费者接收消息后,尚未消费就宕机

针对这些问题,RabbitMQ给出了对应的解决方案

  • 生产者发送消息丢失:使用生产者确认机制

  • Broker接收消息丢失:MQ消息持久化

  • 消费者接收消息丢失:消费者确认机制与失败重试机制  

2. 生产者确认机制

介绍

在了解生产者确认机制之前,

我们需要先明确一件事:生产者发送的消息,怎么样才算是发送成功了?

消息发送成功,有两个标准

  • 消息被成功送达Exchange

  • 消息被成功送达匹配的Queue

以上两个过程任何一步失败,都认为消息发送失败了。

生产者确认机制,可以确保生产者明确知道消息是否成功发出,如果未成功的话,是哪一步出现问题。然后开发人员就可以根据投递结果做进一步处理。

Confirm Callback机制:确定回收

说明

使用发送者的ConfirmCallback机制,

用于让生产者确认 消息是否送达交换机

如果消息成功送达交换机,MQ会给生产者返回一个ack(确认)。

当生产者得到ack之后,就可以确定消息成功送达交换机了

使用步骤,在生产者一方做如下操作:

  1. 修改配置文件,指定 confirm确认的处理方式,使用异步方式

  2. 发送消息时,配置CorrelationData,用于处理确认结果     

示例

1. 修改配置文件

修改生产者一方的配置文件application.yaml,增加如下配置

  • 如果配置为simple,表示使用同步方式处理确认的结果

  • 如果配置为correlated,表示使用异步方式处理确认的结果,但是发送消息时需要我们准备一个CorrelationData对象,用于接收确认结果

spring:
  rabbitmq:
    #生产者确认机制类型。simple同步方式确认;correlated异步方式确认,将使用CorrelationData接收确认结果
    publisher-confirm-type: correlated

2.发送消息

package com.mqrebbit;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@Slf4j
@SpringBootTest
public class Demo01SimpleTest {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Test
    public void test(){
        //创建一个CorrelationData Correlation:关联
        CorrelationData data = new CorrelationData();
        //设置消息的id
        data.setId("msg-001");
        //准备好 回调函数:Callback,用于接收 将来:Future 的确认结果
        data.getFuture().addCallback(
                //Success:成功
                /**
                 * 当消息发送没有出现异常时,这个方法会被调用
                 */
                result -> {
                    if (result.isAck()){
                        log.info("发送消息完成,且已经到达交换机。消息id={}",data.getId());
                    }else {
                        log.info("发送消息完成,但是没有到达交换机。消息id={},原因={}",data.getId(),result.getReason());

                    }                },
                //Failure:失败
                /**
                 * 当消息发送出现异常时,这个方法会被调用
                 */
                ex -> {
                    log.warn("发送消息出现异常,消息id={}",data.getId(),ex);
                }
        );
        rabbitTemplate.convertAndSend("demo.exchange", "demo", "hello",data);
    }
}

3.测试结果-未送达交换机的结果

首先,我们先要保证 demo.exchange交换机不存在,再运行单元测试方法,发送消息。可看到如下结果

4.测试结果-成功送达交换机

然后,我们再创建配置类,声明一个名称为demo.exchange的交换机

package com.mqrebbit.config;

import org.springframework.amqp.core.ExchangeBuilder;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitBindingConfig {
    //创建一个交换机
    @Bean
    public TopicExchange demoExchange(){
        return ExchangeBuilder.topicExchange("demo.exchange").build();
    }
}

然后重新发送消息,可看到如下结果:


Return Callback机制

说明

使用生产者的Confirm Callback机制,可以确保消息成功送达交换机

但是消息是否被送达队列呢?我们同样需要进行确认。

为了解决这个问题,RabbitMQ提供了Return Callback机制:

  • 如果消息被交换机成功路由到队列,一切正常

  • 如果消息路由到队列时失败了,Return回调会把消息回退给生产者。生产者可以自行决定后续要如何处理

使用步骤,在生产者一方操作:

  1. 修改配置文件,开启return callback机制,并设置强制return back 

  2. 创建配置类,预先设置Return回调函数

示例

1. 修改配置文件

修改生产者的配置文件application.yaml,开启return回调机制

spring:
  rabbitmq:
    publisher-returns: true #开启生产者return回调机制
    template:
      mandatory: true #开启强制回调。如果为true,消息路由失败时会调用ReturnCallback回退消息;如果为false,消息路由失败时会丢弃消息

设置Return回调

当消息未被路由到Queue时,Return回调会执行

注意:

  • 只要给RabbitTemplate对象设置一次回调函数即可,并不需要每次发送消息都设置Return回调。所以我们在配置类里给RabbitTemplate设置一次即可

  • 给单例的RabbitTemplate对象设置Return回调的方式有多种,使用哪种都行,只要能够设置成功即可

创建一个配置类,在配置类里设置Return回调函数:

package com.mqrebbit.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;

/*
 * ApplicationContext是: spring容器,所有bean对象都在这里面
 * ApplicationContextAware接口:当ApplicationContext初始化完成之后,
 * 接口的setApplicationContext方法将会被自动调用
 */
@Slf4j
@Configuration
public class RabbitConfig implements ApplicationContextAware {

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        RabbitTemplate rabbitTemplate = applicationContext.getBean(RabbitTemplate.class);
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
            //当交换机把消息路由到队列出现问题时,这个方法会自动执行
            log.warn("把消息路由到队列失败,replyCode{},replyText{},RoutingKey={},msg={}",
                    replyCode,replyText,exchange,routingKey, message);
        });
    }
}

测试结果-未路由到队列

首先,我们要先保证交换机没有绑定队列demo.queue,再运行单元测试方法,发送消息,可看到如下结果:

测试结果-成功路由到队列

 

然后,我们再找到RabbitBindingConfig配置类

增加一个队列demo.queue并绑定给交换机demo.exchange,最终代码如下:

@Configuration
public class RabbitBindingConfig {
    //创建一个交换机
    @Bean
    public TopicExchange demoExchange(){
        return ExchangeBuilder.topicExchange("demo.exchange").build();
    }
    @Bean
    public Queue demoQueue(){
        return QueueBuilder.durable("demo.queue").build();
    }
    @Bean
    public Binding demoBinding(Queue demoQueue,TopicExchange demoExchange){
        return BindingBuilder.bind(demoQueue).to(demoExchange).with("demo");
    }
}

然后再发送消息,不报错,就说明路由成功了。可以去RabbitMQ控制台上查看消息

 

 

3. MQ消息持久化

 介绍

通过生产者确认机制,我们可以把消息投递到队列中。但是如果这时候MQ宕机了,队列里的消息同样有可能会丢失。这是因为:

  • 交换机可能是非持久化的。MQ一重启,交换机就消失了

  • 队列可能是非持久化的。MQ一重启,队列就消失了

  • 消息可能是非持久化的(在RabbitMQ内存中)。MQ一重启,消息就丢失了

所以我们必须要保证:交换机、队列、消息都是持久化的。

但实际上,我们创建交换机、队列、消息的方式都是持久化创建的,所以以下内容我们仅仅了解即可

 交换机持久化

 队列持久化

 消息持久化



​4. 消费者确认机制

介绍

RabbitMQ采用的是阅后即焚模式,即只要消息被消费成功获取,MQ就会立刻删除掉这条消息。所以,我们必须保证,消息确实成功的被消费掉了。为此,RabbitMQ也提供了ack确认机制:

  • RabbitMQ将消息投递给消费者

    • 消费者成功处理消息

    • 消费者向RabbitMQ返回ack确认

  • RabbitMQ收到ack确认,删除消息

从上述过程中我们可以得到,消费者返回ack的时机是非常关键的:如果消费者仅仅是得到消息还未处理,就给RabbitMQ返回ack,然后消费者宕机了,就会导致消息丢失。

SpringAMQP允许消费者使用以下三种ack模式:

  • manual:手动ack。由开发人员在处理完业务后,手动调用API,向RabbitMQ返回ack确认

  • auto:自动ack【默认】。当消费者方法正常执行完毕后,由Spring自动给RabbitMQ返回ack确认;如果出现异常,就给RabbitMQ返回nack(未消费成功)

  • none:关闭ack。MQ假定所有消息都会被成功消费,因为RabbitMQ投递消息后会立即删除

我们一般使用默认的auto模式


none模式
auto模式


5. 消费者失败重试

介绍

当消费者出现异常后,消息会不断requeue(重入队)到队列,再重新发送给消费者,然后再次异常,再次requeue,无限循环,导致mq的消息处理飙升,带来不必要的压力:

我们可以利用Spring本身的retry机制,在消费者出现异常后,在消费者内部进行本地重试;而不是让消息重新入队列,然后让RabbitMQ重新投递。  

消费者本地重试

只要修改消费者一方的配置文件,设置消费者本地重试,并配置重试参数

修改消费者一方的配置文件application.yaml,增加如下配置:


失败后的恢复策略

在刚刚的本地重试中,在达到最大次数后,消息会被丢弃,这是Spring内部机制决定的。

但是,其实在重试多次消费仍然失败后,SpringAMQP提供了MessageRecoverer接口,定义了不同的恢复策略可以用来进一步处理消息:

  • RejectAndDontRequeueRecoverer:重试次数耗尽后,直接reject,丢弃消息。是默认的处理策略

  • ImmediateRequeueMessageRecoverer:重试次数耗尽后,立即重新入队requeue

  • RepublishMessageRecoverer:重试次数耗尽后,将失败消息投递到指定的交换机


6. 小结

三、死信交换机

1. 介绍

什么是死信

当一个队列中的消息满足下列情况之一时,可以成为死信(dead letter):

  • 消费者使用basic.reject或 basic.nack声明消费失败,并且消息的requeue参数设置为false

  • 消息是一个过期消息,超时无人消费

  • 要投递的队列消息满了,无法投递

死信交换机

如果这个包含死信的队列配置了dead-letter-exchange属性,指定了一个交换机,那么队列中的死信就会投递到这个交换机中,而这个交换机称为死信交换机(Dead Letter Exchange,检查DLX)。

如图,一个消息被消费者拒绝了,变成了死信;因为demo.queue绑定了死信交换机 dl.direct,因此死信会投递给这个交换机;如果这个死信交换机也绑定了一个队列,则消息最终会进入这个存放死信的队列:

注意:

  • 死信交换机,其实是普通交换机。只是用于处理死信,所以称为死信交换机

  • 死信队列,其实也是普通队列。只是用于处理死信,所以称为死信队列

2. 消费失败成为死信【拓展】

在失败重试策略中,默认的RejectAndDontRequeueRecoverer会在本地重试次数耗尽后,发送reject给RabbitMQ,消息变成死信,被丢弃。

我们可以给demo.queue添加一个死信交换机,给死信交换机绑定一个队列。这样消息变成死信后也不会丢弃,而是最终投递到死信交换机,路由到与死信交换机绑定的队列。

取消恢复策略

把消费者服务中RabbitMsgRecovererConfig配置类里的恢复策略注释掉,则SpringAMQP将会使用默认的RejectAndDontRequeueRecoverer策略,在本地重试次数耗尽后,发送reject给RabbitMQ。


配置死信交换机

修改生产者的配置类,在声明队列时绑定死信交换机


测试效果

  1. 先去RabbitMQ控制台页面(http://192.168.200.137:15672)中,demo.queue队列删除掉。因为之前声明的队列并没有绑定死信交换机,必须要删除掉,重新声明才行

  2. 运行生产者的单元测试方法,发送消息

  3. 启动消费者服务,开始从demo.queue中接收消息但出现异常;在耗尽重试次数后,因为恢复策略是默认的RejectAndDontRequeueRecoverer成为死信。消息被投递到死信交换机,然后路由到死信队列

  4. 在RabbitMQ控制台中查看死信队列dl.queue,可看到死信队列中有一条消息


3. 消息超时成为死信

说明

如果一条消息超时未被消费,也会成为死信。而超时有两种方式:

  • 消息所在的队列设置了超时

  • 消息本身设置了超时

我们将按照如下设计,演示超时成为死信的效果:


队列TTL示例

注意:为了方便演示死信队列的效果,我们将创建一个新的project,准备新的代码环境。参考第一章节中准备的代码环境。

生产者

声明队列和交换机

  • 声明死信交换机与死信队列,并绑定

  • 声明普通交换机与普通队列,并绑定。注意,声明普通队列时要:

    设置队列的TTL

    给队列设置死信交换机与死信的RoutingKey


消息TTL示例

生产者

声明队列和交换机

可以直接使用刚刚的“队列TTL示例”中的配置,与之相比,仅仅是声明队列时不再设置队列的TTL。代码如下:


4. 延迟队列

四、惰性队列

五、MQ集群

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

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

相关文章

编译flink1.6源码并打包成CDH6.3.2的parcel

说明&#xff1a;scala &#xff1a;2.12&#xff0c;maven:3.6.1, java:1.8&#xff0c;macOS 1、指定scala,maven的环境变量 sudo vi ~/.bash_profile export PATH$PATH:$M2_HOME/bin:/Users/admin/Documents/softwares/scala-2.12.17/bin2、克隆flink代码 git clone https…

smb配置,详细图文及配置

samba :网络文件共享服务 ​ Samba是一个能让Linux系统应用Microsoft网络通讯协议的软件&#xff0c;而SMB是Server Message Block的缩写&#xff0c;即为服务器消息块&#xff0c;SMB主要是作为Microsoft的网络通讯协议&#xff0c;后来Samba将SMB通信协议应用到了Linux系统上…

【Android入门到项目实战-- 11.4】—— ExoPlayer视频播放器框架的详细使用

目录 什么是ExoPlayer 一、基本使用 1、添加依赖项 2、布局 3、Activity 二、自定义播放暂停 1、首先如何隐藏默认的开始暂停和快进&#xff1f; 2、自定义 三、控制视频画面旋转和比例调整 四、全屏放大和缩小 1、双击视频放大缩小 2、按钮放大缩小 五、完整的实现…

JS 面试整理

1.JS运行机制&#xff08;EventLoop事件循环&#xff09; Js是单线程&#xff0c;每次只能执行一项任务&#xff0c;其他任务按照顺序排队等待&#xff0c;使用eventloop来解决线程阻塞的问题。在执行栈过程中&#xff0c;有同步代码和异步代码时&#xff0c;首先会执行完所有…

Linux学习笔记 --- 初识Linux

PC操作系统&#xff0c;也就是个人电脑所使用的操作系统 一. 操作系统概述 导学&#xff1a;了解操作系统的作用&#xff0c;了解常见的操作系统有哪些 1.1 硬件和软件 说白了&#xff0c;硬件就是你看得见&#xff0c;摸得到的。 1.2 操作系统 1.3 常见操作系统 PC操作系统…

分布式消息队列-RabbitMQ从入门到精通

文章目录 分布式消息队列认知提升分布式消息队列&#xff08;MQ&#xff09;应用场景分布式消息队列&#xff08;MQ&#xff09;应用思考点MQ本身的一些思考点业界主流的分布式消息队列&#xff08;MQ&#xff09;MQ的技术选型关注点初识 JMS 与其专业术语 RabbitMQ四种集群架构…

程序员:面试造火箭,入职拧螺丝?太难了···

刚开始工作的时候&#xff0c;我也想不通这个问题&#xff0c;甚至很鄙视这种现象。后面当了面试官&#xff0c;做到了公司中层管理&#xff0c;也会站在公司以及行业角度去重新思考这个问题。 为什么这种现象会越来越普遍呢&#xff1f;尤其在 IT 行业愈加明显。 面试看的是…

抖音SEO源码开发:技术分享与实践

抖音SEO源码开发一直是数字营销领域的重要技术之一。它可以帮助企业在搜索引擎结果页面上获得更好的排名&#xff0c;从而吸引更多的用户。为了帮助更多的企业提升在抖音平台上的曝光率&#xff0c;开发者们分享了自己的技术并进行了实践。 在抖音SEO源码开发的过程中&#xf…

Pytho制作自动更换壁纸程序,快来给你的电脑开启无限换肤吧

目录 前言环境使用:需导入的模块一. 获取壁纸二. 设置自动更换尾语 &#x1f49d; 前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 环境使用: Python 3.8 解释器 Pycharm 编辑器 需导入的模块 import re # 正则表达式模块 import requests >>> pip install r…

oracle数值型函数大全(不包含三角函数)

--数值型函数大全 --1.abs(x) 返回x的绝对值 select abs(-2.1) from dual; --2.mod(x,y) 取余 select mod(5,2) from dual; --3.sign(x) 返回正负值 --x>o,则返回1 select sign(10) from dual; --x0,则返回0 select sign(0) from dual; --x<0,则返回-1 sele…

typora怎么把本地固定目录下的图片拷贝到相对目录,怎么分享图片(图片分享)

如图&#xff0c;我的这张图片是存在固定目录下的&#xff0c;我把这个.md文件分享给别人&#xff0c;别人就看不到图片了 我们只需要点击图片按钮&#xff0c;并点击“将图片复制到到…”或者“将图片移动到…” 然后图片就被拷贝到这里来了&#xff1a; 把这个目录连同我们的…

MATLAB | 实用(离谱)小技巧大合集:仅隐藏轴线 | 复杂公式刻度标签 | 渐变背景 | 半透明图例... ...

看到阿昆的科研日常写了一篇如何将轴线隐藏而不隐藏刻度的推送&#xff0c;使用了XRuler中的Axle对象来实现&#xff0c;但我试了一下R2023A版本中不太能直接用&#xff0c;解决了一下&#xff0c;同时讲一下这些有趣的隐藏对象及其其他的用法。 1 隐藏轴框线 假设我们编写了如…

Win10“我的电脑”图标不见了,恢复方法

Win10“我的电脑”图标不见了&#xff0c;恢复方法 当使用电脑时&#xff0c;若‘我的电脑’图标在桌面不显示&#xff0c;使得对电脑各个盘区文件的查找和打开带来不便&#xff0c;本文将以Win10为例子&#xff0c;介绍桌面图标不显示的处理恢复方法。 具体的恢复方法如下 1…

pdf怎么转jpg?转换途径分享

PDF 转 JPG 是一种常用的数字图像处理技术&#xff0c;它可以帮助我们将 PDF 文件转换为 JPG 图像&#xff0c;从而更好地存储或传输文件。在实际应用中&#xff0c;PDF 转 JPG 有许多优点&#xff0c;例如可以节省存储空间、提高文件传输速度&#xff0c;以及增强文件的可读性…

Netty实战(六)

ChannelHandler和ChannelPipeline 一、ChannelHandler1.1 Channel 的生命周期1.2 ChannelHandler 的生命周期1.3 ChannelInboundHandler 接口1.4 ChannelOutboundHandler 接口1.5 ChannelHandler 适配器1.6 资源管理 二、ChannelPipeline 接口2.1 修改 ChannelPipeline2.2 触发…

【机器学习】采样方法

文章目录 采样方法11.1 简介11.2 常见采样方法11.2.1 均匀分布采样11.2.2 逆变换采样11.2.3 拒绝采样11.2.4 重要采样11.2.5 Metropolis方法11.2.6 Metropolis-Hasting 算法11.2.7 吉布斯采样 采样方法 11.1 简介 什么是采样 从一个分布中生成一批服从该分布的样本&#xff0c…

Linux知识点 -- 进程概念(一)

Linux知识点 – 进程概念&#xff08;一&#xff09; 文章目录 Linux知识点 -- 进程概念&#xff08;一&#xff09;一、冯诺伊曼体系结构二、操作系统&#xff08;OS&#xff09;1.概念2.设计OS的目的3.如何理解管理4.系统调用和库函数的概念 三、进程概念1.理解进程2.描述进程…

Windows源码安装INDEMIND双目惯性模组

最近电赛准备在Win10的平台上做一个增强现实眼镜&#xff0c;所以IMU相机也是必不可少的传感器&#xff0c;记录Windows源码安装INDEMIND双目惯性模组。 文章目录 实验环境一、配置准备1、SDK下载及准备安装2、安装CMake并添加环境变量3、设置".sln"文件的默认打开方…

区块链服务网络发展联盟最新成员单位名单公布

原标题&#xff1a;《BSN发展联盟第六批入盟成员单位及全体联盟成员名单公示》 为了更好地推动BSN的发展&#xff0c;国家信息中心、中国移动通信集团有限公司、中国银联股份有限公司、北京红枣科技有限公司共同发起成立了区块链服务网络发展联盟&#xff08;Blockchain-based…

六、AOP(2)

一、AOP操作&#xff08;AspectJ注解&#xff09;重点 1.创建类&#xff0c;在类里面定义方法com.zhilei.spring5.aopanno public class User {public void add(){System.out.println("add...");} }2.创建增强类&#xff0c;编写增强逻辑 在增强类里面&#xff0c…