中间件-------RabbitMQ

news2024/9/21 20:41:18

同步和异步

异步调用

MQ

MQ优势:①服务解耦   ②异步调用   ③流量削峰

结构

消息模型

 RabbitMQ入门案例,实现消息发送和消息接收

生产者:
public class PublisherTest {
    @Test
    public void testSendMessage() throws IOException, TimeoutException {
        // 1.建立连接
        ConnectionFactory factory = new ConnectionFactory();
        // 1.1.设置连接参数,分别是:主机名、端口号、vhost、用户名、密码
        factory.setHost("192.168.136.132");
        factory.setPort(5672);
        factory.setVirtualHost("/");
        factory.setUsername("itcast");
        factory.setPassword("123321");
        // 1.2.建立连接
        Connection connection = factory.newConnection();

        // 2.创建通道Channel
        Channel channel = connection.createChannel();

        // 3.创建队列
        String queueName = "simple.queue";
        channel.queueDeclare(queueName, false, false, false, null);

        // 4.发送消息
        String message = "hello, rabbitmq!";
        channel.basicPublish("", queueName, null, message.getBytes());
        System.out.println("发送消息成功:【" + message + "】");

        // 5.关闭通道和连接
        channel.close();
        connection.close();

    }
}
消费者:
public class ConsumerTest {

    public static void main(String[] args) throws IOException, TimeoutException {
        // 1.建立连接
        ConnectionFactory factory = new ConnectionFactory();
        // 1.1.设置连接参数,分别是:主机名、端口号、vhost、用户名、密码
        factory.setHost("192.168.136.132");
        factory.setPort(5672);
        factory.setVirtualHost("/");
        factory.setUsername("itcast");
        factory.setPassword("123321");
        // 1.2.建立连接
        Connection connection = factory.newConnection();

        // 2.创建通道Channel
        Channel channel = connection.createChannel();

        // 3.创建队列
        String queueName = "simple.queue";
        channel.queueDeclare(queueName, false, false, false, null);

        // 4.订阅消息
        channel.basicConsume(queueName, true, new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope,
                                       AMQP.BasicProperties properties, byte[] body) throws IOException {
                // 5.处理消息
                String message = new String(body);
                System.out.println("接收到消息:【" + message + "】");
            }
        });
        System.out.println("等待接收消息。。。。");
    }
}

SpringAMQP

引入依赖

        <!--AMQP依赖,包含RabbitMQ-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

普通队列 

 第一步:publisher服务配置文件,发消息

spring:
  rabbitmq:
    host: 192.168.136.132
    port: 5672
    username: itcast
    password: 123321
    virtual-host: /
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringAMQPTest {

    //获取RabbitTemplateAPI
    @Resource
    private RabbitTemplate rabbitTemplate;

    @Test
    public void test(){
        String queueName = "simple.queue";
        String message = "hello SpringAMQP";

        //使用API传入队列名和消息即可直接发送
        rabbitTemplate.convertAndSend(queueName,message);
    }

}

第二步:Consumer服务配置信息监听消息

spring:
  rabbitmq:
    host: 192.168.136.132
    port: 5672
    username: itcast
    password: 123321
    virtual-host: /
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

//定义一个监听类去监听消息
@Component
public class SpringRabbitListener {

    @RabbitListener(queues = "simple.queue")
    public void ListenSimpleQueue(String msg){
        System.out.println("msg = " + msg);
    }
}


Work Queue队列

多个消费者绑定到同一个队列,可以通过prefetch来控制消费者消息预取的数量

第一步: 生产者发送消息

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringAMQPTest {

    //获取RabbitTemplateAPI
    @Resource
    private RabbitTemplate rabbitTemplate;

    @Test
    public void test01() throws InterruptedException {
        String queueName = "simple.queue";
        String message = "hello SpringAMQP--";

        for (int i = 0; i < 50; i++) {
            //使用API传入队列名和消息即可直接发送
            rabbitTemplate.convertAndSend(queueName,message+i);
            Thread.sleep(20);
        }

    }

}

第二步:消费者设置多个监听消息

@Component
public class SpringRabbitListener {

    @RabbitListener(queues = "simple.queue")
    public void ListenWorkQueue(String msg) throws InterruptedException {
        System.out.println("消费者一接收到消息---- = " + msg + LocalDateTime.now());
        Thread.sleep(20);
    }

    @RabbitListener(queues = "simple.queue")
    public void ListenWorkQueue01(String msg) throws InterruptedException {
        System.out.println("消费者二接收到消息---- = " + msg + LocalDateTime.now());
        Thread.sleep(200);
    }
}

 第三步:消费者可通过prehtch设置消息预取数量

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


发布-订阅模型

Fanout广播交换机 --->多个队列收到交换机的消息

第一步:Consumer声明交换机,队列并进行绑定。
@Configuration
public class FanoutConfig {

    //声明交换机
    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange("itcast.fanout");
    }

    //声明队列1
    @Bean
    public Queue fanoutQueue1(){
        return new Queue("fanout.queue1");
    }
    //绑定队列1到交换机上
    @Bean
    public Binding fanoutBanding1(Queue fanoutQueue1,FanoutExchange fanoutExchange){
        return BindingBuilder
                .bind(fanoutQueue1)
                .to(fanoutExchange);
    }


    //声明队列2
    @Bean
    public Queue fanoutQueue2(){
        return new Queue("fanout.queue2");
    }
    //绑定队列2到交换机上
    @Bean
    public Binding fanoutBanding2(Queue fanoutQueue2,FanoutExchange fanoutExchange){
        return BindingBuilder
                .bind(fanoutQueue2)
                .to(fanoutExchange);
    }
}
 第二步:Consumer进行监听消息
@Component
public class SpringRabbitListener {
    @RabbitListener(queues = "fanout.queue1")
    public void ListenSimpleQueue1(String msg){
        System.out.println("消费者接收到fanout.queue1的消息 = " + msg);
    }

    @RabbitListener(queues = "fanout.queue2")
    public void ListenSimpleQueue2(String msg){
        System.out.println("消费者接收到fanout.queue2的消息 = " + msg);
    }
}
第三步:Publisher向交换机发送消息
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringAMQPTest {

    //获取RabbitTemplateAPI
    @Resource
    private RabbitTemplate rabbitTemplate;

    @Test
    public void testExchange() {
        //声明交换机名称
        String exchangeName = "itcast.fanout";
        //消息
        String message = "Hello Everyone";
        //发送消息
        rabbitTemplate.convertAndSend(exchangeName,"",message);
    }
}

Direct路由交换机 --->将消息发给指定key的队列

第一步:在Listener中声明队列,交换机以及key
@Component
public class SpringRabbitListener {
    //声明队列1,交换机以及队列1的bindingKey
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "derict.queue1"),
            exchange = @Exchange(name = "itcast.direct",type = ExchangeTypes.DIRECT),
            key = {"red","blue"}
    ))
    public void ListenDirectQueue1(String msg){
        System.out.println("消费者接收到direct.queue1的消息 = " + msg);
    }

    //声明队列2,交换机以及队列2的bindingKey
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "derict.queue2"),
            exchange = @Exchange(name = "itcast.direct",type = ExchangeTypes.DIRECT),
            key = {"red","yellow"}
    ))
    public void ListenDirectQueue2(String msg){
        System.out.println("消费者接收到direct.queue2的消息 = " + msg);
    }
}
第二步:向指定key的队列发送消息
    @Test
    public void testDirect() {
        //声明交换机名称
        String exchangeName = "itcast.direct";

        //消息
        String message = "Hello Blue!!";

        //发送消息,指定交换机,队列以及要发送的key
        rabbitTemplate.convertAndSend(exchangeName,"red",message);
    }

Topic主题交换机 ---->key必须是多个单词列表,统一主题,支持通配符

 第一步:在Listener中声明队列,交换机以及通配符key
@Component
public class SpringRabbitListener {

    //声明队列2的交换机,队列以及通配符key
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "topic.queue1"),
            exchange = @Exchange(name = "itcast.topic",type = ExchangeTypes.TOPIC),
            key = "china.#"
    ))
    public void ListenTopicQueue1(String msg){
        System.out.println("消费者接收到topic.queue1的消息 = " + msg);
    }
    //声明队列2的交换机,队列以及通配符key
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "topic.queue2"),
            exchange = @Exchange(name = "itcast.topic",type = ExchangeTypes.TOPIC),
            key = "#.news"
    ))
    public void ListenTopicQueue2(String msg){
        System.out.println("消费者接收到topic.queue2的消息 = " + msg);
    }

}
第二步:向主题通配符发送消息

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringAMQPTest {

    //获取RabbitTemplateAPI
    @Resource
    private RabbitTemplate rabbitTemplate;

    @Test
    public void testTopic() {
        //声明交换机名称
        String exchangeName = "itcast.topic";

        //消息
        String message = "Hello China!!";

        //发送消息
        rabbitTemplate.convertAndSend(exchangeName,"china.news",message);
    }
}

消息转换器

 RabbitMQ发的消息体都是Object类型,所有还可以发送对象数据。而且默认的消息转换器是MessageConverter实现的,当使用的是Map数据类型时,就会序列化成很多字节,所以推荐使用JSON的序列化和反序列化,直接修改默认的MessageConverter的类型

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
@Bean
    public MessageConverter messageConverter(){
        return  new Jackson2JsonMessageConverter();
    }

对于RabbitMQ高级部分:死信队列,延迟队列,发布确认,幂等性,优先,惰性队列等有时间再学

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

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

相关文章

【Visual Studio】没法进断点

文章目录 先看看文心一言给的回答 开发过程中&#xff0c;没法进断点的情况还是很少的&#xff08;指的是一直进不去的情况&#xff0c;热重载导致的都可以通过重启ide解决&#xff09;&#xff0c;但还是有极少数情况下会出现。 先看看文心一言给的回答 如果Visual Studio无…

2024年NGFW防火墙安全基准-防火墙安全功效竞争性评估实验室总结报告

Check Point 委托 Miercom 对 Check Point 下一代防火墙 (NGFW) 开展竞争性安全有效性测试&#xff0c; 选择的竞品分别来自 Cisco、Fortinet 和 Palo Alto Networks。对 Zscaler 的测试涉及他们的 SWG&#xff08;安全网关&#xff09;。测试内容包括验证防病毒、反恶意软件、…

文本处理工具grep及sed

文章目录 一、grep文本处理工具二、sed文本处理工具基本用法sed脚本格式搜索替代 一、grep文本处理工具 选项含义-color对匹配到的文本着色显示-m 次数匹配到规定的次数后停止-v显示不被命令匹配到的行,即取反-i忽略字符大小写-n显示匹配的行号-c统计匹配的行数-o仅显示匹配到…

乡村振兴的乡村文化传承与活化:活化乡村传统文化,传承乡村文化基因,打造具有文化魅力的美丽乡村

目录 一、引言 二、乡村文化的独特价值与现状 三、活化乡村传统文化的策略 1、挖掘乡村文化资源 2、创新文化表达方式 3、加强文化产业发展 四、传承乡村文化基因的途径 1、加强文化教育 2、培育文化人才 3、弘扬文化精神 五、打造具有文化魅力的美丽乡村 1、规划乡…

输入输出(1)——C++的输入输出概述

目录 一、C的输入输出 (一) C的输入输出 (二&#xff09;C语言的scanf和printf 二、C的输入输出流 (一) iostream类库中有关的类 (二&#xff09; iostream.h头文件的流对象和重载运算符 一、C的输入输出 (一) C的输入输出 之前用到的输入输出&#xff0c;都是以终端…

最近5星好评的华为的书《常变与长青》

常变与长青 (豆瓣) 作者简介 郭平&#xff0c;1988年加入华为&#xff0c;历任产品开发部项目经理、供应链总经理、总裁办主任、管理工程部总裁、企业发展部总裁、终端公司董事长兼总裁、公司轮值CEO、财经委员会主任、公司副董事长、轮值董事长等职务&#xff0c;现任公…

Science 基于尖峰时序编码的模拟神经触觉系统,可实现动态对象分类

快速处理和有效利用手与物体交互过程中产生的动态触觉信号&#xff08;例如触摸和抓握&#xff09;对于触觉探索和灵巧的物体操作至关重要。将电子皮肤&#xff08;e-skins&#xff09;推进到模仿自然触觉的水平&#xff0c;是恢复截肢者和瘫痪患者丧失的功能的可行解决方案&am…

IDE上传本地仓库到GitHub

IDE上传本地仓库到GitHub 1、选择远程仓库平台2、下载安装Git3、IDE集成Git4、本地项目上传GitHub 1、选择远程仓库平台 1.1、注册远程仓库平台 常见的远程仓库托管平台有&#xff1a; 1&#xff09;GitHub 域名&#xff1a;https://github.com 介绍&#xff1a;GitHub是全球最…

CAD二次开发(4)-编辑图形

工具类&#xff1a;EditEntityTool.cs using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Th…

等保2.0看这一篇就够了

一、等级保护介绍 1.1什么是等级保护 网络安全等级保护是指对国家重要信息、法人和其他组织及公民的专有信息以及信息和存储、传输、处理这些信息的信息系统分等级实行安全保护&#xff0c;对信息系统中使用的信息安全产品实行按等级管理&#xff0c;对信息系统中发生的信息安…

有人物联网4G模块【WH-LTE-7S1】超简单上云流程完整版~!(一)

目录 前言一、所需环境二、使用步骤1.官方资料包获取2.硬件连接3.云平台配置 四、结尾 前言 废话不多说直接上干货 一、所需环境 1、有人家的WH-LTE-7S1&#xff08;带配套底板&#xff09;。 2、串口工具&#xff08;TTL或USB485&#xff09;。二、使用步骤 1.官方资料包获…

颜色值进制转换

颜色值进制转换 专业的和非专业程序员在编程时都碰到过颜色值的表达式。特别是在编制网页和设计界面时&#xff0c;都要选择颜色。各语言的颜色值表达式就两种&#xff0c;十六进制的颜色值hex$和十进制的RGB格式。现成的调色板颜色表也是这两种格式。写代码时会遇到写颜色值码…

NVIDIA Jetson 上编译opencv 4.9.0

直接上命令 cmake .. \ -DCMAKE_C_COMPILER/usr/bin/gcc-7 -DCMAKE_CXX_COMPILER/usr/bin/g-7 \ -DCMAKE_BUILD_TYPERelease \ -DCMAKE_INSTALL_PREFIX/usr/local \ -DOPENCV_ENABLE_NONFREE1 \ -DBUILD_opencv_python21 \ -DBUILD_opencv_python31 \ -DCUDA_TOOLKIT_ROOT_DIR…

使用Django框架搭建Web应用

文章目录 简介安装Django创建一个Django项目创建一个Django应用编写视图配置URL运行开发服务器总结与拓展数据库集成管理后台表单处理模板引擎安全性 简介 Django 是一款基于 Python 语言的开源 Web 应用框架&#xff0c;采用了 MVC&#xff08;模型-视图-控制器&#xff09;设…

运筹说 第115期 | 排队论经典例题讲解

通过前几期的学习&#xff0c;我们已经学会了排队论的基本概念、生灭过程和Poisson过程&#xff0c;等待制排队模型、混合制排队模型、其他排队模型以及排队系统优的定义与相关求解方法。在实际工作中&#xff0c;我们能发现排队论在经济管理中有着许多应用&#xff0c;本期小编…

神经网络的工程基础(一)——利用PyTorch实现梯度下降法

相关说明 这篇文章的大部分内容参考自我的新书《解构大语言模型&#xff1a;从线性回归到通用人工智能》&#xff0c;欢迎有兴趣的读者多多支持。 本文涉及到的代码链接如下&#xff1a;regression2chatgpt/ch06_optimizer/gradient_descent.ipynb 本文将讨论利用PyTorch实现…

高斯过程学习笔记

目录 基础知识 例子 推荐 A Visual Exploration of Gaussian Processes (distill.pub) AB - Introduction to Gaussian Processes - Part I (bridg.land) 基础知识 高斯过程回归&#xff08;Gaussian Process Regression&#xff09; - 知乎 (zhihu.com) 高斯过程&#x…

VS2022上通过C++绘图库ROOT库绘制一个3D曲面图

ROOT库提供了强大的交互式图形功能。通过使用ROOT库的TCanvas和TApplication类&#xff0c;可以创建一个交互式的图形窗口&#xff0c;可以对图形进行缩放、平移、旋转等操作&#xff0c;并且可以通过鼠标和键盘与图形进行交互&#xff0c;这点实在是太厉害了&#xff0c;也就是…

贪心算法4(c++)

过河的最短时间 题目描述 输入 在漆黑的夜里&#xff0c;N位旅行者来到了一座狭窄而且没有护栏的桥边。如果不借助手电筒的话&#xff0c;大家是无论如何也不敢过桥去的。不幸的是&#xff0c;N个人一共只带了一只手电筒&#xff0c;而桥窄得只够让两个人同时过&#xff0c;如果…