RabbitMQ

Linux搭建RabbitMQ

1.RabbitMQ是由erlang语言编写的,导入RabbitMQ之前需要导入erlang和socat依赖
三个文件如图
在这里插入图片描述
2.使用工具将这三个导入系统,放在/home下,进入/home,报错点我

rpm -ivh erlang-22.0.7-1.el7.x86_64.rpm
rpm -ivh socat-1.7.3.2-2.el7.x86_64.rpm
rpm -ivh rabbitmq-server-3.7.18-1.el7.noarch.rpm

3.rabbitmq默认会读取ls /etc/rabbitmq/下的rabbitmq.config文件,但是一开始是没有的,寻找一下

[root@localhost home]# find / -name rabbitmq.config.example
/usr/share/doc/rabbitmq-server-3.7.18/rabbitmq.config.example

4.得到路径后copy过来到/etc/rabbitmq下

cp /usr/share/doc/rabbitmq-server-3.7.18/rabbitmq.config.example /etc/rabbitmq/rabbitmq.config

5.vim /etc/rabbitmq/rabbitmq.config
修改一下配置文件打开注释,允许来宾用户,别忘了删除后面的逗号
在这里插入图片描述
6.启动rabbitmq的插件管理

rabbitmq-plugins enable rabbitmq_management

7.查看一下状态

 systemctl status rabbitmq-server

8启动

systemctl restart rabbitmq-server

9.访问一下

http://192.168.200.130:15672

10.账号:guest
密码:guest
在这里插入图片描述
10.配置完成

初识mq—hello例子(点对点消费,直连)

在这里插入图片描述

生产者

package helloword;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.junit.Test;

import java.io.IOException;

public class Send {
    @Test
    public void getConnection() throws IOException {
        //创建连接mq的连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //设置连接地址
        connectionFactory.setHost("192.168.200.130");
        //设置端口号
        connectionFactory.setPort(5672);
        //设置连接哪个虚拟主机
        connectionFactory.setVirtualHost("/ems");
        //设置账号
        connectionFactory.setUsername("ems");
        //设置密码
        connectionFactory.setPassword("renliwei1");

        //构建链接
        Connection connection = connectionFactory.newConnection();

        //获取链接中的通道
        Channel channel = connection.createChannel();

        /**
         * 通道绑定对应消息队列
         * 参数1:队列名称,如果队列不存在就自动创建
         * 参数2:用来定义队列特性是否需要持久化 true持久化队列  false不持久化
         * 参数3:exclusive是否独占队列 true独占队列 false不独占
         * 参数4:autoDelete 是否在消费完成后自动删除队列 true自动删除 false不自动删除
         * 参数5:附加参数
         */
        channel.queueDeclare("hello",false,false,false,null);

        //发布消息
        /**
         * 参数一:交换机名称
         * 参数二:队列名称
         * 参数三:传递消息额外名称
         * 参数四:消息的具体内容
         */
        channel.basicPublish("","hello",null,"hellorebbit".getBytes());

        //关闭通道
        channel.close();
        connection.close();
    }
}

消费者

package helloword;

import com.rabbitmq.client.*;

import java.io.IOException;

public class Customer {
    public static void main(String[] args) throws IOException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.200.130");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/ems");
        connectionFactory.setUsername("ems");
        connectionFactory.setPassword("renliwei1");

        //构建链接
        Connection connection = connectionFactory.newConnection();

        //获取通道
        Channel channel = connection.createChannel();

        //通道绑定对象
        channel.queueDeclare("hello",false,false,false,null);

        //消费消息
        //参数1:消费哪个队列的消息,队列名称
        //参数2:开始消息的自动确认机制
        //参数3:消费时的回调接口
        channel.basicConsume("hello",true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("body:"+new String(body));
            }
        });
//        channel.close();
//        connection.close();
    }
}

封装了一个工具类
省去重复的编写代码,构建连接直接调用工具类即可

package utils;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;

public class RabbitMQUtils {
    private static ConnectionFactory connectionFactory;
    static{
        //创建连接mq的连接工厂,让他只new一次,类加载的时候初始化   静态代码块儿类加载的时候执行且只执行一次
        connectionFactory = new ConnectionFactory();
        //设置连接地址
        connectionFactory.setHost("192.168.200.130");
        //设置端口号
        connectionFactory.setPort(5672);
        //设置连接哪个虚拟主机
        connectionFactory.setVirtualHost("/ems");
        //设置账号
        connectionFactory.setUsername("ems");
        //设置密码
        connectionFactory.setPassword("renliwei1");
    }
    public static Connection getConnection(){
        try {
            //构建链接
            return connectionFactory.newConnection();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static void getSendAndCustomerClose(Channel channel,Connection connection){
        try {
           if (channel!=null)channel.close();
           if (connection!=null)connection.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

RabbitMQ持久化操作

在我们上面的例子中,当出现没有被消费的消息时,这时候突发意外情况,假如mq宕机了,这时候mq中的消息就会丢失,那么怎么来避免呢?
在这里插入图片描述
尝试一下
发送完消息
在这里插入图片描述
重启mq
在这里插入图片描述
刷新页面后发现消息并没有丢失
在这里插入图片描述

RabbitMQ消费者使用过后删除队列
在这里插入图片描述

Work模型

一个生产者直接对应多个消费者
在这里插入图片描述
在这里插入图片描述
生产者

package workQueue;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import utils.RabbitMQUtils;

import java.io.IOException;

public class Provider {
    public static void main(String[] args) throws IOException {
        //建立连接
        Connection connection = RabbitMQUtils.getConnection();
        //得到通道
        Channel channel = connection.createChannel();
        //通过通道声名队列
        channel.queueDeclare("work",true,false,false,null);
        for (int i=0;i<10;i++){
            //发送消息
            channel.basicPublish("","work",null,(i+"hello work queue").getBytes());
        }
        RabbitMQUtils.getSendAndCustomerClose(channel,connection);
    }
}

消费者1

package workQueue;

import com.rabbitmq.client.*;
import utils.RabbitMQUtils;

import java.io.IOException;

public class Customer1 {
    public static void main(String[] args)throws IOException {
        Connection connection = RabbitMQUtils.getConnection();
        Channel channel = connection.createChannel();
        channel.queueDeclare("work",true,false,false,null);
        channel.basicConsume("work",true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//                super.handleDelivery(consumerTag, envelope, properties, body);
                System.out.println("customer1"+new String(body));
            }
        });
    }
}

消费者2

package workQueue;

import com.rabbitmq.client.*;
import utils.RabbitMQUtils;

import java.io.IOException;

public class Customer2 {
    public static void main(String[] args)throws IOException {
        Connection connection = RabbitMQUtils.getConnection();
        Channel channel = connection.createChannel();
        channel.queueDeclare("work",true,false,false,null);
        channel.basicConsume("work",true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//                super.handleDelivery(consumerTag, envelope, properties, body);
                System.out.println("customer2"+new String(body));
            }
        });
    }
}

我们会发现这个规律:在默认情况下,消费者是依次执行的(平均分配);
这里也会出现消息堆积的问题,假如消费者1,消费消息的时候比较慢,消费者2,消费消息比较快,这不是我们所希望的,我们希望消费快的多处理消息在这里插入图片描述在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值