1 简单模式Hello World

rabbitTemplate 绑定的地址_消息队列

功能:一个生产者P发送消息到队列Q,一个消费者C接收

生产者实现思路:

创建连接工厂ConnectionFactory,设置服务地址,端口号,设置用户名、密码、virtual host,从连接工厂中获取连接connection,使用连接创建通道channel,使用通道channel创建队列queue,使用通道channel向队列中发送消息,关闭通道和连接。

public class RabbitMQPublishTest {

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.1.245");
        connectionFactory.setPort(5672);
        //设置访问的虚拟主机
        connectionFactory.setVirtualHost("my_vhost");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = connectionFactory.newConnection();
        //获取连接通道
        Channel channel = connection.createChannel();
        //通道绑定对应消息队列
//     * @param queue 队列名称
//     * @param durable 是否持久队列(服务重启,队列是否会存在)
//     * @param exclusive 该连接是否独占队列
//     * @param autoDelete 服务器在不使用的时候是否删除该队列
//     * @param arguments 多余参数
        channel.queueDeclare("hello",false,false,false,null);

        //发布消息
//     * @param exchange 发布的交换机名称
//     * @param routingKey 路由关键字 要注意 这个表示具体发送到哪个队列(和通道中的queue名称一致)
//     * @param props 额外设置参数
//     * @param body 消息体
        //MessageProperties.PERSISTENT_TEXT_PLAIN 消息持久化
        channel.basicPublish("","hello", MessageProperties.PERSISTENT_TEXT_PLAIN,"hello,rabbitMQ".getBytes());
        System.out.println("消息发送完毕");
        channel.close();
        connection.close();
    }
}

消费者实现思路:
创建连接工厂ConnectionFactory,设置服务地址,端口号,设置用户名、密码、virtual host,从连接工厂中获取连接connection,使用连接创建通道channel,使用通道channel创建队列queue, 创建消费者并监听队列,从队列中读取消息。

public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.1.245");
        connectionFactory.setPort(5672);
        //设置访问的虚拟主机
        connectionFactory.setVirtualHost("my_vhost");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = connectionFactory.newConnection();
        //获取连接通道
        Channel channel = connection.createChannel();
        //通道绑定对应消息队列
        channel.queueDeclare("hello",false,false,false,null);
        //消费消息
        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(new String(body));
            }
        });
        //消费端不要关闭连接和通道
    }

2 工作队列模式Work Queue

rabbitTemplate 绑定的地址_System_02


功能:一个生产者,多个消费者,每个消费者获取到的消息唯一,多个消费者只有一个队列。

任务队列:避免立即做一个资源密集型任务,必须等待它完成,而是把这个任务安排到稍后再做。我们将任务封装为消息并将其发送给队列。后台运行的工作进程将弹出任务并最终执行作业。当有多个worker同时运行时,任务将在它们之间共享。

生产者实现思路:
创建连接工厂ConnectionFactory,设置服务地址,端口号,用户名、密码、virtual host,从连接工厂中获取连接connection,使用连接创建通道channel,使用通道channel创建队列queue,使用通道channel向队列中发送消息,2条消息之间间隔一定时间,关闭通道和连接。

public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.1.245");
        connectionFactory.setPort(5672);
        //设置访问的虚拟主机
        connectionFactory.setVirtualHost("my_vhost");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = connectionFactory.newConnection();
        //获取连接通道
        Channel channel = connection.createChannel();
        //通道绑定对应消息队列
        channel.queueDeclare("hello",false,false,false,null);

        //发布消息
        for (int i = 1; i <=20 ; i++) {
            String body = "send["+i+"] hello,rabbitMQ";
            channel.basicPublish("","hello", MessageProperties.PERSISTENT_TEXT_PLAIN,body.getBytes());
        }

        System.out.println("消息发送完毕");
        channel.close();
        connection.close();
    }

消费者实现思路:

创建连接工厂ConnectionFactory,设置服务地址,端口号,用户名、密码、virtual host,从连接工厂中获取连接connection,使用连接创建通道channel,使用通道channel创建队列queue,创建两个消费队列。

2.1 平均分配消息

消费者1:

public class Customer1 {

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.1.245");
        connectionFactory.setPort(5672);
        //设置访问的虚拟主机
        connectionFactory.setVirtualHost("my_vhost");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = connectionFactory.newConnection();
        //获取连接通道
        Channel channel = connection.createChannel();
        //通道绑定对应消息队列
        channel.queueDeclare("hello",false,false,false,null);
        //消费消息
        channel.basicConsume("hello",true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(new String(body));
            }
        });
        //消费端不要关闭连接和通道
    }
}

rabbitTemplate 绑定的地址_消息队列_03

public class Customer2 {

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.1.245");
        connectionFactory.setPort(5672);
        //设置访问的虚拟主机
        connectionFactory.setVirtualHost("my_vhost");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = connectionFactory.newConnection();
        //获取连接通道
        Channel channel = connection.createChannel();
        //通道绑定对应消息队列
        channel.queueDeclare("hello",false,false,false,null);
        //消费消息
        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(new String(body));
            }
        });
        //消费端不要关闭连接和通道
    }
}

rabbitTemplate 绑定的地址_虚拟主机_04

从上面可以看到 默认情况下,消息会被平分到各个消费者来消费。

2.2 手动确认达到能者多劳

可以通过手动确认和限制消息数量来控制。
生产者:

public class RabbitMQPublishTest {

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.1.245");
        connectionFactory.setPort(5672);
        //设置访问的虚拟主机
        connectionFactory.setVirtualHost("my_vhost");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = connectionFactory.newConnection();
        //获取连接通道
        Channel channel = connection.createChannel();
        //通道绑定对应消息队列
        channel.queueDeclare("hello",false,false,false,null);

        //发布消息
        for (int i = 1; i <=20 ; i++) {
            String body = "send["+i+"] hello,rabbitMQ";
            channel.basicPublish("","hello", null,body.getBytes());
        }

        System.out.println("消息发送完毕");
        channel.close();
        connection.close();
    }
}

消费者:

public class Customer1 {

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.1.245");
        connectionFactory.setPort(5672);
        //设置访问的虚拟主机
        connectionFactory.setVirtualHost("my_vhost");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = connectionFactory.newConnection();
        //获取连接通道
        Channel channel = connection.createChannel();
        //通道绑定对应消息队列
        channel.queueDeclare("hello",false,false,false,null);
        //消费消息
        channel.basicConsume("hello",false,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println(new String(body));
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        });
        //消费端不要关闭连接和通道
    }
}

rabbitTemplate 绑定的地址_虚拟主机_05

public class Customer2 {

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.1.245");
        connectionFactory.setPort(5672);
        //设置访问的虚拟主机
        connectionFactory.setVirtualHost("my_vhost");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = connectionFactory.newConnection();
        //获取连接通道
        Channel channel = connection.createChannel();
        //通道绑定对应消息队列
        channel.queueDeclare("hello",false,false,false,null);
        //服务器只给该消费者一次只发一条
        channel.basicQos(1);
        //消费消息
        channel.basicConsume("hello",false,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println(new String(body));
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //参数2 是否开启多个消息同时确认
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        });
        //消费端不要关闭连接和通道
    }
}

rabbitTemplate 绑定的地址_rabbitmq_06

3 发布/订阅模式Publish/Subscribe

rabbitTemplate 绑定的地址_rabbitmq_07


功能:一个生产者发送的消息会被多个消费者获取。一个生产者、一个交换机、多个队列、多个消费者

生产者:可以将消息发送到队列或者是交换机。

消费者:只能从队列中获取消息。

如果消息发送到没有队列绑定的交换机上,那么消息将丢失。

交换机不能存储消息,消息存储在队列中

生产者实现思路:

创建连接工厂ConnectionFactory,设置服务地址,端口号,用户名、密码、virtual host,从连接工厂中获取连接connection,使用连接创建通道channel,使用通道channel创建队列queue,使用通道channel创建交换机并指定交换机类型为fanout,使用通道向交换机发送消息,关闭通道和连接。

public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.1.245");
        connectionFactory.setPort(5672);
        //设置访问的虚拟主机
        connectionFactory.setVirtualHost("my_vhost");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = connectionFactory.newConnection();
        //获取连接通道
        Channel channel = connection.createChannel();
        //声明交换机,交换机类型:
        channel.exchangeDeclare("logs", BuiltinExchangeType.FANOUT);
        channel.basicPublish("logs", "", null, "广播消息".getBytes());
        channel.close();
        connection.close();
        System.out.println("消息发送完毕");
    }

消费者实现思路:

创建连接工厂ConnectionFactory,设置服务地址,端口号,用户名、密码、virtual host,从连接工厂中获取连接connection,使用连接创建通道channel,使用通道channel创建队列queue,绑定队列到交换机,创建多个消费者进行监听。
消费者1:

public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.1.245");
        connectionFactory.setPort(5672);
        //设置访问的虚拟主机
        connectionFactory.setVirtualHost("my_vhost");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = connectionFactory.newConnection();
        //获取连接通道
        Channel channel = connection.createChannel();
        //创建临时队列
        String queue = channel.queueDeclare().getQueue();
        //队列绑定交换机
        channel.queueBind(queue, "logs", "");
        channel.basicConsume(queue, true, new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag,
                                       Envelope envelope,
                                       AMQP.BasicProperties properties,
                                       byte[] body) throws IOException {
                System.out.println("消费者1: "+new String(body));
            }
        });
    }

rabbitTemplate 绑定的地址_rabbitmq_08


消费2:

public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.1.245");
        connectionFactory.setPort(5672);
        //设置访问的虚拟主机
        connectionFactory.setVirtualHost("my_vhost");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = connectionFactory.newConnection();
        //获取连接通道
        Channel channel = connection.createChannel();
        //创建临时队列
        String queue = channel.queueDeclare().getQueue();
        //队列绑定交换机
        channel.queueBind(queue, "logs", "");
        channel.basicConsume(queue, true, new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag,
                                       Envelope envelope,
                                       AMQP.BasicProperties properties,
                                       byte[] body) throws IOException {
                System.out.println("消费者2: "+new String(body));
            }
        });
    }

rabbitTemplate 绑定的地址_虚拟主机_09

4 路由模式Routing

rabbitTemplate 绑定的地址_System_10


说明:生产者发送消息到交换机并且要指定路由key,消费者将队列绑定到交换机时需要指定路由key。

生产者实现思路:

创建连接工厂ConnectionFactory,设置服务地址,端口号,用户名、密码、virtual host,从连接工厂中获取连接connection,使用连接创建通道channel,使用通道channel创建队列queue,使用通道channel创建交换机并指定交换机类型为direct,使用通道向交换机发送消息,关闭通道和连接。

public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.1.245");
        connectionFactory.setPort(5672);
        //设置访问的虚拟主机
        connectionFactory.setVirtualHost("my_vhost");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = connectionFactory.newConnection();
        //获取连接通道
        Channel channel = connection.createChannel();
        //声明交换机,交换机类型:
        channel.exchangeDeclare("logs_direct", BuiltinExchangeType.DIRECT);
        channel.basicPublish("logs_direct", "123456", null, "广播路由消息".getBytes());
        channel.close();
        connection.close();
        System.out.println("消息发送完毕");
    }

消费者实现:
customer1:

public class Customer1 {

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.1.245");
        connectionFactory.setPort(5672);
        //设置访问的虚拟主机
        connectionFactory.setVirtualHost("my_vhost");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = connectionFactory.newConnection();
        //获取连接通道
        Channel channel = connection.createChannel();
        //创建临时队列
        String queue = channel.queueDeclare().getQueue();
        //队列绑定交换机
        channel.queueBind(queue, "logs_direct", "123456");
        channel.basicConsume(queue, true, new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag,
                                       Envelope envelope,
                                       AMQP.BasicProperties properties,
                                       byte[] body) throws IOException {
                System.out.println("消费者1: "+new String(body));
            }
        });
    }
}

rabbitTemplate 绑定的地址_System_11

public class Customer2 {

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.1.245");
        connectionFactory.setPort(5672);
        //设置访问的虚拟主机
        connectionFactory.setVirtualHost("my_vhost");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = connectionFactory.newConnection();
        //获取连接通道
        Channel channel = connection.createChannel();
        //创建临时队列
        String queue = channel.queueDeclare().getQueue();
        //队列绑定交换机
        channel.queueBind(queue, "logs_direct", "");
        channel.basicConsume(queue, true, new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag,
                                       Envelope envelope,
                                       AMQP.BasicProperties properties,
                                       byte[] body) throws IOException {
                System.out.println("消费者2: "+new String(body));
            }
        });
    }
}

rabbitTemplate 绑定的地址_System_12

5 通配符模式Topics

rabbitTemplate 绑定的地址_交换机_13

注意:
*匹配一个单词,#匹配0个或多个单词,单词之间用.做分割
生产者:

public class RabbitMQPublishTest {

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.1.245");
        connectionFactory.setPort(5672);
        //设置访问的虚拟主机
        connectionFactory.setVirtualHost("my_vhost");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = connectionFactory.newConnection();
        //获取连接通道
        Channel channel = connection.createChannel();
        //声明交换机,交换机类型:
        channel.exchangeDeclare("logs_Topics", BuiltinExchangeType.TOPIC);
        channel.basicPublish("logs_Topics", "china.weather", null, "今天中国天气真好".getBytes());
        channel.basicPublish("logs_Topics", "china.news", null, "今天中国中芯国际上市了".getBytes());
        channel.basicPublish("logs_Topics", "usa.weather", null, "今天美国天气非常差".getBytes());
        channel.basicPublish("logs_Topics", "usa.news", null, "今天美国疫情突破两百万".getBytes());
        channel.close();
        connection.close();
        System.out.println("消息发送完毕");
    }
}

消费者1:

public class Customer1 {

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.1.245");
        connectionFactory.setPort(5672);
        //设置访问的虚拟主机
        connectionFactory.setVirtualHost("my_vhost");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = connectionFactory.newConnection();
        //获取连接通道
        Channel channel = connection.createChannel();
        //创建临时队列
        String queue = channel.queueDeclare().getQueue();
        //队列绑定交换机 *匹配一个单词,#匹配0个或多个单词
        channel.queueBind(queue, "logs_Topics", "usa.*");
        channel.basicConsume(queue, true, new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag,
                                       Envelope envelope,
                                       AMQP.BasicProperties properties,
                                       byte[] body) throws IOException {
                System.out.println("消费者1: "+new String(body));
            }
        });
    }
}

rabbitTemplate 绑定的地址_虚拟主机_14


消费者2:

public class Customer2 {

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.1.245");
        connectionFactory.setPort(5672);
        //设置访问的虚拟主机
        connectionFactory.setVirtualHost("my_vhost");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = connectionFactory.newConnection();
        //获取连接通道
        Channel channel = connection.createChannel();
        //创建临时队列
        String queue = channel.queueDeclare().getQueue();
        //队列绑定交换机 *匹配一个单词,#匹配0个或多个单词
        channel.queueBind(queue, "logs_Topics", "china.*");
        channel.basicConsume(queue, true, new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag,
                                       Envelope envelope,
                                       AMQP.BasicProperties properties,
                                       byte[] body) throws IOException {
                System.out.println("消费者2: "+new String(body));
            }
        });
    }
}

rabbitTemplate 绑定的地址_rabbitmq_15