RabbitMQ,想说爱你不容易(附详细安装教程),java开发实战经典课后答案


AMQP 全称是:Advanced Message Queuing Protocol。RabitMQ 最核心的协议就是基于 AMQP 模型的 AMQP 协议,AMQP 模型目前最新的版本是 1.0 版本,但是目前官方推荐使用者的最佳版本仍是基于 0.9.1 版本的 AMQP 模型,0.9.1 版本在 RabbitMQ官网中也将其称之为 AMQP 0-9-1模型。

AMQP 0-9-1(高级消息队列协议)是一种消息传递协议,它允许符合标准的客户端应用程序与符合标准的消息传递中间件代理进行通信。消息传递代理(Broker)从发布者(Publisher,即发布消息的应用程序,也称为生产者:Producter)接收消息,并将其路由到使用者(消费者:Consumer,即处理消息的应用程序)。

AMQP 0-9-1 模型的核心思想为:消息被发布到交换处,通常被比作邮局或邮箱。然后,交换机使用称为绑定的规则将消息副本分发到队列。然后,代理将消息传递给订阅了队列的使用者,或者使用者根据需要从队列中获取/提取消息。

下图就是一个 AMQP 模型简图,理解了这幅图,那么就基本理解了 RabbitMQ 的工作模式。

在这里插入图片描述

Producer 和 Consumer

Producer 即生产者,一般指的是应用程序客户端,生产者会产生消息发送给 RabbitMQ,等待消费者进行处理。

Consumer 即消费者,消费者会从特定的队列中取出消息,进行消费。当消息传递给消费者时,消费者会自动通知 BrokerBroker 只有在收到关于该消息的通知时才会从队列中完全删除该消息。

Connection:我是一个 TCP 长连接

生产者发送消息和消费者接收消息之前都必须要和 Broker 建立一个 tcp 长连接,才能进行通信。

Channel:我是被虚构出来的

消息队列的作用之一就是用来做削峰,所以消息队列在高并发场景可能会有大量的生产者和消费者,那么假如每一个生产者在发送消息时或者每一个消费者在消费消息时都需要不断的创建和销毁 tcp 连接,那么这对 Broker 会是一个很大的消耗,为了降低这个 tcp 连接的创建频率,AMQP 模型引入了 Channel(通道或者信道)。

Channel 是一个虚拟的的连接,可以被认为是“轻量级的连接,其共享同一个 tcp 连接”。在同一个 tcp 长连接里面可以通过创建和销毁不同的 Channel 来减少了创建和销毁 tcp 连接的频率,从而大大减少了资源的消耗。

客户端(生产者/消费者)执行的每个协议操作都发生在通道上。特定 Channel 上的通信完全独立于另一个 Channel 上的通信,因此每个协议方法还携带一个Channel ID(又称通道号)。

Channel 只存在于连接的上下文中,不会独立存在,所以当一个 tcp 连接被关闭时,其中所有 Channel 也都会被关闭。

Channel 是线程不安全的,所以对于使用多个线程/进程进行处理的应用程序,需要为每个线程/进程创建一个 Channel,而不是共享同一个 Channel

Broker:我只是一个普通的代理商

Broker 直接翻译成中文就是:中介/代理,所以如果我们使用的是 RabbitMQ,那么这个 Broker 就是指的 RabbitMQ 服务端。

Exchange:我只是做一个消息的映射

Echange 即交换机,因为要实现生产者和消费者的多对多关系,所以只有一个队列是无法满足要求的,那么如果有多个队列,每次我们发送的消息应该存储到哪里呢?交换机就是起到了中间角色的作用,我们发送消息到交换机上,然后通过交换机发送到对应的队列,交换机和队列之间需要提前绑定好对应关系,这样消息就到了各自指定的队列内,然后消费者就可以直接从各自负责的队列内取出消息进行消费。

Queue:我才是真正存储消息的地方

消息发送到 Broker 之后,通过交换机的映射,存储到指定的 Queue里面。

VHost:我只是一个命名空间而已

VHost 类似于命名空间,主要作用就是用来隔离数据的,比如我们由很多个业务系统都需要用到 RabbitMQ,如果是一台服务器完全可以满足要求,那就没必要安装多个 RabbitMQ 了,这时候就可以定义不同的 VHost ,不同的 VHost 就可以实现各个业务系统间的数据隔离。

RabbitMQ 的安装


RabbitMQ 是用 Erlang 语言开发的,所以在安装 RabbitMQ 之前,需要先安装 ErlangRabbitMQErlang 之间有版本对应关系,这个需要注意,本文以 Erlang 21.3RabbitMQ3.8.4 为例进行安装 。

  1. 安装 Erlang

yum -y install gcc glibc-devel make ncurses-devel openssl-devel xmlto perl wget //提前安装一些依赖,个人电脑依赖不同,可根据实际情况选择未安装的依赖进行安装

wget http://erlang.org/download/otp_src_21.3.tar.gz # 下载(也可以下载好传到服务器)

tar -xvf otp_src_21.3.tar.gz //解压

mkdir erlang //在指定目录,如/usr/local下创建erlang目录

cd otp_src_21.3 //切换到解压后的目录

./configure --prefix=/usr/local/erlang //编译(路径根据实际情况选择)

make && make install //安装

  1. 配置 Erlang 环境变量:

vim /etc/profile //编辑环境变量文件(CentOS系统默认环境变量文件,其他系统可能不一样)

export PATH=$PATH:/usr/local/erlang/bin //在末尾加入环境变量配置(路径根据实际情况选择)

source /etc/profile //实时生效

  1. 输入 erl 验证 Erlang 是否安装成功。如果出现如下显示版本号的界面则说明安装成功(可以输入 halt(). 命令进行退出):

在这里插入图片描述

  1. 安装 RabbitMQ

wget https://dl.bintray.com/rabbitmq/all/rabbitmq-server/3.8.4/rabbitmq-server-generic-unix-3.8.4.tar.xz //下载RabbitMQ

xz -d rabbitmq-server-generic-unix-3.8.4.tar.xz //解压

tar -xvf rabbitmq-server-generic-unix-3.8.4.tar //解压

  1. 同样的,这里需要进行环境变量配置:

vim /etc/profile //编辑环境变量文件(CentOS系统默认环境变量文件,其他

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

系统可能不一样)

export PATH=$PATH:/usr/local/rabbitmq_server-3.8.4/sbin //在末尾加入环境变量配置(路径根据实际情况选择)

source /etc/profile //实时生效

  1. 启动 RabbitMQ ,默认端口为 6752

/usr/local/rabbitmq_server-3.8.4/sbin/./rabbitmq-server -detached //在后台启动。根据自己实际路径选择,或者也可以选择service或者systemctl等命令启动

  1. 如果没有报错则说明启动成功,启动之后默认会创建一个 guest/guest 账户,只能本地连接,所以还需要再重新创建一个用户,并给新用户授权(当然,我们也可以直接给 guest 用户授权):

./rabbitmqctl add_user admin 123456 //创建用户admin

./rabbitmqctl set_user_tags admin administrator //添加标签

./rabbitmqctl set_permissions -p / admin “." ".” “.*” //授权

  1. RabbitMQ 默认还提供了可视化管理界面,需要手动开启一下,默认端口为 15672

./rabbitmq-plugins enable rabbitmq_management //启动后台管理系统插件(禁止的话换成disable即可)

  1. 开启插件之后,可以通过访问:http://ip:15672/ 访问后台管理系统,并进行一些参数设置,账号密码就是上面添加的 admin/123456

在这里插入图片描述

安装过程常见错误

安装过程中可能会出现如下图所示错误:

在这里插入图片描述

  1. odbc:ODBC library - link check failed:

解决方法:执行命令 yum install unixODBC.x86_64 unixODBC-devel.x86_64 进行安装。

  1. wx:wxWidgets not found, wx will NOT be usable:

解决方法:这个属于 APPLOICATION INFORMATION ,可以不处理。

  1. fakefop to generate placeholder PDF files,documentation: fop is missing.Using fakefop to generate placeholder PDF files:

解决方法:执行命令 yum install fop.noarch 进行安装。

利用 Java API 实现一个生产者和消费者


接下来用 Java 原生的 API 来实现一个简单的生产者和消费者:

  1. pom.xml 文件引入RabbitMQ 客户端依赖:

com.rabbitmq

amqp-client

5.6.0

  1. 新建一个消费者 TestRabbitConsumer 类:

package com.lonelyWolf.rabbitmq;

import com.rabbitmq.client.*;

import java.io.IOException;

public class TestRabbitConsumer {

public static void main(String[] args) throws Exception{

ConnectionFactory factory = new ConnectionFactory();

factory.setUri(“amqp://admin:123456@ip:5672”);

Connection conn = factory.newConnection();//建立连接

Channel channel = conn.createChannel(); //创建消息通道

channel.queueDeclare(“TEST_QUEUE”, false, false, false, null);//声明队列

System.out.println(“正在等待接收消息…”);

Consumer consumer = new DefaultConsumer(channel) {//创建消费者

@Override

public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,byte[] body) throws IOException {

System.out.println("收到消息: " + new String(body, “UTF-8”) + “,当前消息ID为:” + properties.getMessageId());

System.out.println(“收到自定义属性:”+ properties.getHeaders().get(“name”));

}

};

channel.basicConsume(“TEST_QUEUE”, true, consumer);//消费之后,回调给consumer

}

}

  1. 新建一个生产者 TestRabbitProducter类:

package com.lonelyWolf.rabbitmq;

import com.rabbitmq.client.AMQP;

import com.rabbitmq.client.Channel;

import com.rabbitmq.client.Connection;

import com.rabbitmq.client.ConnectionFactory;

import java.util.HashMap;

import java.util.Map;

import java.util.UUID;

public class TestRabbitProducter {

public static void main(String[] args) throws Exception {

ConnectionFactory factory = new ConnectionFactory();

factory.setUri(“amqp://admin:123456@ip:5672”);

Connection conn = factory.newConnection();// 建立连接

Channel channel = conn.createChannel();//创建消息通道

Map<String, Object> headers = new HashMap<String, Object>(1);

headers.put(“name”, “双子孤狼”);//可以自定义一些自定义的参数和消息一起发送过去

AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()

.contentEncoding(“UTF-8”) //编码

.headers(headers) //自定义的属性

.messageId(String.valueOf(UUID.randomUUID()))//消息id

.build();

String msg = “Hello, RabbitMQ”;//需要发送的消息

channel.queueDeclare(“TEST_QUEUE”, false, false, false, null); //声明队列

channel.basicPublish("", “TEST_QUEUE”, properties, msg.getBytes());//发送消息

channel.close();

conn.close();

}

}

  1. 先启动消费者,启动之后消费者就会保持和 RabbitMQ 的连接,等待消息;然后再运行生产者,消息发送之后,消费者就可以收到消息:

在这里插入图片描述

利用SpringBoot 实现一个生产者和消费者


接下来再看看 SpringBoot 怎么与 RabbitMQ 集成并实现一个简单的生产者和消费者:

  1. 引入依赖(我这边 SpringBoot 用的是 2.4.0 版本,所以如果用的低版本这个版本号也需要修改):

org.springframework.boot

spring-boot-starter-amqp

2.4.0

  1. 新增以下配置文件:

spring:

rabbitmq:

host: ip

port: 5672

username: admin

password: 123456

  1. 新建一个配置文件 RabbitConfig 类,创建一个队列:

package com.lonely.wolf.rabbit.config;

import org.springframework.amqp.core.Queue;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Configuration

public class RabbitConfig {

@Bean(“simpleRabbitQueue”)

public Queue getFirstQueue(){

Queue queue = new Queue(“SIMPLE_QUEUE”);

return queue;

}

}

  1. 新建一个消费者 SimpleConsumer 类(注意这里监听的名字要和上面定义的保持一致):

package com.lonely.wolf.rabbit.consumer;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;

import org.springframework.amqp.rabbit.annotation.RabbitListener;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值