RabbitMQ

  • RabbitMQ
    • 1.MQ简介
    • 2.使用场景
      • 2.1.流量削峰
        • 流量削峰的由来
      • 2.2 日志处理
      • 2.3 应用解耦
      • 2.4 异步处理
    • 3. RabbitMQ简介
    • 4. AMQP 协议
    • 5. Windows环境下单节点安装
      • 下载安装包
      • 安装erlang:
      • 安装rabbitmq
    • 6.RabbitMQ 管理界面使用
      • 添加用户
      • 添加Virtual Host
      • 授权:
    • 7.RabbitMQ 消息种类
      • 7.1 simple 简单队列
        • 7.1.1获取连接工具类 ConnectionUtil:
        • 7.1.2消息生产者:Send
        • 7.1.3 消费者:Recv
        • 7.1.4 简单队列的不足:
      • 7.2 work queues 工作队列,公平分发轮询分发
        • 7.2.1 **为什么会出现工作队列:**
        • 7.2.2 分发轮询
          • 7.2.2.1 消息生产者:Send
          • 7.2.2.2 消费者:Recv1:
          • 7.2.2.3 消费者:Recv2
          • 7.2.2.4现象:
        • 7.2.3 公平分发 fair dipatch
          • 7.2.3.1 生产者
          • 7.2.3.2 消费者1
          • 7.2.3.3 消费者2
          • 7.2.3.4 现象:
      • 7.3 publish/subscribe 发布订阅 订阅模式
        • 生产者
        • 消费者1:Recv1
        • 消费者2:Recv2
      • 7. 4.routing 路由选择通配符模式
        • 生产者
        • 消费者1:Recv1
        • 消费者2:Recv2
      • 7.5.Topics 主题
      • 7.6 RPC 手动和自动确认消息(消息确认机制 事务——confirm)
        • 事务机制:
          • 生产者
      • Confirm 模式
    • 消息应答与消息持久化
        • 消息应答
        • 消息持久化
    • Exchange (交换机 转发器)
      • 类型:
        • fanout(不处理路由键)
        • Direct(处理路由键)

RabbitMQ

1.MQ简介

MQ全称为Message Queue,消息队列(MQ)是一种应用程序对应用程序的通信方法。

在这里插入图片描述

2.使用场景

2.1.流量削峰

流量削峰的由来

主要是还是来自于互联网的业务场景,例如,马上即将开始的春节火车票抢购,大量的用户需要同一时间去抢购;以及大家熟知的阿里双11秒杀, 短时间上亿的用户涌入,瞬间流量巨大(高并发),比如:200万人准备在凌晨12:00准备抢购一件商品,但是商品的数量缺是有限的100-500件左右。

这样真实能购买到该件商品的用户也只有几百人左右, 但是从业务上来说,秒杀活动是希望更多的人来参与,也就是抢购之前希望有越来越多的人来看购买商品。

但是,在抢购时间达到后,用户开始真正下单时,秒杀的服务器后端缺不希望同时有几百万人同时发起抢购请求。

我们都知道服务器的处理资源是有限的,所以出现峰值的时候,很容易导致服务器宕机,用户无法访问的情况出现。

2.2 日志处理

在这里插入图片描述

2.3 应用解耦

在这里插入图片描述

2.4 异步处理

在这里插入图片描述

在这里插入图片描述

3. RabbitMQ简介

简介

​ RabbitMQ采用Erlang语言开发,是实现了高级消息队列协议(AMQP Advanced Message Queuing Protocol) 的开源消息中间件。

优点:

  • 性能很好,延时低
  • 吞吐量到万级
  • 有良好的管理界面管理工具
  • 社区相对比较活跃

缺点:

  • 吞吐量相对低

4. AMQP 协议

Advanced Message Queuing Protocol 高级消息队列协议

在这里插入图片描述

5. Windows环境下单节点安装

下载安装包

点击跳转下载RabbitMQ页面

查看该RabbitMQ所需的Erlang版本

在这里插入图片描述

下载erlang

在这里插入图片描述

安装erlang:

双击默认安装,选择安装目录,目录不能有中文字符,计算机名不能有中文字符

配置erlang环境变量

打开cmd输入erl

在这里插入图片描述

安装rabbitmq

在这里插入图片描述

激活rabbitMQ UI管理界面:

进入rabbit的sbin目录下运行

D:\work\java\rabbitMQ\rabbitmq_server-3.8.3\sbin> rabbitmq-plugins.bat enable rabbitmq_management

在这里插入图片描述

重启服务:

在这里插入图片描述

浏览器访问:http://localhost:15672/
输入username:guest
输入password:guest

在这里插入图片描述

6.RabbitMQ 管理界面使用

​ 浏览器地址栏输入:localhost:15672

​ 用户名:guest 密码:guest

在这里插入图片描述

添加用户

Tags

​ Admin:超级管理员

​ Monitoring:监控者,可以查看节点信息

​ Policymaker:策略制定者(镜像)

​ Management:

​ Impersonator:

​ None

在这里插入图片描述

​ 添加了一个admin 密码123456,Tags:Administrator

在这里插入图片描述

添加Virtual Host

​ Virtual Host相当于mysql的 db

​ 添加:一般以“/”开头

在这里插入图片描述
​ 添加后:

在这里插入图片描述

授权:

​ 设置admin访问vhost01

​ 点击用户名

在这里插入图片描述

​ 选择Virtual Host,然后Set permission

在这里插入图片描述

在这里插入图片描述

7.RabbitMQ 消息种类

7.1 simple 简单队列

在这里插入图片描述

P:消息生产者

红色:队列

C:消费者

3个对象:生产者 队列 消费者

7.1.1获取连接工具类 ConnectionUtil:

import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class ConnectionUtil {/*** 获取MQ的连接* @return*/public static Connection getConnection() throws IOException, TimeoutException {// 定义一个连接工厂ConnectionFactory factory = new ConnectionFactory();// 设置服务地址factory.setHost("localhost");// AMQP 5672factory.setPort(5672);// vhostfactory.setVirtualHost("/vhost01");// 用户名factory.setUsername("admin");// 密码factory.setPassword("123456");return factory.newConnection();}
}

7.1.2消息生产者:Send

public class Send {private static final String QUERE_NAME="test_simple_queue";public static void main(String[] args) throws IOException, TimeoutException {// 获取一个连接Connection connection = ConnectionUtil.getConnection();// 从连接中获取一个通道Channel channel = connection.createChannel();// 声明一个队列channel.queueDeclare(QUERE_NAME, false, false, false, null);String message = "hello simple !";channel.basicPublish("", QUERE_NAME, null, message.getBytes());System.out.println("send message");channel.close();connection.close();}
}

7.1.3 消费者:Recv

public class Recv {private static final String QUERE_NAME="test_simple_queue";public static void main(String[] args) throws IOException, TimeoutException {// 获取连接Connection connection = ConnectionUtil.getConnection();// 创建频道Channel channel = connection.createChannel();// 队列声明channel.queueDeclare(QUERE_NAME, false, false,false, null);// 定义队列的消费者DefaultConsumer defaultConsumer = new DefaultConsumer(channel){// 获取到达的消息@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {super.handleDelivery(consumerTag, envelope, properties, body);String msgString = new String(body,"utf-8");System.out.println("new api recv: " + msgString);}};// 监听队列channel.basicConsume(QUERE_NAME, true, defaultConsumer);}
}

7.1.4 简单队列的不足:

​ 耦合性高,生产者一一对应消费者(如果我想有多个消费者消费队列中消息,这时候就不行),队 列名变更,这时候得同时变更

7.2 work queues 工作队列,公平分发轮询分发

在这里插入图片描述

7.2.1 为什么会出现工作队列:

​ simple 队列是一一对应的,而且我们实际开发,生产者发送消息是毫不费力的,而消费者一般是要跟业务 相结合的,消费者接收到消息之后就需要处理,可能需要花费时间,这时候队列就会积压了很多消息

7.2.2 分发轮询

7.2.2.1 消息生产者:Send

public class Send {public static final String QUEUE_NAME = "test_work_queue";/***                  |--> C2* P ---> Queue ----|*                  |--> C1* @param args* @throws IOException* @throws TimeoutException*/public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {// 获取连接Connection connection = ConnectionUtil.getConnection();// 获取channelChannel channel = connection.createChannel();// 声明队列channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 发送消息for (int i = 0; i < 50; i++) {String msg= "send hello " + i;channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());System.out.println("【WQ】 send msg = " + msg);Thread.sleep(i*20);}// 关闭资源channel.close();connection.close();}
}
7.2.2.2 消费者:Recv1:

public class Recv1 {public static final String QUEUE_NAME = "test_work_queue";public static void main(String[] args) throws IOException, TimeoutException {// 获取连接Connection connection = ConnectionUtil.getConnection();// 获取channelChannel channel = connection.createChannel();// 声明队列channel.queueDeclare(QUEUE_NAME, false, false, false,null);// 定义一个消费者Consumer consumer = new DefaultConsumer(channel) {// 消息到达,触发这个方法@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {//super.handleDelivery(consumerTag, envelope, properties, body);String msg = new String(body, "utf-8");System.out.println("Recv [1] msg = " + msg);try{Thread.sleep(2000);}catch (InterruptedException e) {e.printStackTrace();}finally{System.out.println("Recv [1] done!");}}};// 监听队列boolean autoAck = true;channel.basicConsume(QUEUE_NAME, autoAck, consumer);}
}
7.2.2.3 消费者:Recv2
public class Recv2 {public static final String QUEUE_NAME = "test_work_queue";public static void main(String[] args) throws IOException, TimeoutException {// 获取连接Connection connection = ConnectionUtil.getConnection();// 获取channelChannel channel = connection.createChannel();// 声明队列channel.queueDeclare(QUEUE_NAME, false, false, false,null);// 定义一个消费者DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {// 消息到达,触发这个方法@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {super.handleDelivery(consumerTag, envelope, properties, body);String msg = new String(body, "utf-8");System.out.println("Recv [2] msg = " + msg);try{Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();} finally{System.out.println("Recv [2] done!");}}};// 监听队列boolean autoAck = true;channel.basicConsume(QUEUE_NAME, autoAck, defaultConsumer);}
}
7.2.2.4现象:

​ 消费者1 和消费者2处理消息的数量是一样的

​ 消费者1:偶数
​ 消费者2:奇数
​ 这种方式叫做轮询分发(round-robin)结果就是不管谁忙或者谁清闲 都不会多给一个消息。任务总是你一个我一个

7.2.3 公平分发 fair dipatch

需要手动回执

// MQ一次只发一个请求给消费者,当消费者处理完消息后会手动回执,然后MQ再发一个消息给消费者
channel.basicQos(1);boolean autoAck = false; //false 手动回执,处理完消息后,告诉MQchannel.basicConsume(QUEUE_NAME, autoAck, defaultConsumer);
7.2.3.1 生产者
public class Send {public static final String QUEUE_NAME = "test_work_queue";/***                  |--> C2* P ---> Queue ----|*                  |--> C1* @param args* @throws IOException* @throws TimeoutException*/public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {// 获取连接Connection connection = ConnectionUtil.getConnection();// 获取channelChannel channel = connection.createChannel();// 声明队列channel.queueDeclare(QUEUE_NAME, false, false, false, null);/*** 每个消费者 发送确认消息之前,消息队列不发送下一个消息到消费者,一次只处理一个消息* 限制发送给同一个消费者 不得超过一条消息*/channel.basicQos(1);// 发送消息for (int i = 0; i < 50; i++) {String msg= "send hello " + i;channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());System.out.println("【WQ】 send msg = " + msg);Thread.sleep(i*5);}// 关闭资源channel.close();connection.close();}
}
7.2.3.2 消费者1
public class Recv1 {public static final String QUEUE_NAME = "test_work_queue";public static void main(String[] args) throws IOException, TimeoutException {// 获取连接Connection connection = ConnectionUtil.getConnection();// 获取channelChannel channel = connection.createChannel();// 声明队列channel.queueDeclare(QUEUE_NAME, false, false, false,null);//  MQ一次只发一个请求给消费者,当消费者处理完消息后会手动回执,然后MQ再发一个消息给消费者channel.basicQos(1);// 定义一个消费者Consumer consumer = new DefaultConsumer(channel) {// 消息到达,触发这个方法@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {//super.handleDelivery(consumerTag, envelope, properties, body);String msg = new String(body, "utf-8");System.out.println("Recv [1] msg = " + msg);try{Thread.sleep(2000);}catch (InterruptedException e) {e.printStackTrace();}finally{System.out.println("Recv [1] done!");// 手动回执channel.basicAck(envelope.getDeliveryTag(), false);}}};// 监听队列
//        boolean autoAck = true; //自动应答boolean autoAck = false; //手动应答channel.basicConsume(QUEUE_NAME, autoAck, consumer);}
}
7.2.3.3 消费者2
public class Recv2 {public static final String QUEUE_NAME = "test_work_queue";public static void main(String[] args) throws IOException, TimeoutException {// 获取连接Connection connection = ConnectionUtil.getConnection();// 获取channelChannel channel = connection.createChannel();// 声明队列channel.queueDeclare(QUEUE_NAME, false, false, false,null);//  MQ一次只发一个请求给消费者,当消费者处理完消息后会手动回执,然后MQ再发一个消息给消费者channel.basicQos(1);// 定义一个消费者DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {// 消息到达,触发这个方法@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {super.handleDelivery(consumerTag, envelope, properties, body);String msg = new String(body, "utf-8");System.out.println("Recv [2] msg = " + msg);try{Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();} finally{System.out.println("Recv [2] done!");// 手动回执channel.basicAck(envelope.getDeliveryTag(), false);}}};// 监听队列boolean autoAck = false; //false 手动回执channel.basicConsume(QUEUE_NAME, autoAck, defaultConsumer);}
}
7.2.3.4 现象:

消费者2 处理的消息比消费者1多,能者多劳

7.3 publish/subscribe 发布订阅 订阅模式

在这里插入图片描述
1.一个生产者,多个消费者
2.每个消费者都有自己的队列
3.生产者没有直接把消息发送到队列,而是发送到交换机转换器 exchange
4.每个队列都要绑定到交换机上
5.生产者发送的消息,经过交换机,到达队列。就能实现一个消息被多个消费者消费

生产者

public class Send {public static final String EXCHANGE_NAME = "test_exchange_fanout";public static void main(String[] args) throws IOException, TimeoutException {Connection connection = ConnectionUtil.getConnection();Channel channel = connection.createChannel();// 声明交换机channel.exchangeDeclare(EXCHANGE_NAME, "fanout"); //分发// 发送消息String msg = "hello ps";channel.basicPublish(EXCHANGE_NAME, "", null, msg.getBytes());System.out.println("Send msg = " + msg);channel.close();connection.close();}
}

在这里插入图片描述

消息哪去了?? 丢失了,因为交换机没有存储的能力,在rabbitmq里面只有队列有存储的能力。
因为只是申明交换机后,还没有队列绑定到这个交换机,所以数据丢失了

注册 -》 邮件—》短信

消费者1:Recv1


public class Recv1 {public static final String QUEUE_NAME = "test_queue_fanout_email";public static final String EXCHANGE_NAME = "test_exchange_fanout";public static void main(String[] args) throws IOException, TimeoutException {// 获取连接Connection connection = ConnectionUtil.getConnection();// 获取channelChannel channel = connection.createChannel();// 声明队列channel.queueDeclare(QUEUE_NAME, false, false, false,null);// 保证一次只分发一个channel.basicQos(1);// 绑定到交换机 转发器channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");// 定义一个消费者Consumer consumer = new DefaultConsumer(channel) {// 消息到达,触发这个方法@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {//super.handleDelivery(consumerTag, envelope, properties, body);String msg = new String(body, "utf-8");System.out.println("Recv [1] msg = " + msg);try{Thread.sleep(2000);}catch (InterruptedException e) {e.printStackTrace();}finally{System.out.println("Recv [1] done!");// 手动回执channel.basicAck(envelope.getDeliveryTag(), false);}}};// 监听队列boolean autoAck = false;channel.basicConsume(QUEUE_NAME, autoAck, consumer);}
}

消费者2:Recv2

public class Recv2 {public static final String QUEUE_NAME = "test_queue_fanout_sms";public static final String EXCHANGE_NAME = "test_exchange_fanout";public static void main(String[] args) throws IOException, TimeoutException {// 获取连接Connection connection = ConnectionUtil.getConnection();// 获取channelChannel channel = connection.createChannel();// 声明队列channel.queueDeclare(QUEUE_NAME, false, false, false,null);// 绑定到交换机 转发器channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");// 保证一次只分发一个channel.basicQos(1);// 定义一个消费者Consumer consumer = new DefaultConsumer(channel) {// 消息到达,触发这个方法@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {//super.handleDelivery(consumerTag, envelope, properties, body);String msg = new String(body, "utf-8");System.out.println("Recv [2] msg = " + msg);try{Thread.sleep(2000);}catch (InterruptedException e) {e.printStackTrace();}finally{System.out.println("Recv [2] done!");// 手动回执channel.basicAck(envelope.getDeliveryTag(), false);}}};// 监听队列boolean autoAck = false;channel.basicConsume(QUEUE_NAME, autoAck, consumer);}
}

在这里插入图片描述

7. 4.routing 路由选择通配符模式

在这里插入图片描述

生产者

public class Send {public static final String EXCHANGE_NAME = "test_exchange_direct";public static void main(String[] args) throws IOException, TimeoutException {Connection connection = ConnectionUtil.getConnection();Channel channel = connection.createChannel();// exchangechannel.exchangeDeclare(EXCHANGE_NAME, "direct");String msg = "hello direct !";// routing keyString routingKey = "info";channel.basicPublish(EXCHANGE_NAME, routingKey, null, msg.getBytes());System.out.println("send :" + msg);channel.close();connection.close();}
}

消费者1:Recv1

public class Recv1 {public static final String EXCHANGE_NAME = "test_exchange_direct";public static final String QUEUE_NAME = "test_queue_direct_1";public static void main(String[] args) throws IOException, TimeoutException {Connection connection = ConnectionUtil.getConnection();Channel channel = connection.createChannel();// 声明队列channel.queueDeclare(QUEUE_NAME, false, false, false,null);// 绑定队列到交换机,并绑定 routingKeychannel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "error");// 保证一次只分发一个channel.basicQos(1);// 定义一个消费者Consumer consumer = new DefaultConsumer(channel){// 消息到达,触发这个方法@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {String msg = new String(body, "utf-8");System.out.println("Recv [1] msg = " + msg);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();} finally{// 消息回执channel.basicAck(envelope.getDeliveryTag(), false);System.out.println("Recv [1] done!");}}};// 监听队列 autoAck(消息应答):false 手动回执 (消息回执 channel.basicAck(envelope.getDeliveryTag(), false);)channel.basicConsume(QUEUE_NAME, false, consumer);}
}

消费者2:Recv2

public class Recv2 {public static final String EXCHANGE_NAME = "test_exchange_direct";public static final String QUEUE_NAME = "test_queue_direct_2";public static void main(String[] args) throws IOException, TimeoutException {Connection connection = ConnectionUtil.getConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false,null);channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "error");channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "info");channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "waring");channel.basicQos(1);Consumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {String msg = new String(body, "utf-8");System.out.println("Recv [2] msg = " + msg);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();} finally{channel.basicAck(envelope.getDeliveryTag(), false);System.out.println("Recv [2] done!");}}};channel.basicConsume(QUEUE_NAME, false, consumer);}
}

7.5.Topics 主题

在这里插入图片描述

​ Topic exchange
​ 将路由和某个模式匹配
​ # 匹配一个或者多个字符
​ * 匹配一个字符
​ 例如:Goods.#

在这里插入图片描述

商品:发布、删除、修改、查询

生产者

public class Send {public static final String EXCHANGE_NAME = "test_exchange_topic";public static void main(String[] args) throws IOException, TimeoutException {Connection connection = ConnectionUtil.getConnection();Channel channel = connection.createChannel();// 声明交换机channel.exchangeDeclare(EXCHANGE_NAME, "topic");String message = "商品...";channel.basicPublish(EXCHANGE_NAME, "goods.delete", null, message.getBytes());System.out.println("send message = " + message);channel.close();connection.close();}}

消费者:

public class Recv1 {public static final String EXCHANGE_NAME = "test_exchange_topic";public static final String QUEUE_NAME = "test_queue_topic_1";public static void main(String[] args) throws IOException, TimeoutException {Connection connection = ConnectionUtil.getConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false,false,false,null);//绑定:channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "goods.add");channel.basicQos(1);//定义消费者Consumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {String msg = new String(body, "utf-8");System.out.println("[1] recv msg: " + msg);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();} finally{System.out.println("[1] recv done!");// 手动回执channel.basicAck(envelope.getDeliveryTag(), false);}}};// 监听队列channel.basicConsume(QUEUE_NAME, false, consumer);}
}

消费者2

public class Recv2 {public static final String EXCHANGE_NAME = "test_exchange_topic";public static final String QUEUE_NAME = "test_queue_topic_2";public static void main(String[] args) throws IOException, TimeoutException {Connection connection = ConnectionUtil.getConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false,false,false,null);//绑定:channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "goods.#");channel.basicQos(1);//定义消费者Consumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {String msg = new String(body, "utf-8");System.out.println("[2] recv msg: " + msg);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();} finally{System.out.println("[2] recv done!");// 手动回执channel.basicAck(envelope.getDeliveryTag(), false);}}};// 监听队列channel.basicConsume(QUEUE_NAME, false, consumer);}
}

7.6 RPC 手动和自动确认消息(消息确认机制 事务——confirm)

在rabbitmq中,我们可以通过持久化数据,解决rabbitmq服务器异常的数据丢失问题
问题:生产者将消息发送出去之后,消息到底有没有到达 rabbitmq服务器,默认的情况是不知道的
两种方式:

​ AMQP 实现了事务机制

​ confirm 模式

事务机制:

txSelect txCommit txRollback

txSelect :用户将当前的channel设置成transaction模式
txCommit :用于提交事务
txRollback:回滚事务

生产者
public class TxSend {public static final String QUEUE_NAME = "test_queue_tx";public static void main(String[] args) throws IOException, TimeoutException {Connection connection = ConnectionUtil.getConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);String msg = "hello tx message";try{// 开启事务channel.txSelect();channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());System.out.println(1/0);//提交事务channel.txCommit();} catch(Exception e){// 回滚事务channel.txRollback();System.out.println("send message txRollback");} finally{channel.close();connection.close();}}

消费者:

public class TxRecv {public static final String QUEUE_NAME="test_queue_tx";public static void main(String[] args) throws IOException, TimeoutException {Connection connection = ConnectionUtil.getConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);channel.basicConsume(QUEUE_NAME, true, new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {String msg = new String(body, "utf-8");System.out.println("recv[tx] msg:" + msg);}});}
}

此种模式还是很耗时的,采用了这种方式,降低了Rabbitmq的消息吞吐量

Confirm 模式

生产者端模式的实现原理

生产者将信道设置成confirm模式,一旦信道进入confirm模式,所有在该信道上面发布的消息都会被指派一个唯一的ID(从1开始)。一旦消息被投递到所有匹配的队列之后,broker就会发送一个确认给生产者(包含消息的唯一ID) 。这就使得生产者知道消息已经正确到达目的队列了,如果消息和队列是可持久化的,那么确认消息会将洧息写入磁盘之后发出,broker 回传给生产者的确认消息中deliver-tag 域包含了确认消息的序列号,此外broker也可以设置basic.ack的multiple域。表示到这个序列号之前的所有消息都已经得到了处理。

Confirm 模式最大的好处在于他是异步

Nack

开启confirm模式
channel.confirmSelect();

编程模式:

1.普通 waitForCOnfirms()

  1. 批量的 发一批 waitForConfirms
  2. 异步 confirm 模式:提供一个回调

普通 confirm 单条普通

send

/*** 普通模式*/
public class Send1 {public static final String QUEUE_NAME = "test_queue_confirm1";public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {Connection connection = ConnectionUtil.getConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 生产者调用confirmSelect 将chancel设置为confirm模式。注意(事务机制改为这个会出异常)channel.confirmSelect();String msg = "hello confirm message";channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());System.out.println("send message txRollback");// 判断是否发送成功if(!channel.waitForConfirms()){System.out.println("message send failed");} else {System.out.println("message send ok");}channel.close();connection.close();}
}

批量的 发一批 waitForConfirms

/*** 批量模式*/
public class Send2 {public static final String QUEUE_NAME = "test_queue_confirm2";public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {Connection connection = ConnectionUtil.getConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 生产者调用confirmSelect 将chancel设置为confirm模式。注意(事务机制改为这个会出异常)channel.confirmSelect();// 批量发送for (int i = 0; i < 10; i++) {String msg = "hello confirm message";channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());}System.out.println("send message txRollback");// 确认是否发送成功if(!channel.waitForConfirms()){System.out.println("message send failed");} else {System.out.println("message send ok");}channel.close();connection.close();}
}

异步模式

Channel 对象提供的ConfirmListener()回调方法只包含deliveryTag (当前Channel发出的消息序号)。我们需要自己为每一个Channel维护一个unconfirm的消息序号集合,每publish一条数据,集合中元素加1。每回调一次handleAck方法,unconfirm 集合删掉相应的一条(multiple=false) 或多条( multiple=true)记录。从程序运行效率上看,这个unconfirm集合最好采用有序集合SortedSet存储结构。

生产者:

/*** 异步*/
public class Send3 {public static final String QUEUE_NAME = "test_queue_confirm3";public static void main(String[] args) throws IOException, TimeoutException {Connection connection = ConnectionUtil.getConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false,false,false, null);// 生产者调用confirmSelect 将channel设置为confirm模式channel.confirmSelect();// 存放未确认的消息标识final SortedSet<Long> confirmSet = Collections.synchronizedSortedSet(new TreeSet<Long>());// 监听通道channel.addConfirmListener(new ConfirmListener(){// 没问题的handleAck@Overridepublic void handleAck(long deliveryTag, boolean multiple) throws IOException {if(multiple){System.out.println("【handleAck】-----multiple true");confirmSet.headSet(deliveryTag+1).clear();} else {System.out.println("【handleAck】-----multiple false");confirmSet.remove(deliveryTag);}}// handleNack 有问题的@Overridepublic void handleNack(long deliveryTag, boolean multiple) throws IOException {if(multiple){System.out.println("【N】handleNack-----multiple");confirmSet.headSet(deliveryTag + 1).clear();} else {System.out.println("【N】handleNack-----multiple false");confirmSet.remove(deliveryTag);}}});String msgStr = "ssss";while(true){long seqNo = channel.getNextPublishSeqNo();channel.basicPublish("", QUEUE_NAME, null, msgStr.getBytes());confirmSet.add(seqNo);}}
}

在这里插入图片描述

消息应答与消息持久化

消息应答

boolean autoAck = false; //false 手动回执

channel.basicConsume(QUEUE_NAME, autoAck, defaultConsumer);

boolean autoAck =true;(自动确认模式)一旦rabbitmq将消息分发给消费者,就会从内存中删除
这种情况下:如果杀死正在执行的消费者,就会丢失正在处理的消息。

boolean autoAck =false;(手动模式),如果有一个消费者挂掉,就会交付给其它消费者,rabbitmq支持消息应答,消费者发送一个消息应答,告诉rabbitmq这个消息我已经处理完成,你可以删了,然后rabbitmq就删除内存中的消息。

消息应答默认是打开的,默认是false

Message acknowledgment:

​ 如果rabbitmq挂了,消息仍然会丢失

消息持久化

Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,                             Map<String, Object> arguments) throws IOException;

boolean durable = false;

channel.queueDeclare(QUEUE_NAME, false, false, false,null);

我们将程序中的boolean durable = false 改成true,是不可以的,尽管代码是正确的,他也不会运行成功!因为我们已经定义了一个叫test_work_queue ,这个queue是为持久化的,rabbitmq不允许重新定义 (不同参数)一个已存在的队列

Exchange (交换机 转发器)

一方面是接收生产者的消息,另一方面是向队列推送消息

匿名转发

void basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body) throws IOException;

String exchange:交换机名字

channel.basicPublish("", QUERE_NAME, null, message.getBytes());

类型:

fanout(不处理路由键)

在这里插入图片描述

Direct(处理路由键)

路由模式:

在这里插入图片描述

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 操作系统实验——磁盘调度算法(FIFS SSTF SCAN)

    操作系统实验——磁盘调度算法(FIFS SSTF SCAN) 一、实验目的 1、了解磁盘调度的策略和原理; 2、理解和掌握磁盘调度算法——先来先服务算法(FCFS)、最短寻道时间优先算法(SSTF)、电梯扫描算法(SCAN)。 二、实验内容 1、模拟先来先服务法(First-Come, First-Served,…...

    2024/4/30 16:40:03
  2. 贝叶斯网络之父Judea Pearl:要建立真正的人工智能,少不了因果推理

    贝叶斯网络之父Judea Pearl:要建立真正的人工智能,少不了因果推理 2011年图灵奖得主,贝叶斯网络之父Judea Pearl认为现在人工智能的发展进入的新的瓶颈期,各种新的成果不过本质上不过是重复简单的“曲线拟合”工作。Pearl 认为人们应该更关注人工智能中的因果(Cause and E…...

    2024/4/30 16:49:20
  3. 关于百度七日打卡——强化学习的感悟

    1.刚开始第一个作业搭建环境PARL: PARL是一个算法库,是对Agent的框架抽象。简单来说就是在一台机器上调用pip install parl,就可以启动集群并行计算,使运算加速。 PS:心里窃喜,对于我们小白,非常友好,因为之前有机器学习的基础,又经常~~白嫖~~ 参加aistudio的活动,所以…...

    2024/4/24 14:24:53
  4. leetcode-6_递归和回溯

    算法总结递归和回溯中的常见问题1.树形问题2.什么是回溯3.排列问题4.组合问题5.回溯法解决问题的优化6.二维平面上的回朔法7.foodfill算法8.回朔法是人工智能的基础 递归和回溯中的常见问题 1.树形问题 Leetcode相关题目: 17 (1) 电话号码的字母组合。(LeetCode:17) 2.什…...

    2024/4/30 17:57:08
  5. contos 文件操作

    contos 操作 xshell脚本 入门到放弃,边操作边记录 查看文件夹及文件: ls创建文件夹: mkdir 文件夹名进入文件夹:cd 文件夹名返回上一层: cd..创建文件: touch 文件名.后缀编辑文件:vi 文件名.后缀保存:按esc键,输入 :wq:w 保存文件但不退出 :w file 将修改另外保存…...

    2024/4/24 14:24:50
  6. Chomp 游戏与偏序关系

    Chomp 游戏与偏序关系一、游戏介绍Chomp是一个双人游戏,有 m X n 块曲奇饼排成一个矩形格状,称作棋盘。两个玩家轮流自选吃掉一块还剩下的曲奇饼,而且要把它右边和下面所有的曲奇饼都被取走(如果存在)。如果不吃左上角的那一块曲奇饼(位置记为(1, 1))就没有其他选择的玩…...

    2024/4/24 14:24:49
  7. 永磁直流无刷电机设计之路(四)——仿真计算分析

    永磁直流无刷电机设计之路(四)——仿真计算分析 在数学中,有限元法(FEM,Finite Element Method)是一种为求解偏微分方程边值问题近似解的数值技术。求解时对整个问题区域进行分解,每个子区域都成为简单的部分,这种简单部分就称作有限元。 它通过变分方法,使得误差函数…...

    2024/4/26 23:59:55
  8. 模型压缩95%,MIT韩松等人提出新型Lite Transformer

    文章目录长短距离注意力(LSRA)实验设置架构实验结果机器翻译与自动化设计模型的对比文本摘要 转载来源:https://zhuanlan.zhihu.com/p/146448576Transformer 的高性能依赖于极高的算力,这让移动端 NLP 严重受限。在不久之前的 ICLR 2020 论文中,MIT 与上海交大的研究人员提…...

    2024/4/24 14:24:47
  9. 知识产权大作业

    一、怎样从历史视角看待知识产权 首先我想列举两个关于古代中国是否存在知识产权的概念的两种观点。一个是哈佛大学的安守廉教授的观点。他认为中国自古以来不存在知识产权保护这一概念,即使具有知识产权保护的雏形,也只是某种形式上的东西。而郑成思教授提出中国古代存在版权保…...

    2024/4/30 18:17:02
  10. 渗透测试-Openssl心脏出血漏洞复现

    心脏滴血 早在2014年,互联网安全协议OpenSSL被曝存在一个十分严重的安全漏洞。在黑客社区,它被命名为“心脏出血”,表明网络上出现了“致命内伤”。利用该漏洞,黑客可以获取约30%的https开头网址的用户登录账号密码,其中包括购物、网银、社交、门户等类型的知名网站。 漏洞…...

    2024/4/30 17:54:00
  11. 哈尔滨工业大学软件构造课程笔记第六章第三节

    6.3 断言与防御式编程 1.回忆:设计ADT 第一个防御:让bug不可能出现 最好的防御就是不要引入bug 静态检查:通过在编译时捕获bug来消除许多bug。 动态检查:Java使数组溢出错误不可能捕获他们动态。如果尝试在数组或列表的边界之外使用索引,那么Java会自动产生错误。——未检查的…...

    2024/4/26 16:46:05
  12. 最详细下载安装注册最新版SecureCRT 八.七

    文章目录一.下载SecureCRT 八.七二.安装SecureCRT 8.7三.注册SecureCRT 8.7 一.下载SecureCRT 八.七官网下载网址:https://www.vandyke.com/products/securecrt/2.选择系统3.选择64位或者32位4.输入邮箱密码 邮箱 admin@mail.bccto.me 密码 wheretogo88885.点击下载,下载完成 文…...

    2024/4/30 18:06:41
  13. C08(goto 和 void 分析)

    文章目录1. goto关键字2. void 关键字2.1 void 修饰函数返回值和参数2.2 C语言不存在void变量2.3 void 指针的含义3. 总结 1. goto关键字在如今的项目经验中禁止使用 goto goto 语句的使用给程序的可读性带来了麻烦,不方便维护,并且使用的时候很容易出现错误2. void 关键字 2…...

    2024/4/19 21:13:31
  14. transformers库学习笔记(一):安装与测试

    印象中觉得transformers是一个庞然大物,但实际接触后,却是极其友好,感谢huggingface大神。原文见tmylla.github.io。​ 安装 我的版本号:python 3.6.9;pytorch 1.0;CUDA 10.0。 pip install transformerspip之前确保安装1.1.0+。​ 测试 验证代码与结果 python -c "…...

    2024/4/15 3:14:48
  15. day01笔记

    序言小学期软件编程实践笔记 (:IDE工具VSCode语法检测:头文件(include 头文件)+编译内置的语法 添加头文件检测 ctrl + shift + p -> C++配置编辑:添加头文件所在目录;控制终端命令 环境变量PATH: echo %PATH% set指令显示所有环境变量 PATH:Windows 执行程序的搜索的路…...

    2024/4/15 3:14:48
  16. 后验概率与条件概率区别

    ** 后验概率与条件概率区别 ** 后验概率就是一种条件概率,但是与其它条件概率的不同之处在于,它限定了目标事件为隐变量取值,而其中的条件为观测结果。 一般的条件概率,条件和事件都可以是任意的。 贝叶斯公式就是由先验概率求后验概率的公式 举例区分普通条件概率与后验概…...

    2024/4/15 3:14:47
  17. 二分查找_求解sqrt问题

    二分查找_求解sqrt的基本问题 1 实现 int sqrt(int x) 函数 计算并返回 x 的平方根,其中 x 是非负整数。 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。 示例 1:输入: 4 输出: 2 示例 2:输入: 8 输出: 2 说明: 8 的平方根是 2.82842..., 由于返回类型是整数,…...

    2024/4/24 14:24:48
  18. 插入排序(Insertion Sorting)

    插入排序(Insertion Sorting) 1.基本介绍插入式排序属于内部排序法,是对于欲排序的元素以插入的方式找寻该元素的适当位置,以达到排序的目的。 插入排序(Insertion Sorting)的基本思想是:把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,…...

    2024/4/24 14:24:42
  19. 背包问题--01背包 (Bitset的优化) 多重背包 (二进制优化)

    01背包问题:题目链接题意:n个物品一个m容量的背包,n个物品有need[i]的体积消耗,以及权值value[i] ,问m容量装n个物品能得到的最大权值是多少。做法:01背包介绍:博客代码:#include<bits/stdc++.h> using namespace std; typedef long long ll; inline ll read() {…...

    2024/4/24 14:24:40
  20. ubuntu安装mysql数据库

    三条命令安装mysql: sudo apt-get install mysql-server sudo apt-get install mysql-client sudo apt-get install libmysqlclient-dev登录数据库 systemctl start mysql # 打开数据库 mysql -uroot -p # 登录数据库,第一次登陆不需要密码...

    2024/4/24 14:24:39

最新文章

  1. 《深入解析WIndows操作系统》第9章读书笔记

    1、闪存类型&#xff1a;常见的闪存类型有NOR和NAND。NOR闪存在操作上最接近RAM&#xff0c;它的每个字节都可以被独立地寻址&#xff0c;而NAND闪存则被组织成以块为单位&#xff0c;就像磁盘一样。NOR类型的闪存用来设计保存计算机主板上的BIOS&#xff0c;而NAND类型的闪存被…...

    2024/4/30 18:18:12
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. 【Ubuntu】 Github Readme导入GIF

    1.工具安装 我们使用 ffmpeg 软件来完成转换工作1.1 安装命令 sudo add-apt-repository ppa:jonathonf/ffmpeg-3sudo apt-get updatesudo apt-get install ffmpeg1.2 转换命令 &#xff08;1&#xff09;直接转换命令&#xff1a; ffmpeg -i out.mp4 out.gif(2) 带参数命令&…...

    2024/4/30 1:46:01
  4. 从头开发一个RISC-V的操作系统(二)RISC-V 指令集架构介绍

    文章目录 前提ISA的基本介绍ISA是什么CISC vs RISCISA的宽度 RISC-V指令集RISC-V ISA的命名规范模块化的ISA通用寄存器Hart特权级别内存管理与保护异常和中断 目标&#xff1a;通过这一个系列课程的学习&#xff0c;开发出一个简易的在RISC-V指令集架构上运行的操作系统。 前提…...

    2024/4/29 20:05:10
  5. composer常见错误解决

    在Java中&#xff0c;常见的问题和解决方法包括&#xff1a; 内存不足错误&#xff1a;Java应用程序在运行时可能会遇到内存不足的错误。可以通过增加JVM的堆内存大小来解决&#xff0c;可以通过设置-Xms和-Xmx参数来指定初始堆大小和最大堆大小。 java -Xms2G -Xmx4G YourAppl…...

    2024/4/30 3:27:03
  6. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/4/29 23:16:47
  7. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/4/30 18:14:14
  8. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/29 2:29:43
  9. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/4/29 14:21:50
  10. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/27 17:58:04
  11. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/27 14:22:49
  12. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/28 1:28:33
  13. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/30 9:43:09
  14. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/27 17:59:30
  15. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/4/25 18:39:16
  16. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/28 1:34:08
  17. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/26 19:03:37
  18. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/29 20:46:55
  19. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/25 18:39:14
  20. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/4/26 23:04:58
  21. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/27 23:24:42
  22. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/28 5:48:52
  23. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/30 9:42:22
  24. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/4/30 9:43:22
  25. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/30 9:42:49
  26. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  27. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  28. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  29. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  30. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  31. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  32. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  33. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  34. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  35. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  36. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  37. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  38. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  39. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  40. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  41. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  42. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  43. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  44. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  45. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57