RabbitM安装使用
前言
一、下载安装包
Rabbitmq下载地址
Rabbitmq,Erlang 对应版本查看地址
Erlang下载地址
一、安装Erlang
wget https://packages.erlang-solutions.com/erlang-solutions-2.0-1.noarch.rpm
rpm -Uvh erlang-solutions-2.0-1.noarch.rpm
udo yum install -y erlang
erl -v //查看版本
二、安装rabbitmq-server
//1安装
rpm -ivh rabbitmq-server-3.8.14-1.el7.noarch.rpm
//2 在etc/rabbitmq下新建文件 rabbitmq-env.conf 内容为 NODENAME=rabbit@localhost
//3启动服务
systemctl start rabbitmq-server
//4查看状态
systemctl status rabbitmq-server
//5web视图控制台
rabbitmq-plugins enable rabbitmq_management
//重启服务
systemctl restart rabbitmq-server
//停止服务
systemctl stop rabbitmq-server
//为RabbitMQ Web管理控制台创建管理用户
rabbitmqctl add_user admin 1234qwer
rabbitmqctl set_user_tags admin administrator
rabbitmqctl set_permissions -p / username ".*" ".*" ".*"
访问控制台
http://Your_Server_IP:15672/
三、卸载Rabbitmq 、Erlang
rabbitmq是运行在erlang环境下的,所以卸载时应将erlang卸载。
1、卸载rabbitmq相关
卸载前先停掉rabbitmq服务,执行命令
service rabbitmq-server stop
查看rabbitmq安装的相关列表
yum list | grep rabbitmq
卸载rabbitmq已安装的相关内容
yum -y remove rabbitmq-server.noarch
2、卸载erlang
查看erlang安装的相关列表
yum list | grep erlang
卸载erlang已安装的相关内容
yum -y remove erlang-*
yum remove erlang.x86_64
卸载完之后就可以重新安装了
四、工作模式
五、springboot整合RabbitMq
(一)引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
(二)Direct:新建DirectRabbitConfig
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DirectRabbitConfig {
public final static String QUEUE2ORDER = "order.queue2Order";
public final static String QUEUE2WAREHOUSE = "order.queue2Warehouse";
public final static String QUEUE2SMS = "QUEUE2SMS";
public final static String QUEUE2EMAIL = "QUEUE2EMAIL";
public final static String EXCHANGE = "direct_change_" + QUEUE2ORDER;
public final static String ORDER2MESSAGE = "order2Message";
/**
* 创建交换机
*
* @return
*/
@Bean("exchange")
DirectExchange exchange() {
// return new DirectExchange(EXCHANGE, true, false);
return ExchangeBuilder.directExchange(EXCHANGE).autoDelete().durable(true).build();
}
@Bean("exchangeFanoutMessage")
FanoutExchange exchangeFanoutMessage() {
// return new DirectExchange(EXCHANGE, true, false);
return ExchangeBuilder.fanoutExchange(ORDER2MESSAGE).durable(true).build();
}
/**
* 队列 起名
*
* @return
*/
@Bean("queue2Order")
public Queue queue2Order() {
return new Queue(QUEUE2ORDER, true);
}
@Bean("queue2Warehouse")
public Queue queue2Warehouse() {
return new Queue(QUEUE2WAREHOUSE, true);
}
/**
* rediect 将队列和交换机绑定, 并设置用于匹配键
* routingKey 可以理解成队列名称
*
* @return
*/
@Bean
Binding bindingDirect2Order(@Qualifier("exchange") DirectExchange directExchange, @Qualifier("queue2Order") Queue queue) {
return BindingBuilder.bind(queue).to(directExchange).with("queue2Order");
}
@Bean
Binding bindingDirect2Ware(@Qualifier("exchange") DirectExchange directExchange, @Qualifier("queue2Warehouse") Queue queue) {
return BindingBuilder.bind(queue).to(directExchange).with("queue2Warehouse");
}
/**
* Fanout 模型
*
* @return
*/
@Bean("queue2sms")
public Queue queue2sms() {
return new Queue(QUEUE2SMS, true);
}
@Bean("queue2email")
public Queue queue2email() {
return new Queue(QUEUE2EMAIL, true);
}
@Bean
Binding bindingEmail(@Qualifier("exchangeFanoutMessage") FanoutExchange exchange, @Qualifier("queue2sms") Queue queue) {
return BindingBuilder.bind(queue).to(exchange);
}
@Bean
Binding bindingSms(@Qualifier("exchangeFanoutMessage") FanoutExchange exchange, @Qualifier("queue2email") Queue queue) {
return BindingBuilder.bind(queue).to(exchange);
}
}
(三)Direct:新建product
import com.alibaba.fastjson.JSONObject;
import com.yang.common.mq.MessagePojo;
import com.yang.yimall.yimallauthserver.rabbitmq.DirectRabbitConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @ClassName ProcedureService
* @Description
* @Author 狗蛋儿
* @Date 2021/4/28 15:26
* @Version V1.0
**/
@Component
@Slf4j
public class ProcedureService {
@Autowired
RabbitTemplate rabbitTemplate; //使用RabbitTemplate,这提供了接收/发送等等方法
public String sendMessage(final MessagePojo msg) {
log.info("RabbitMq发送消息:{}", JSONObject.toJSONString(msg), msg);
rabbitTemplate.convertAndSend(DirectRabbitConfig.EXCHANGE, DirectRabbitConfig.QUEUE2ORDER, msg);
return "ok";
}
public String sendMessage(final MessagePojo msg,String routingKey) {
log.info("RabbitMq发送消息:{}", JSONObject.toJSONString(msg), msg);
rabbitTemplate.convertAndSend(DirectRabbitConfig.EXCHANGE, routingKey, msg);
return "ok";
}
public String sendMessage2(final MessagePojo msg) {
log.info("RabbitMq发送消息:{}", JSONObject.toJSONString(msg), msg);
rabbitTemplate.convertAndSend(DirectRabbitConfig.ORDER2MESSAGE,"", msg);
return "ok";
}
}
controller 模拟发送消息:
import com.yang.common.mq.MessagePojo;
import com.yang.common.mq.MsgTagEnum;
import com.yang.yimall.yimallauthserver.rabbitmq.product.ProcedureService;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@AllArgsConstructor
@RestController
public class SendMessageController {
private ProcedureService procedureService;
@GetMapping("/sendDirectMessage")
public String sendDirectMessage() {
for (int i = 0; i < 5; i++) {
MessagePojo<String> message = new MessagePojo<>();
message.setTag(MsgTagEnum.MESSAGE_ONE);
// 必须要设置这个userId,不然新零售会拿不到信息
message.setMessageData("测试--" + i);
procedureService.sendMessage(message);
}
return "ok";
}
}
(四)Direct:新建consumer
import com.yang.common.mq.MessagePojo;
import com.yang.yimall.yimallauthservertwo.rabbitmq.DirectRabbitConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class DirectReceiver {
@RabbitListener(queues = DirectRabbitConfig.QUEUE2ORDER)//监听的队列名称
public void process(final MessagePojo messagePojo) {
System.out.println("DirectReceiver---消费者0收到消息 : " + messagePojo.toString());
}
@RabbitListener(queues = DirectRabbitConfig.QUEUE2WAREHOUSE)//监听的队列名称
public void process1(final MessagePojo messagePojo) {
System.out.println("DirectReceiver---消费者1收到消息 : " + messagePojo.toString());
}
@RabbitListener(queues = DirectRabbitConfig.QUEUE2SMS)//监听的队列名称
public void process2(final MessagePojo messagePojo) {
System.out.println("消费者2收到消息 email: " + messagePojo.toString());
}
@RabbitListener(queues = DirectRabbitConfig.QUEUE2EMAIL)//监听的队列名称
public void process3(final MessagePojo messagePojo) {
System.out.println(" 消费者3收到消息 sms: " + messagePojo.toString());
}
}
六种模式:
生产者:
@SpringBootTest(classes = YimallAuthServerApplication.class)
@RunWith(SpringRunner.class)
public class TestRabbitMq {
@Autowired
private RabbitTemplate rabbitTemplate; //使用RabbitTemplate,这提供了接收/发送等等方法
//Topic 动态路由,订阅模式
@Test
public void sendTopic() {
rabbitTemplate.convertAndSend("topics", "order", "发送user.save的路由信息");
}
//Route 路由模式
@Test
public void sendRoute() {
rabbitTemplate.convertAndSend("directs", "error", "发送 info key的路由信息");
}
//广播
@Test
public void sendFanout() {
rabbitTemplate.convertAndSend("log", "", "fanout类型消息");
}
//Work
@Test
public void testWork() {
for (int i = 0; i < 20; i++) {
rabbitTemplate.convertAndSend("", "work", "这是work模型" + i);
}
}
@Test
public void sendMessage() {
rabbitTemplate.convertAndSend("", "hello", "hello,这是第一种模式");
}
}
模式一消费者:
@Component
public class HelloConsumer {
//默认独占 持久化,不是自动删除
@RabbitListener(queuesToDeclare = @Queue("hello"))
public void process(final String messagePojo) {
System.out.println("DirectReceiver---消费者1收到消息 : " + messagePojo);
}
}
模式二 work 消费者:
@Component
public class WorkConsumer {
//默认独占 持久化,不是自动删除
@RabbitListener(queuesToDeclare = @Queue("work"))
public void process1(final String messagePojo) {
System.out.println("Consumer---消费者1收到消息 : " + messagePojo);
}
@RabbitListener(queuesToDeclare = @Queue("work"))
public void process2(final String messagePojo) {
System.out.println("Consumer---消费者2收到消息 : " + messagePojo);
}
@RabbitListener(queuesToDeclare = @Queue("work"))
public void process3(final String messagePojo) {
System.out.println("Consumer---消费者3收到消息 : " + messagePojo);
}
}
模式三 fanout 消费者:
@Component
public class FanoutConsumer {
@RabbitListener(bindings = @QueueBinding(
value = @Queue,//生产临时队列
exchange = @Exchange(value = "log", type = "fanout")
))
public void process1(final String messagePojo) {
System.out.println("Consumer---消费者1收到消息 : " + messagePojo);
}
@RabbitListener(bindings = @QueueBinding(
value = @Queue,//生产临时队列
exchange = @Exchange(value = "log", type = "fanout")
))
public void process2(final String messagePojo) {
System.out.println("Consumer---消费者2收到消息 : " + messagePojo);
}
@RabbitListener(bindings = @QueueBinding(
value = @Queue,//生产临时队列
exchange = @Exchange(value = "log", type = "fanout")
))
public void process3(final String messagePojo) {
System.out.println("Consumer---消费者3收到消息 : " + messagePojo);
}
}
模式四 route 消费者:
@Component
public class RouteConsumer {
@RabbitListener(bindings = @QueueBinding(
value = @Queue,//生产临时队列
exchange = @Exchange(value = "directs", type = "direct"),
key = {"info","warn","error"}
))
public void process1(final String messagePojo) {
System.out.println("Consumer---消费者1收到消息 : " + messagePojo);
}
@RabbitListener(bindings = @QueueBinding(
value = @Queue,//生产临时队列
exchange = @Exchange(value = "directs", type = "direct"),
key = {"warn","error"}
))
public void process2(final String messagePojo) {
System.out.println("Consumer---消费者2收到消息 : " + messagePojo);
}
}
模式五 Topic 消费者:
@Component
public class TopicConsumer {
@RabbitListener(bindings = @QueueBinding(
value = @Queue,//生产临时队列
exchange = @Exchange(name = "topics", type = "topic"),
key = {"user.save.*", "user.save"}
))
public void process1(final String messagePojo) {
System.out.println("Consumer---消费者1收到消息 : " + messagePojo);
}
@RabbitListener(bindings = @QueueBinding(
value = @Queue,//生产临时队列
exchange = @Exchange(value = "topics", type = "topic"),
key = {"order.#", "product.#", "user.save"}
))
public void process2(final String messagePojo) {
System.out.println("Consumer---消费者2收到消息 : " + messagePojo);
}
}
七、消息丢失
记录表:
八、消息可靠性 加锁,幂等性,消息自带是否重发字段
九、消息积压
十、插件延迟队列
下载对应版本 放在 路径/usr/lib/rabbitmq/lib/rabbitmq_server-3.8.14/plugins/ 下
//执行
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
//重启mq
systemctl restart rabbitmq-server