目录
优点
缺点

优点
缺点
MQ即是事件驱动架构中的Broker。
直接docker拉一个:
# 拉取镜像
docker pull rabbitmq:3-management
#启动容器
docker run \
-e RABBITMQ_DEFAULT_USER=root \
-e RABBITMQ_DEFAULT_PASS=123456 \
--name mq \
--hostname mq1 \
-p 15672:15672 \
-p 5672:5672 \
-d \
rabbitmq:3-management
# 15672是管理口

几个概念:

依赖
<!--AMQP依赖,包含RabbitMQ-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
amqp是高级消息队列协议,springAMQP则是一种实现。
配置
spring:
rabbitmq:
host: 190.92.246.107 # 主机名
port: 5672 # 端口
virtual-host: / # 虚拟主机
username: root
password: 123456
实现
发布者
public class PublisherTest {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void testSimpleQueue() {
String queueName = "simple.queue";
String message = "hello, spring amqp";
rabbitTemplate.convertAndSend(queueName, message);
}
}
消费者
配置都是一样的
@Component
public class SpringRabbitListener {
@RabbitListener(queues = {"simple.queue"})
public void listenSimpleQueue(String msg) {
System.out.println(msg);
}
}
启动main函数,成功:


两个消费者合作处理消息,避免消息堆积。
AMQP有一个消息预取机制,预取多少条消息是可以配置的。
spring:
rabbitmq:
host: 190.92.246.107 # 主机名
port: 5672 # 端口
virtual-host: / # 虚拟主机
username: root
password: 123456
listener:
simple:
prefetch: 1
发布者:
@Test
public void testSimpleQueue() throws InterruptedException {
String queueName = "simple.queue";
String message = "hello, spring amqp";
for (int i = 0; i < 50; i++) {
rabbitTemplate.convertAndSend(queueName, message + i);
Thread.sleep(20);
}
}
消费者
@Component
public class SpringRabbitListener {
@RabbitListener(queues = {"simple.queue"})
public void listenSimpleQueue1(String msg) throws InterruptedException {
System.out.println("消费者1" + "【" + msg + "】" + LocalTime.now());
Thread.sleep(20);
}
@RabbitListener(queues = {"simple.queue"})
public void listenSimpleQueue2(String msg) throws InterruptedException {
System.err.println("消费者2" + "【" + msg + "】" + LocalTime.now());
Thread.sleep(200);
}
}
如果消息预取机制不设置,意味着不设限,那么在这个例子中每个消费者无论处理能力如何,都会处理25条消息,设置为1后,则按照能力分配。
和之前不同的是,可以将一条消息发送给多个消费者,实现方式是加入了交换机。
根据交换机类型不同分为三种:广播、路由和主题
Fanout Exchange 广播
这个交换机会将消息路由到每一个和它绑定的队列

发布者
不同的是,我们发送消息到交换机
@Test
public void testSendFanoutExchange() {
String exchangeName = "root.fanout";
String message = "hello everyone";
rabbitTemplate.convertAndSend(exchangeName, "", message);
}
订阅者
首先创建交换机和队列,并将队列绑定到交换机上(有注解的写法,像后文路由模式那样)
@Configuration
public class FanoutConfig {
@Bean
public FanoutExchange fanoutExchange() {
return new FanoutExchange("root.fanout");
}
@Bean
public Queue fanoutQueue1() {
return new Queue("fanout.queue1");
}
@Bean
public Queue fanoutQueue2() {
return new Queue("fanout.queue2");
}
@Bean
public Binding bindQueue1(Queue fanoutQueue1, FanoutExchange fanoutExchange) {
return BindingBuilder.bind(fanoutQueue1).to(fanoutExchange);
}
@Bean
public Binding bindQueue2(Queue fanoutQueue2, FanoutExchange fanoutExchange) {
return BindingBuilder.bind(fanoutQueue2).to(fanoutExchange);
}
}
然后监听队列:
@RabbitListener(queues = {"fanout.queue1"})
public void listenFanoutQueue1(String msg) throws InterruptedException {
System.out.println("fanout.queue1消费者" + "【" + msg + "】" + LocalTime.now());
}
@RabbitListener(queues = {"fanout.queue2"})
public void listenFanoutQueue2(String msg) throws InterruptedException {
System.err.println("fanout.queue2消费者" + "【" + msg + "】" + LocalTime.now());
}
启动测试:

Direct Exchange 路由

特点:
接下来就可以测试一下:
有一个交换机,两个队列,两个消费者分别有两个BindingKey。
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "direct.queue1"),
exchange = @Exchange(name = "root.direct", type = ExchangeTypes.DIRECT),
key = {
"blue",
"red"
}
))
public void listenDirectQueue1(String msg) {
System.err.println("direct.queue1消费者" + "【" + msg + "】" + LocalTime.now());
}
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "direct.queue2"),
exchange = @Exchange(name = "root.direct", type = ExchangeTypes.DIRECT),
key = {
"yellow",
"red"
}
))
public void listenDirectQueue2(String msg) {
System.err.println("direct.queue2消费者" + "【" + msg + "】" + LocalTime.now());
}
发布者:
@Test
public void testSendDirectExchange() {
String exchangeName = "root.direct";
String message = "hello red";
rabbitTemplate.convertAndSend(exchangeName, "red", message);
}
不断更换routingKey,观察订阅者日志。
Topic Exchange 主题

和路由模式类似,区别是这个模式的key是多个单词的列表,以 “ . ” 分割。
在指定BIndingKey时可以使用通配符。例如:#代表0个或多个单词,*代表一个单词。
订阅
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "topic.queue1"),
exchange = @Exchange(name = "root.topic", type = ExchangeTypes.TOPIC),
key = {
"china.#"
}
))
public void listenTopicQueue1(String msg) {
System.err.println("topic.queue1消费者" + "【" + msg + "】" + LocalTime.now());
}
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "topic.queue2"),
exchange = @Exchange(name = "root.topic", type = ExchangeTypes.TOPIC),
key = {
"#.news"
}
))
public void listenTopicQueue2(String msg) {
System.err.println("topic.queue2消费者" + "【" + msg + "】" + LocalTime.now());
}
发布
@Test
public void testSendTopicExchange() {
String exchangeName = "root.topic";
String message = "hello world";
rabbitTemplate.convertAndSend(exchangeName, "china.news", message);
}
改变routingkey,观察日志。
我们不仅仅可以发送字符串消息,还可以发送对象,默认情况下,需要传统的序列化方式,对象需要实现Serializable接口,不太方便,我们使用json。
引入依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
自定义MessageConverter
@Bean
public MessageConverter messageConverter() {
return new Jackson2JsonMessageConverter();
}
这个时候发送的消息就会经过json序列化了。
测试
创建队列
@Bean
public Queue fanoutExchange() {
return new Queue("object.queue");
}
消费者(需要像发布者一样的,引入jackson,然后定义messageConverter)
@RabbitListener(queues = "object.queue")
public void listenObjectQueue(Map<String, Object> msg) {
System.err.println("object.queue消费者" + "【" + msg.get("name") + "】" + LocalTime.now());
System.err.println("object.queue消费者" + "【" + msg.get("date") + "】" + LocalTime.now());
}
发布消息
@Test
public void testSendObj() {
String queue = "object.queue";
Map<String, Object> msg = new HashMap<>();
msg.put("name", "root");
msg.put("date", new Date());
rabbitTemplate.convertAndSend(queue, msg);
}
成功:

目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c
TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是
目录SpringBootStarter是什么?以前传统的做法使用SpringBootStarter之后starter的理念:starter的实现: 创建SpringBootStarter步骤在idea新建一个starter项目、直接执行下一步即可生成项目。 在xml中加入如下配置文件:创建proterties类来保存配置信息创建业务类:创建AutoConfiguration测试如下:SpringBootStarter是什么? SpringBootStarter是在SpringBoot组件中被提出来的一种概念、简化了很多烦琐的配置、通过引入各种SpringBootStarter包可以快速搭建出一
TCP是面向连接的协议,连接的建立和释放是每一次面向连接的通信中必不可少的过程。TCP连接的管理就是使连接的建立和释放都能正常地进行。三次握手TCP连接的建立—三次握手建立TCP连接①若主机A中运行了一个客户进程,当它需要主机B的服务时,就发起TCP连接请求,并在所发送的分段中用SYN=1表示连接请求,并产生一个随机发送序号x,如果连接成功,A将以x作为其发送序号的初始值:seq=x。主机B收到A的连接请求报文,就完成了第一次握手。客户端发送SYN=1表示连接请求客户端发送一个随机发送序号x,如果连接成功,A将以x作为其发送序号的初始值:seq=x②主机B如果同意建立连接,则向主机A发送确认报
VXLAN简介定义RFC定义了VLAN扩展方案VXLAN(VirtualeXtensibleLocalAreaNetwork,虚拟扩展局域网)。VXLAN采用MACinUDP(UserDatagramProtocol)封装方式,是NVO3(NetworkVirtualizationoverLayer3)中的一种网络虚拟化技术。目的随着网络技术的发展,云计算凭借其在系统利用率高、人力/管理成本低、灵活性/可扩展性强等方面表现出的优势,已经成为目前企业IT建设的新趋势。而服务器虚拟化作为云计算的核心技术之一,得到了越来越多的应用。服务器虚拟化技术的广泛部署,极大地增加了数据中心的计算密度;同时,为
目录一、原理部分1、什么是串行通信(1)并行通信与串行通信(2)串行通信的制式(3)串行通信的主要方式 2、配置串口(1)SCON和PCON:串行口1的控制寄存器(2)SBUF:串行口数据缓冲寄存器 (3)AUXR:辅助寄存器编辑(4)ES、PS:与串行口1中断相关的寄存器(5)波特率设置 3、串口框架编写二、程序案例一、原理部分1、什么是串行通信(1)并行通信与串行通信微控制器与外部设备的数据通信,根据连线结构和传送方式的不同,可以分为两种:并行通信和串行通信。并行通信:数据的各位同时发送与接收,每个数据位使用一条导线,这种方式传输快,但是需要多条导线进行信号传输。串行通信:数据一位一
📝学技术、更要掌握学习的方法,一起学习,让进步发生👩🏻作者:一只IT攻城狮。💐学习建议:1、养成习惯,学习java的任何一个技术,都可以先去官网先看看,更准确、更专业。💐学习建议:2、然后记住每个技术最关键的特性(通常一句话或者几个字),从主线入手,由浅入深学习。❤️《SpringCloud入门实战系列》解锁SpringCloud主流组件入门应用及关键特性。带你了解SpringCloud主流组件,是如何一战解决微服务诸多难题的。项目demo:源码地址👉🏻SpringCloud入门实战系列不迷路👈🏻:SpringCloud入门实战(一)什么是SpringCloud?SpringCloud入门实战
这篇文章,主要介绍如何使用SpringCloud微服务组件从0到1搭建一个微服务工程。目录一、从0到1搭建微服务工程1.1、基础环境说明(1)使用组件(2)微服务依赖1.2、搭建注册中心(1)引入依赖(2)配置文件(3)启动类1.3、搭建配置中心(1)引入依赖(2)配置文件(3)启动类1.4、搭建API网关(1)引入依赖(2)配置文件(3)启动类1.5、搭建服务提供者(1)引入依赖(2)配置文件(3)启动类1.6、搭建服务消费者(1)引入依赖(2)配置文件(3)启动类1.7、运行测试一、从0到1搭建微服务工程1.1、基础环境说明(1)使用组件这里主要是使用的SpringCloudNetflix
绝对详细的RabbitMQ实践操作手册,看完本系列就够了。一、什么是MQ?1、MQ的概念2、理解消息队列二、MQ的优势和劣势1、优势和作用2、劣势三、MQ的应用场景四、AMQP五、工作原理一、什么是MQ?1、MQ的概念MQ全称MessageQueue(消息队列),是在消息的传输过程中保存消息的容器。多用于系统之间的异步通信。下面用图来理解异步通信,并阐明与同步通信的区别。同步通信:甲乙两人面对面交流,你一句我一句必须同步进行,两人除此之外不做任何事情异步通信:异步通信相当于通过第三方转述对话,可能有消息的延迟,但不需要二人时刻保持联系,消息传给第三方后,两人可以做其他自己想做的事情,当需要获取