RabbitMQ安装

1.RabbitMQ安装

RabbitMQ官网:https://www.rabbitmq.com

1.rabbitmq对应erlang版本

在这里插入图片描述

2.下载rabbitmq和erlang

erlang下载地址:https://www.erlang.org/downloads/22.0
在这里插入图片描述

rabbitmq下载地址:https://www.rabbitmq.com/install-windows.html
在这里插入图片描述

3.安装erlang

一直点下一步,具体步骤如下
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

4.安装rabbitmq

一直点下一步
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
安装完成
在win10中找到
在这里插入图片描述
这里会出现启动、停止、重新安装等

5.启动管理工具

在这里插入图片描述
安装完之后我们得验证一下安装是否成功,那么接下来如果你能成功启动并且登录,那么恭喜你安装成功,否则你得重新安装。

1.点击
在这里插入图片描述

在这里插入图片描述
2.输入命令:。
rabbitmq-plugins enable rabbitmq_management

在这里插入图片描述

6.打开浏览器控制台

http://localhost:15672/
默认账号guest guest

在这里插入图片描述
如果不能访问,
文件夹为隐藏需要再文件夹选项中把隐藏文件夹打开显示。
C:\Users\wangleilAppData\Roaming\RabbitMQ\db里面的数据删除再次安装一下Rabbitmq.exe中
然后执行。

添加用户
  • 用户界面
    在这里插入图片描述
  • virtual hosts管理
    virtual hosts相当于mysql的db
    在这里插入图片描述

一般以/开头

我们得对用户进行授权

在这里插入图片描述

在这里插入图片描述

2.java操作队列
新建项目:myrabbitmq
  • pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.blj</groupId>
    <artifactId>myrabbitmq</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>4.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.10</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>
    </dependencies>

</project>
1.简单队列:

在这里插入图片描述
P:消息的生产者。
红色的:队列。
C:消费者。

3个对象:生产者 队列 消费者。

1.2.获取MQ连接
package com.blj.rabbitmq.util;


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

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class ConnectionUtils {

    /**
     * 获取MQ链接
     *
     * @return
     */
    public static Connection getConnetion() throws IOException, TimeoutException {
        ConnectionFactory factory = new ConnectionFactory();
        //设置服务地址
        factory.setHost("127.0.0.1");
        //设置端口号 AMQP 5672
        factory.setPort(5672);
        //VirtualHost
        factory.setVirtualHost("/test");
        //用户名
        factory.setUsername("root");
        //密码
        factory.setPassword("root1234");
        return factory.newConnection();
    }

}
  • 1.3生产者生产消息
package com.blj.rabbitmq.simple;

import com.blj.rabbitmq.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Send {
public static final String QUEUE_NAME="test_simple_queue";
    public static void main(String[] args) throws IOException, TimeoutException {
         //获取一个链接
        Connection connetion = ConnectionUtils.getConnetion();
        //从链接中获取一个通道
        Channel channel = connetion.createChannel();
        //创建队列声明
        channel.queueDeclare(QUEUE_NAME,false,false,false,null);
        String msg="hello simple!";
        channel.basicPublish("",QUEUE_NAME,null,msg.getBytes());
        System.out.println("-- send msg"+msg);
        channel.close();
        connetion.close();
    }

}

  • 1.4消费者接受消息
package com.blj.rabbitmq.simple;

import com.blj.rabbitmq.util.ConnectionUtils;
import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 消费者
 *
 * @author BaiLiJun on 2019/10/24 0024
 */
public class Recv {
    public static final String QUEUE_NAME = "test_simple_queue";

    public static void main(String[] args) throws Exception {
        //获取链接
        Connection connetion = ConnectionUtils.getConnetion();
        //创建频道
        Channel channel = connetion.createChannel();
        //创建队列声明
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //定义消费者
        DefaultConsumer consumer = new DefaultConsumer(channel) {
           //获取到达消息
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String msg = new String(body, "utf-8");
                System.out.println("new api recv msg = " + msg);
            }
        };

        //监听队列
        channel.basicConsume(QUEUE_NAME, true, consumer);

    }


    private static void oldApi() throws IOException, TimeoutException, InterruptedException {
        //获取链接
        Connection connetion = ConnectionUtils.getConnetion();
        //创建频道
        Channel channel = connetion.createChannel();
        //定义队列消费者
        QueueingConsumer consumer = new QueueingConsumer(channel);
        //监听队列
        channel.basicConsume(QUEUE_NAME, true, consumer);
        while (true) {
            QueueingConsumer.Delivery delivery = consumer.nextDelivery();
            String msg = new String(delivery.getBody());
            System.out.println("old api Recv msg = " + msg);
        }
    }


}

  • 1.5简单队列的不足
    耦合性高,生产者一一对应消费者(如果我想有多个消费者消费队列中消息,这时候就不行了)队列名变更这时候得同时变更
2.work queue 工作队列

在这里插入图片描述

为什么会出现工作队列
Simple队列是一一对应的,而且我们实际开发生产者发送消息是毫不费力的,而消费者一般
是要跟业务相结合的.消费者接收到消息之后就需要处理可能需要花费时间,这时候队列就
会积压了很多消息

  • 2.2生产者
package com.blj.rabbitmq.work;

import com.blj.rabbitmq.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 生产者
 *
 * @author BaiLiJun on 2019/10/26 0026
 */
public class Send {
    public static final String QUEUE_NAME = "test_work_queue";

    public static void main(String[] args) throws Exception {
        //获取连接
        Connection connetion = ConnectionUtils.getConnetion();
        //建立通道
        Channel channel = connetion.createChannel();
        //队列声明
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        for (int i = 0; i < 50; i++) {
            String msg = "hello" + i;
            System.out.println("Send msg = " + msg);
            //发布消息
            channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
            Thread.sleep(i*20);
        }
        channel.close();
        connetion.close();
    }


}
  • 2.3消费者1
package com.blj.rabbitmq.work;

import com.blj.rabbitmq.util.ConnectionUtils;
import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 消费者1
 *
 * @author BaiLiJun on 2019/10/26 0026
 */
public class Recv1 {
    public static final String QUEUE_NAME = "test_work_queue";

    public static void main(String[] args) throws Exception {
        //获取连接
        Connection connetion = ConnectionUtils.getConnetion();
        //建立通道
        Channel channel = connetion.createChannel();
        //队列声明
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //定义消费者
        DefaultConsumer consumer = new DefaultConsumer(channel) {
            //消息到达,触发这个方法
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String msg = new String(body, "utf-8");
                System.out.println("[1] Recv msg = " + msg);
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    System.out.println("[1] done");
                }
            }
        };

        //监听队列
        boolean autoAck=true;
        channel.basicConsume(QUEUE_NAME,autoAck,consumer);
    }


}
  • 2.3消费者2
package com.blj.rabbitmq.work;

import com.blj.rabbitmq.util.ConnectionUtils;
import com.rabbitmq.client.*;

import java.io.IOException;

/**
 * 消费者2
 *
 * @author BaiLiJun on 2019/10/26 0026
 */
public class Recv2 {
    public static final String QUEUE_NAME = "test_work_queue";

    public static void main(String[] args) throws Exception {
        //获取连接
        Connection connetion = ConnectionUtils.getConnetion();
        //建立通道
        Channel channel = connetion.createChannel();
        //队列声明
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //定义消费者
        DefaultConsumer consumer = new DefaultConsumer(channel) {
            //消息到达,触发这个方法
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String msg = new String(body, "utf-8");
                System.out.println("[2] Recv msg = " + msg);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    System.out.println("[2] done");
                }
            }
        };

        //监听队列
        boolean autoAck=true;
        channel.basicConsume(QUEUE_NAME,autoAck,consumer);
    }


}
  • 2.4现象
    消费者1和消费者2处理的消息是一样的。.
    消费者1:偶数。
    消费者2:奇数,
    这种方式叫做轮询分发(round-robin) 结果就是不管谁忙或者谁清闲都不会多给一个消息
    任务消息总是你一个我一个
3.公平分发fair dipatch

在这里插入图片描述

  • 生产者
package com.blj.rabbitmq.workfair;

import com.blj.rabbitmq.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

/**
 * 生产者
 *
 * @author BaiLiJun on 2019/10/26 0026
 */
public class Send {
    public static final String QUEUE_NAME = "test_work_queue";

    public static void main(String[] args) throws Exception {
        //获取连接
        Connection connetion = ConnectionUtils.getConnetion();
        //建立通道
        Channel channel = connetion.createChannel();
        //队列声明
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        /**
         * 每个消费者发送确认消息之前,消息队列不发送下一条消息到消费者,一次只处理一条数据
         *
         * 限制发送给同一个消费者不得超过一条消息
         */
        int prefetchCount=1;
        channel.basicQos(prefetchCount);
        for (int i = 0; i < 50; i++) {
            String msg = "hello" + i;
            System.out.println("Send msg = " + msg);
            //发布消息
            channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
            Thread.sleep(i*5);
        }
        channel.close();
        connetion.close();
    }


}
  • 消费者1
package com.blj.rabbitmq.workfair;

import com.blj.rabbitmq.util.ConnectionUtils;
import com.rabbitmq.client.*;

import java.io.IOException;

/**
 * 消费者1
 *
 * @author BaiLiJun on 2019/10/26 0026
 */
public class Recv1 {
    public static final String QUEUE_NAME = "test_work_queue";

    public static void main(String[] args) throws Exception {
        //获取连接
        Connection connetion = ConnectionUtils.getConnetion();
        //建立通道
        final Channel channel = connetion.createChannel();
        //队列声明
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //保证一次只发送一个
        channel.basicQos(1);
        //定义消费者
        DefaultConsumer consumer = new DefaultConsumer(channel) {
            //消息到达,触发这个方法
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String msg = new String(body, "utf-8");
                System.out.println("[1] Recv msg = " + msg);
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    System.out.println("[1] done");
                    //手动回执
                    channel.basicAck(envelope.getDeliveryTag(), false);
                }
            }
        };
        //自动应答改成false
        boolean autoAck = false;
        //监听队列
        channel.basicConsume(QUEUE_NAME, autoAck, consumer);
    }


}
  • 消费
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值