建筑公司做网站买空间多大合适/谷歌搜索引擎优化seo
RabbitMQ
它是消息中间件,是在消息的传输过程中保存消息的容器,实现应用程序和应用程序之间通信的中间产品。目前主流消息队列通讯协议是AMQP(二进制传输,支持多种语言)、JMS(HTTP传输,只支持Java)。
特点:每秒十万左右级别、消息延迟在微秒级、完整的消息确认机制、并发能力强、性能好。
常见MQ
- ActiveMQ基于JMS,每秒数万级别
- RabbitMQ基于AMQP,每秒十万级别
- RocketMQ是阿里的产品,基于JMS,每秒十万级别,经历过双十一
- Kafka自定义协议,每秒百万级别
体系结构
分为:服务器、交换器、队列;
服务器:负责管理所有的交换器和队列,一个RabbitMQ内有多个服务器,(为了避免每次发送消息都建立TCP连接,有了很多的服务器,每个线程建立单独的服务器进行通讯)每个服务器负责一部分交换器和队列,之间通过 HTTP 协议通信;
交换机:负责接收、路由、传递消息,支持多种交换器类型,每个类型有不同的消息传递方式和使用场景;
队列:负责存储消息,支持多种队列,都有不同的存储方式;
安装:
使用docker方式
# 拉取镜像
docker pull rabbitmq:3.8.12-management
# 注意:在拉取镜像,遇到missing signature key问题,需要提升docker的版本# 运行容器
# -d 参数:后台运行 Docker 容器
# -e 参数:设置容器内的环境变量,这里我们设置了登录RabbitMQ管理后台的默认用户和密码
docker run --name rabbitmq -d -p 5672:5672 -p 15672:15672 -e RABBITMQ_DEFAULT_USER=guest -e RABBITMQ_DEFAULT_PASS=123456 rabbitmq:3.8.12-management# 启动成功,MQ的客户端页面,输入所设置的用户名和密码
# 访问:http://xxx:15672# 如果访问不通,需要开放端口
firewall-cmd --zone=plublic -add-pord=5672/tcp --add-pord=15672/tcp --permanent
success
firewall-cmd --reload
success
发送消息
需要引包
<dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.20.0</version>
</dependency>
生产者
// 生产者 - 产生消息
public static void main(String[] args) throws Exception {ConnectionFactory connectionFactory = new ConnectionFactory();connectionFactory.setHost("IP地址");connectionFactory.setPort(5672);connectionFactory.setVirtualHost("/");connectionFactory.setUsername("guest");connectionFactory.setPassword("123456");// 创建连接Connection connection = connectionFactory.newConnection();// 创建频道Channel channel = connection.createChannel();// 创建队列,参数:队列名称、是否定义持久化队列、是否独占本次连接、是否在不使用的时候自动删除队列、其他参数channel.queueDeclare("new_queue", true, false, false, null);String message = "发送的消息的内容:123";// 参数:交换机名称,默认Default Exchange、队列名称、配置信息、消息内容channel.basicPublish("", "new_queue", null, message.getBytes());// 关闭资源 channel.close();connection.close();
}
创建一个队列,并有消息待查看,点击该队列的名称,在Get messages处,可以查看该消息的信息;
查看队列:
消费者
// 消费者 - 要消费消息
public static void main(String[] args) throws Exception {ConnectionFactory factory = new ConnectionFactory();factory.setHost("IP地址");factory.setPort(5672);factory.setVirtualHost("/");factory.setUsername("guest");factory.setPassword("123456");// 创建连接 Connection Connection connection = factory.newConnection();// 创建频道 Channel channel = connection.createChannel();// 接收消息 DefaultConsumer consumer = new DefaultConsumer(channel) {// 回调方法,当收到消息后,会自动执行该方法 // 参数:标识、获取一些信息,交换机等、配置信息、数据(消息内容)@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println("consumerTag:" + consumerTag);System.out.println("Exchange:" + envelope.getExchange());System.out.println("RoutingKey:" + envelope.getRoutingKey());System.out.println("properties:" + properties);System.out.println("body:" + new String(body));}};// 监听程序,用来监听消息,参数:队列、是否自动确认、回调对象 channel.basicConsume("new_queue", true, consumer);
}
如果有被消费者消费,会在管理页中,该队列的 Ready进行-1;
工作模式
简单模式
生产者(只有一个)、消费者(只有一个)、消息储存在队列中;
工作队列模式
生产者(只有一个)、消费者(有多个)、消息储存在队列中;消费者谁抢到算谁的。
发布订阅模式
生产者(只有一个)、消费者(有多个)、交换机、多个队列;
生产者把消息发送给交换机,交换机处理消息取决于交换机的类型,交换机根据类型把消费存在对应的队列中,消费者(多个)满足规则都可以得到消息;
交换机有3种类型
➢ Fanout:广播,将消息交给所有绑定到交换机的队列
➢ Direct:定向,把消息交给符合指定routing key 的队列
➢ Topic:通配符,把消息交给符合routing pattern(路由模式) 的队列
路由模式
队列与交换机的绑定,使用Direct,消费者监听的队列,该队列与交换机绑定的路由件匹配,该消费者可以收到消息。其他消费者也监听该队列,但路由件不匹配,不会收到消息。
查看交换机
交换机与队列的绑定
主题模式(通配符匹配)
这个与路由模式类似,只是这个支持通配符绑定,# 匹配一个或多个词,* 匹配不多不少恰好1个词。
创建
创建交换机
创建队列
队列与交换机绑定
整合SpringBoot
引包
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
更改配置文件
spring: rabbitmq: host: IP地址port: 5672 username: guest password: 123456 virtual-host: /# 来保证消息的可靠性publisher-confirm-type: CORRELATED # 交换机的确认publisher-returns: true # 队列的确认
代码
// 生产者
@Autowired
private RabbitTemplate rabbitTemplate;public void testSend() { rabbitTemplate.convertAndSend("交换机","路由键","消息内容");
}
// 消费者 (durable 是否持久化)
@RabbitListener(bindings = @QueueBinding(value = @Queue(value = "队列名字", durable = "true"),exchange = @Exchange(value = "交换机"),key = {"路由键"}
))
public void process(String dateString,Message message,Channel channel) {log.info("消息内容:"+ dateString);
}
配置类
生产者保障消息的可靠性
生产者 - 保障消息是否发送到队列或者交换机
@Component
public class MQAckConfig implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback {@Autowiredprivate RabbitTemplate rabbitTemplate;@PostConstructpublic void init() {rabbitTemplate.setConfirmCallback(this);rabbitTemplate.setReturnsCallback(this);}/*** 确认消息是否发送到交换机*/@Overridepublic void confirm(CorrelationData correlationData, boolean ack, String cause) {if (ack) {log.info("消息发送到交换机 - 成功!数据:" + correlationData);} else {log.info("消息发送到交换机 - 失败!数据:" + correlationData + " 原因:" + cause);}}/*** 确认消息是否发送到队列 - 只有发送失败的时候才会调用该方法*/@Overridepublic void returnedMessage(ReturnedMessage returned) {log.info("消息主体: " + new String(returned.getMessage().getBody()));log.info("应答码: " + returned.getReplyCode());log.info("描述:" + returned.getReplyText());log.info("消息使用的交换器 exchange : " + returned.getExchange());log.info("消息使用的路由键 routing : " + returned.getRoutingKey());}}
消费者保障消息的可靠性
消费者 - 保障消息真的收到,改为手动确认ACK
spring:rabbitmq:...listener:simple:acknowledge-mode: manual # 把消息确认模式改为手动确认
消费者手动ACK
@RabbitListener( // 设置绑定关系bindings = @QueueBinding(// 配置队列信息:durable 设置为 true 表示队列持久化;autoDelete 设置为 false 表示关闭自动删除value = @Queue(value = QUEUE_NAME, durable = "true", autoDelete = "false"),// 配置交换机信息:durable 设置为 true 表示队列持久化;autoDelete 设置为 false 表示关闭自动删除exchange = @Exchange(value = EXCHANGE_DIRECT, durable = "true", autoDelete = "false"),// 配置路由键信息key = {ROUTING_KEY}
))
public void processMessage2(String dataString, Message message, Channel channel) throws IOException {// 注意: 重置消息,需要考虑幂等性long tag = message.getMessageProperties().getDeliveryTag();try {log.info("消费者 - 接收消息:" + dataString);// System.out.println(10 / 0); // 手动制造出异常,让消息回到队列中channel.basicAck(tag, false);} catch (Exception e) {// 获取信息,查看此消息是否曾经被投递过Boolean redelivered = message.getMessageProperties().getRedelivered();if (!redelivered) {// 没有被投递过,那就重新放回队列,重新投递,再试一次channel.basicNack(tag, false, true);} else {// 已经被投递过,且这一次仍然进入了 catch 块,那么返回拒绝此消息,不会回到MQ队列中channel.basicReject(tag, false);}}
}
消费者-限流
大量消息进入队列中,消息队列中消息有1万,设置每次最多从队列取回1000个消息,并发能力只能处理1000个请求,消费端-最多只处理1000个请求;
限流配置
spring:rabbitmq:...listener:simple:acknowledge-mode: manual # 把消息确认模式改为手动确认prefetch: 10 # 设置消费者,每次最多从消息队列服务器取回多少消息,并不是一下把队列中的消息全部取走
从队列中Ready,变成所设置的值,从此起到了限流的作用,消息者处理ACK个数也下降。
消息超时
可在创建队列的时候,设置参数:x-message-ttl = 3000 (毫秒值)
,当我们生产者发送消息到队列,队列里的消息没有被消费者消费时,可通过队列里的消息超时时间,进行丢弃消息。
@Autowired
private RabbitTemplate rabbitTemplate;MessagePostProcessor processor = (Message message) -> {// 设定超时时间,单位 (毫秒)message.getMessageProperties().setExpiration("7000");return message;
};
rabbitTemplate.convertAndSend("交换机名", "路由键", "生产者发送消息 - 消息超时 - " + processor);
死信
一个消息无法被消费,会变成死信;产生的原因:消费者拒绝:basicNack
、basicReject
这两个方法不把消息重新放回队列、队列溢出:队列里的消息达到数量的限制、消息超时:超时时间未被消费;
解决:丢弃(一般不重要数据)、入库(记录日志、后续处理)、监听(进入死信队列,监听死信队列进行处理)
前提准备:
创建死信交换机、死信队列、死信路由键,互相绑定;
创建正常交换机、队列、路由键,互相绑定;
// 前提把 死信、正常都创建好,绑定好
// 监听正常队列
@RabbitListener(queues = {‘正常队列’})
public void processMessageNormal(String dateString, Message message, Channel channel) throws IOException {// 监听正常队列,但是拒绝消息,进行消息拒绝log.info("【正常】接受到消息:" + dateString);;channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
}
// 监听死信队列
@RabbitListener(queues = {‘死信队列’})
public void processMessageDead(String dataString, Message message, Channel channel) throws IOException {// 监听死信队列log.info("【死信】接受到消息 = " + dataString);channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
}
延迟队列
方案一:
生产者发送消息,到队列中,该队列配置消息超时时间,并没有消费者进行监听该队列(进行监听消费),超时进入死信队列,(监听死信队列)就是延迟队列的一种配置。
方案二:
安装插件,默认消息存放最多2天
地址:https://github.com/rabbitmq/rabbitmq-delayed-message-exchange
下载插件的网址:https://www.rabbitmq.com/community-plugins.html
事务
该事务处理仅仅在java层面,生产者1发送消息,生产者2发送消息,保障其中有一个发送失败,都要失败,需要添加配置类:
@Configuration
@Data
public class RabbitConfig {@Beanpublic RabbitTransactionManager transactionManager(CachingConnectionFactory connectionFactory) {return new RabbitTransactionManager(connectionFactory);}@Beanpublic RabbitTemplate rabbitTemplate(CachingConnectionFactory connectionFactory) {RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);rabbitTemplate.setChannelTransacted(true);return rabbitTemplate;}
}
惰性队列
一般队列创建是默认,并不是惰性队列,惰性队列适用场景:在非常长的队列(百万条消息),生产者的速度超过消费者,消费者处理慢,使用惰性队列;它把消息放在队列中,并不是马上进行持久化操作,是在有空闲时,当队列达到百分之多少时,再进行数据持久化操作。
// x-queue-mode 参数,可在插件安装配置
@Queue(value = 队列名字, durable = "true", autoDelete = "false", arguments = {@Argument(name = "x-queue-mode", value = "lazy")
})
队列消息优先级
创建队列,如果这个值是0,代表优先级无效,设置的值优先级不能超过该值,优先级越高占用内存资源越多。
生产者配置
@Resource
private RabbitTemplate rabbitTemplate;// 生产者发送消息 1 - 优先级是1
rabbitTemplate.convertAndSend(EXCHANGE_PRIORITY, ROUTING_KEY_PRIORITY, "生产者发送消息 - 演示优先级:1", message -> {message.getMessageProperties().setPriority(1);return message;
});
// 生产者发送消息 2 - 优先级是2
rabbitTemplate.convertAndSend(EXCHANGE_PRIORITY, ROUTING_KEY_PRIORITY, "生产者发送消息 - 演示优先级:2", message -> {message.getMessageProperties().setPriority(2);return message;
});
// 生产者发送消息 3 - 优先级是3
rabbitTemplate.convertAndSend(EXCHANGE_PRIORITY, ROUTING_KEY_PRIORITY, "生产者发送消息 - 演示优先级:3", message -> {message.getMessageProperties().setPriority(3);return message;
});
// 生产者发送消息1、消息2、消息3的顺序(先进先出)
// 但消费者,消费优先消费:消息3、消息2、消息1 (改变了消费的顺序)
相关文章:

RabbitMQ(消息队列)
RabbitMQ 它是消息中间件,是在消息的传输过程中保存消息的容器,实现应用程序和应用程序之间通信的中间产品。目前主流消息队列通讯协议是AMQP(二进制传输,支持多种语言)、JMS(HTTP传输,只支持J…...

LeetCode-数组/回溯-No40组合总和II
题目: 给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中只能使用一次 。 注意:解集不能包含重复的组合。 示例 1: 输入: ca…...

直接调用 Java 线程的 run() 方法会发生什么?
文章目录 前言回顾run() 方法 vs start() 方法run()方法start()方法 直接调用 run() 方法的影响直接调用 run() 方法调用 start() 方法 示例解析结论个人简介 前言 在Java中,多线程编程是一个重要的概念,尤其是在处理并发任务时。线程是Java中实现多线程…...

计算机毕业设计Thinkphp/Laravel学生考勤管理系统zyoqy
管理员登录学生考勤管理系统后,可以对首页、个人中心、公告信息管理、年级管理、专业管理、班级管理、学生管理、教师管理、课程信息管理、学生选课管理、课程签到管理、请假申请管理、销假申请管理等功能进行相应操作,如图5-2所示。学生登录进入学生考勤…...

3浏览器安全
上一篇👉: 浏览器渲染原理 浏览器安全涉及多方面的威胁与防护,其中XSS(跨站脚本攻击)与CSRF(跨站请求伪造)是最常见的两类安全问题,而中间人攻击与网络劫持也是不容忽视的安全隐患。下面是对这…...

昇思25天学习打卡Day01
实验结果 心得体会 趁着假期,跟谁官方实战营开始系统学习MindSpore深度学习框架。昇思MindSpore是一个全场景深度学习框架,旨在实现易开发、高效执行、全场景统一部署三大目标。其中易开发表现为API友好,调试难度低;高效执行包括…...

Python-爬虫 下载天涯论坛帖子
为了爬取的高效性,实现的过程中我利用了python的threading模块,下面是threads.py模块,定义了下载解析页面的线程,下载图片的线程以及线程池 import threading import urllib2 import Queue import re thread_lock threading.RL…...

创建github个人博客
文章目录 安装Hexo安装git安装Node.js安装 Hexo git配置SSH key配置ssh 搭建个人博客新建博客生成静态网页 本文主要参考 【保姆级】利用Github搭建自己的个人博客,看完就会 安装Hexo 参考官方文档:https://hexo.io/zh-cn/docs/ Hexo 是一个快速、简洁且…...

【五子棋game】
编写一个五子棋游戏程序可以分为几个步骤:设计棋盘、定义规则、实现人机交互、判断胜负。下面是一个简化的五子棋游戏程序示例,使用Python语言编写。 首先,我们需要一个棋盘。可以使用一个二维数组来表示棋盘,其中0表示空位&#…...

从入门到精通:使用Python的Watchdog库监控文件系统的全面指南
从入门到精通:使用Python的Watchdog库监控文件系统的全面指南 引言Watchdog库概述核心组件工作原理 快速开始:设置Watchdog安装Watchdog创建一个简单的监控脚本设置和启动Observer 事件处理:如何响应文件系统的变化基本事件处理处理复杂的场景…...

Linux 进程管理指令
Linux 进程管理是系统管理的重要部分,通过各种工具和命令,你可以查看、控制、调试和管理进程。以下是一些常用的 Linux 进程管理命令和工具。 查看进程 1. ps ps 命令用于列出当前系统的进程。 查看当前用户的所有进程: ps -u $USER查看…...

Java OA系统通知公告模块
### 使用Spring Boot实现OA通知公告模块 使用Spring Boot框架实现一个支持多种形式公告发布、设置发布时间和有效期,以及公告发布后推送通知的模块。 #### 项目结构 结构组织项目: OA_Notification_Module/ ├── src/ │ ├── main/ │ │ …...

简约的服务器监控工具Ward
什么是 Ward ? Ward 是一个简单简约的服务器监控工具。 Ward 支持自适应设计系统。此外,它还支持深色主题。它仅显示主要信息,如果您想查看漂亮的仪表板而不是查看一堆数字和图表,则可以使用它。 Ward 在所有流行的操作系统上都能…...

新能源发电乙级资质所需办理标准
企业资历与信誉: 必须具有独立企业法人资格。社会信誉良好,注册资本不少于100万元人民币。 技术条件: 专业技术人员配置齐全、合理,数量需满足资质标准要求。主要技术负责人或总工程师应具有大学本科以上学历、10年以上设计经历&a…...

Elasticsearch:使用 Llamaindex 的 RAG 与 Elastic 和 Llama3
这篇文章是对之前的文章 “使用 Llama 3 开源和 Elastic 构建 RAG” 的一个补充。我们可以在本地部署 Elasticsearch,并进行展示。我们将一步一步地来进行配置并展示。你还可以参考我之前的另外一篇文章 “Elasticsearch:使用在本地计算机上运行的 LLM 以…...

AcWing算法基础课笔记——高斯消元
高斯消元 用来求解方程组 a 11 x 1 a 12 x 2 ⋯ a 1 n x n b 1 a 21 x 1 a 22 x 2 ⋯ a 2 n x n b 2 … a n 1 x 1 a n 2 x 2 ⋯ a n n x n b n a_{11} x_1 a_{12} x_2 \dots a_{1n} x_n b_1\\ a_{21} x_1 a_{22} x_2 \dots a_{2n} x_n b_2\\ \dots \\ a…...

【JavaScript脚本宇宙】图形魔术:探索领先的图像处理库及其独特功能
深入了解HTML5视频:最受欢迎的库及其功能 前言 图像处理是现代数字媒体开发中不可或缺的一部分,从调整图像大小到创建复杂的图形场景。有许多库可用,每个库都有其特定的优点和适用场景。在本文中,我们将探讨六种流行的图像处理库…...

Nemotron-4
Nemotron-4是英伟达(NVIDIA)发布的一系列高级人工智能模型,特别着重于大尺度语言模型(LLMs)的发展。这些模型在不同的参数量级上展现出了卓越的性能和效率,其中特别提到了150亿参数的Nemotron-4 15B和3400亿…...

【神经网络】神经元的基本结构和训练过程
🎈个人主页:豌豆射手^ 🎉欢迎 👍点赞✍评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步! 神经元的基本结构和训练过程 …...

第28课 绘制原理图——绘制导线
概述 放置完元器件之后,接着就要用导线将元器件的管脚一个一个连起来了。 绘制导线的方法 点击快速工具条上的“线”命令,进入绘制导线的过程。 点击选择某个管脚或电源端口,作为导线的起始端。 再点击选择另一个管脚或电源端口,…...

NLP 相关知识
NLP 相关知识 NLPLLMPrompt ChainingLangChain NLP NLP(Natuarl Language Processing)是人工智能的一个分支,中文名自然语言处理,专注于处理和理解人类使用的自然语言。它涵盖了多个子领域,如文本分类、情感分析、机器…...

Java中的设计模式:实战案例分享
Java中的设计模式:实战案例分享 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 设计模式是软件开发中的宝贵工具,它们为常见的问题提供…...

并发编程理论基础——合适的线程数量和安全的局部变量(十)
多线程的提升方向 主要方向在于优化算法和将硬件的性能发挥到极致想要发挥出更多的硬件性能,最主要的就是提升I/O的利用率和CPU的利用率以及综合利用率操作系统已经解决了磁盘和网卡的利用率问题,利用中断机制还能避免 CPU 轮询 I/O 状态,也提…...

Python使用抽象工厂模式和策略模式的组合实现生成指定长度的随机数
设计模式选择理由: 抽象工厂模式: 抽象工厂模式适合于创建一组相关或依赖对象的场景。在这里,我们可以定义一个抽象工厂来创建不同类型(数字、字母、特殊符号)的随机数据生成器。 策略模式: 策略模式允许你…...

python-17-零基础自学python-
学习内容:《python编程:从入门到实践》第二版 知识点: 类、子类、继承、调用函数 练习内容: 练习9-6:冰激凌小店 冰激凌小店是一种特殊的餐馆。编写一个名为IceCreamStand的类,让它继承为完成练习9-1或…...

Web应用和Tomcat的集成鉴权1-BasicAuthentication
作者:私语茶馆 1.Web应用与Tomcat的集成式鉴权 Web应用部署在Tomcat时,一般有三层鉴权: (1)操作系统鉴权 (2)Tomcat容器层鉴权 (3)应用层鉴权 操作系统层鉴权包括但不限于:Tomcat可以和Windows的域鉴权集成,这个适合企业级的统一管理。也可以在Tomcat和应用层独立…...

解决Linux下Java应用因内存不足而崩溃的问题
在Linux系统中运行内存密集型的Java应用时,经常会遇到因系统内存不足而导致应用崩溃的问题。本文将探讨如何诊断这类问题以及提供有效的解决方案。 问题诊断 首先,使用 free -h 命令查看系统的内存使用情况,得到以下输出: total…...

ardupilot开发 --- 视觉伺服 篇
风驰电掣云端飘,相机无法对上焦 1.视觉伺服分类2.视觉伺服中的坐标系3.成像模型推导4.IBVS理论推导5.IBVS面临的挑战6.visp 实践参考文献 1.视觉伺服分类 控制量是在图像空间中推导得到还是在欧式空间中推导得到,视觉伺服又可以分类为基于位置(PBVS)和基…...

KVM配置嵌套虚拟化
按照以下步骤启用、配置和开始使用嵌套虚拟化,默认情况下禁用该功能,要启用它,请在宿主机物理机上进行配置。在centos stream 9和ubuntu 22部署kvm默认支持虚拟机嵌套虚拟化。 1、英特尔 1.1检查嵌套虚拟化在您的主机系统上是否可用 $cat /sys/module/kvm_intel/paramete…...

Springboot应用的信创适配-补充
Springboot应用的信创适配-CSDN博客 因为篇幅限制,这里补全Spring信创适配、数据库信创适配、Redis信创适配、消息队列信创适配等四个章节。 Springboot应用的信创适配 Springboot应用的信创适配,如上图所示需要适配的很多,从硬件、操作系统、…...