RabbitMq 的几种常见模式 (仅供参考)

简单队列 

 即一个生产者和一个消费者

 

public class OneToOne {

	private static final String HOST = "192.168.101.210";
	private static final int PORT = 5672;
	private static final String USERNAME = "admin";
	private static final String PASSWORD = "123456";
	private static final String QUEUENAME = "hello";
	@Test
	public void mq_producer() throws IOException {
		//创建连接工厂
		ConnectionFactory connectionFactory = new ConnectionFactory();
		connectionFactory.setHost(HOST);
		connectionFactory.setPort(PORT);
		connectionFactory.setUsername(USERNAME);
		connectionFactory.setPassword(PASSWORD);
		//设置虚拟主机连接
		connectionFactory.setVirtualHost("/");
		//从虚拟主机中获取一个连接
		Connection connection = connectionFactory.newConnection();
		//声明通道   一个TCP连接有可能多个通道
		Channel channel = connection.createChannel();
		//声明队列
		channel.queueDeclare(QUEUENAME, false, false, false, null);
		//定义需要发送的内容
		String msg = "hello rabbitmq2";
		//发布消息
		channel.basicPublish("",QUEUENAME,null,msg.getBytes());
		System.out.println("向"+QUEUENAME+"队列发送了:>>"+msg+"<<");
		channel.close();
		connection.close();
	}

	@Test
	public void mq_consumer() throws IOException, InterruptedException {
		//创建工厂
		ConnectionFactory connectionFactory = new ConnectionFactory();
		connectionFactory.setHost(HOST);
		connectionFactory.setPort(PORT);
		connectionFactory.setUsername(USERNAME);
		connectionFactory.setPassword(PASSWORD);
		//设置发送的虚拟主机
		connectionFactory.setVirtualHost("/");
		//从工厂中获取连接
		Connection connection = connectionFactory.newConnection();
		//声明通道   一个TCP连接有可能多个通道
		Channel channel = connection.createChannel();
		//声明队列
		channel.queueDeclare(QUEUENAME,false,false,false,null);
		//定义队列的消费者
		QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
		//监听队列
		/*
            true:表示自动确认,只要消息从队列中获取,无论消费者获取到消息后是否成功消费,都会认为消息已经成功消费
            false:表示手动确认,消费者获取消息后,服务器会将该消息标记为不可用状态,等待消费者的反馈,
                   如果消费者一直没有反馈,那么该消息将一直处于不可用状态,并且服务器会认为该消费者已经挂掉,不会再给其
                   发送消息,直到该消费者反馈。
         */
		channel.basicConsume(QUEUENAME,true,queueingConsumer);
		//获取消息
		while (true){
			QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
			String msg = new String(delivery.getBody());
			System.out.println("从"+QUEUENAME+"队列中取出了消息:"+msg);
		}

	}
}

Work模式

即一个生产者多个消费者(work,像给老板打工一样)


/**
 * 
 * 如果设置了手动回复,且未回复消息,那么消息在RabbitMq里面是Unacked状态,
 * 每当一个消费者接入,消息会重新变成ready状态重新发送给该消费者,直到接收到回复
 * 如果消费者抛了异常,就会中断与消息队列的连接,由于中断与消息队列的连接相当于没有回复
 * 消息会重新回到队列中,继续发送给下一个消费者处理
 */
public class OneToMany {
    private static final String HOST = "192.168.101.210";
    private static final int PORT = 5672;
    private static final String USERNAME = "admin";
    private static final String PASSWORD = "123456";
    private static final String QUEUENAME = "hello";

    @Test
    public void producer() throws IOException {
        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost(HOST);
        connectionFactory.setPort(PORT);
        connectionFactory.setUsername(USERNAME);
        connectionFactory.setPassword(PASSWORD);
        connectionFactory.setVirtualHost("/");
        //获取连接
        Connection connection = connectionFactory.newConnection();
        //声明通道
        Channel channel = connection.createChannel();
        //声明队列
        channel.queueDeclare(QUEUENAME,false,false,false,null);

        //发送消息
        for (int i=0;i<10;i++){
            String msg = "OneToMany-->>"+i;
            channel.basicPublish("",QUEUENAME,null,msg.getBytes());
        }
        channel.close();
        connection.close();
    }

    @Test
    public void consumer1() throws IOException, InterruptedException {
        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost(HOST);
        connectionFactory.setPort(PORT);
        connectionFactory.setUsername(USERNAME);
        connectionFactory.setPassword(PASSWORD);
        connectionFactory.setVirtualHost("/");
        //获取连接
        Connection connection = connectionFactory.newConnection();
        //声明通道
        Channel channel = connection.createChannel();
        //能者多劳模式、服务器会选择处理完消息的消费者继续发送、如不加这句话无论处理完与否、都会按照平均分发的模式
        /*概念是每次给同一个消费者只发一条消息,在消费者没有反馈处理完该消息时不会再给该消费者发消息*/
        channel.basicQos(1);
        //声明队列
        channel.queueDeclare(QUEUENAME,false,false,false,null);
        //定义该队列的消费者
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
        //监听队列,false为 手动返回消息状态
        channel.basicConsume(QUEUENAME,false,queueingConsumer);
        while(true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            byte[] body = delivery.getBody();
            System.out.println("consumer1接收消息:"+new String(body));
            Thread.sleep(10);
            //手动返回消息给队列
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        }
    }
    @Test
    public void consumer2() throws IOException, InterruptedException {
        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost(HOST);
        connectionFactory.setPort(PORT);
        connectionFactory.setUsername(USERNAME);
        connectionFactory.setPassword(PASSWORD);
        connectionFactory.setVirtualHost("/");
        //获取连接
        Connection connection = connectionFactory.newConnection();
        //声明通道
        Channel channel = connection.createChannel();
        //声明队列
        channel.queueDeclare(QUEUENAME,false,false,false,null);
        //能者多劳模式、服务器会选择处理完消息的消费者继续发送、如不加这句话无论处理完与否、都会按照平均分发的模式
        /*概念是每次给同一个消费者只发一条消息,在消费者没有反馈处理完该消息时不会再给该消费者发消息*/
        channel.basicQos(1);
        //定义该队列的消费者
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
        //监听队列,false为 手动返回消息状态
        channel.basicConsume(QUEUENAME,false,queueingConsumer);
        while(true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            byte[] body = delivery.getBody();
            System.out.println("consumer1接收消息:"+new String(body));
            Thread.sleep(20);
            //手动返回消息给队列
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        }
    }
}

发布订阅

即一个生产者发布,多个消费者共享

/**
 * 发布订阅模式,如果某个消费者挂掉,消息还是会直接存储在队列中,实际情况和一对多消费模式一样
 * 交换机一定要绑定队列,否则消息发送到交换机就会直接丢失(只有队列才有存储的功能)
 */
public class PublishSubscribe {

    private static final String HOST = "192.168.101.210";
    private static final int PORT = 5672;
    private static final String USERNAME = "admin";
    private static final String PASSWORD = "123456";
    private static final String QUEUENAME = "hello";
    private static final String QUEUENAME2 = "hello2";
    private static final String EXCHANGE_NAME = "fanout_exchange";

    @Test
    public void producer() throws IOException {
        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost(HOST);
        connectionFactory.setPort(PORT);
        connectionFactory.setUsername(USERNAME);
        connectionFactory.setPassword(PASSWORD);
        connectionFactory.setVirtualHost("/");
        //获取连接
        Connection connection = connectionFactory.newConnection();
        //获取通道
        Channel channel = connection.createChannel();
        //声明交换机    名字和类型
        channel.exchangeDeclare(EXCHANGE_NAME,"fanout");
        for(int i=0;i<10;i++){
            //创建消息
            String msg = "hello exchange"+i;
            //发布消息
            channel.basicPublish(EXCHANGE_NAME,"",null,msg.getBytes());
        }
        channel.close();
        connection.close();
    }


    @Test
    public void consumer1() throws IOException, InterruptedException {
        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost(HOST);
        connectionFactory.setPort(PORT);
        connectionFactory.setUsername(USERNAME);
        connectionFactory.setPassword(PASSWORD);
        connectionFactory.setVirtualHost("/");
        //获取连接
        Connection connection = connectionFactory.newConnection();
        //获取通道
        Channel channel = connection.createChannel();
        //声明队列
        channel.queueDeclare(QUEUENAME,false,false,false,null);
        //绑定队列到交换机
        channel.queueBind(QUEUENAME,EXCHANGE_NAME,"");
        //服务器每次只发送一条消息给一个消费者
        channel.basicQos(1);
        //定义队列的消费者
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
        //监听队列,手动返回状态
        channel.basicConsume(QUEUENAME,false,queueingConsumer);
        while(true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            System.out.println("consumer1消费消息:>>>"+new String(delivery.getBody()));
            //手动返回消息给服务器
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        }
    }

    @Test
    public void consumer2() throws IOException, InterruptedException {
        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost(HOST);
        connectionFactory.setPort(PORT);
        connectionFactory.setUsername(USERNAME);
        connectionFactory.setPassword(PASSWORD);
        connectionFactory.setVirtualHost("/");
        //获取连接
        Connection connection = connectionFactory.newConnection();
        //获取通道
        Channel channel = connection.createChannel();
        //声明队列
        channel.queueDeclare(QUEUENAME2,false,false,false,null);
        //绑定队列到交换机
        channel.queueBind(QUEUENAME2,EXCHANGE_NAME,"");
        //服务器每次只发送一条消息给一个消费者
        channel.basicQos(1);
        //定义队列的消费者
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
        //监听队列,手动返回状态
        channel.basicConsume(QUEUENAME2,false,queueingConsumer);
        while(true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            System.out.println("consumer2消费消息:>>>"+new String(delivery.getBody()));
            //手动返回消息给服务器
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        }
    }
}

路由模式

即一个生产者,有选择的发送给多个消费者

public class Route {
    private static final String HOST = "192.168.101.210";
    private static final int PORT = 5672;
    private static final String USERNAME = "admin";
    private static final String PASSWORD = "123456";
    private static final String QUEUENAME = "hello";
    private static final String QUEUENAME2 = "hello2";
    private static final String EXCHANGE_NAME = "direct_exchange";
    @Test
    public void producer() throws IOException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost(HOST);
        connectionFactory.setPort(PORT);
        connectionFactory.setUsername(USERNAME);
        connectionFactory.setPassword(PASSWORD);
        connectionFactory.setVirtualHost("/");


        Connection connection = connectionFactory.newConnection();
        //声明信道
        Channel channel = connection.createChannel();
        //声明交换机类型为direct
        channel.exchangeDeclare(EXCHANGE_NAME,"direct");
        //创建消息
        String msg = "Hello Direct !";
        Student s = new Student();
        s.setId(1);
        s.setName("呵呵呵吧");
        //发布消息
        channel.basicPublish(EXCHANGE_NAME,"select",null,Student.ObjectToByte(s));
        System.out.println("生产者发送了:"+msg);
        //关闭通道
        channel.close();
        //关闭连接
        connection.close();
    }


    @Test
    public void consumer1() throws IOException, InterruptedException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost(HOST);
        connectionFactory.setPort(PORT);
        connectionFactory.setUsername(USERNAME);
        connectionFactory.setPassword(PASSWORD);
        connectionFactory.setVirtualHost("/");

        Connection connection = connectionFactory.newConnection();
        //声明信道
        Channel channel = connection.createChannel();
        //声明队列
        channel.queueDeclare(QUEUENAME,false,false,false,null);
        //把队列绑定到交换机上,指定路由Key
        channel.queueBind(QUEUENAME,EXCHANGE_NAME,"update");
        channel.queueBind(QUEUENAME,EXCHANGE_NAME,"delete");
        channel.queueBind(QUEUENAME,EXCHANGE_NAME,"add");
        //同一时刻只发送一条消息给消费者
        channel.basicQos(1);
        //定义队列的消费者
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
        //监听队列,手动返回完成状态
        channel.basicConsume(QUEUENAME,false,queueingConsumer);
        //获取消息
        while(true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            byte[] body = delivery.getBody();
            System.out.println("消费者1接收到消息:"+new String(body,"UTF-8"));
            //返回消息确认状态
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        }

    }

    @Test
    public void consumer2() throws Exception {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost(HOST);
        connectionFactory.setPort(PORT);
        connectionFactory.setUsername(USERNAME);
        connectionFactory.setPassword(PASSWORD);
        connectionFactory.setVirtualHost("/");

        Connection connection = connectionFactory.newConnection();
        //声明通道
        Channel channel = connection.createChannel();
        //声明队列
        channel.queueDeclare(QUEUENAME2,false,false,false,null);
        //绑定队列到交换机,声明key为select
        channel.queueBind(QUEUENAME2,EXCHANGE_NAME,"select");
        //同一时刻只发送一条消息给消费者
        channel.basicQos(1);
        //定义队列的消费者
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
        //监听队列,手动返回消息状态
        channel.basicConsume(QUEUENAME2,false,queueingConsumer);
        //获取消息
        while(true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            byte[] body = delivery.getBody();
            System.out.println("消费者2接收到消息:"+Student.ByteToObject(body));
            //手动返回确认状态
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        }
    }
}

主题模式

和路由模式一样,不过消费者可以模糊匹配key来选择接收的消息

public class Topic {
    private static final String HOST = "192.168.101.210";
    private static final int PORT = 5672;
    private static final String USERNAME = "admin";
    private static final String PASSWORD = "123456";
    private static final String QUEUENAME = "hello";
    private static final String QUEUENAME2 = "hello2";
    private static final String EXCHANGE_NAME = "topic_exchange";
    @Test
    public void producer() throws IOException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost(HOST);
        connectionFactory.setPort(PORT);
        connectionFactory.setUsername(USERNAME);
        connectionFactory.setPassword(PASSWORD);
        connectionFactory.setVirtualHost("/");


        Connection connection = connectionFactory.newConnection();
        //声明信道
        Channel channel = connection.createChannel();
        //声明交换机类型为direct
        channel.exchangeDeclare(EXCHANGE_NAME,"topic");
        //创建消息
        String msg = "Hello Topic !";
        Student s = new Student();
        s.setId(1);
        s.setName("呵呵呵吧");
        //发布消息
        channel.basicPublish(EXCHANGE_NAME,"select.from",null,Student.ObjectToByte(s));
        System.out.println("生产者发送了:"+msg);
        //关闭通道
        channel.close();
        //关闭连接
        connection.close();
    }


    @Test
    public void consumer1() throws IOException, InterruptedException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost(HOST);
        connectionFactory.setPort(PORT);
        connectionFactory.setUsername(USERNAME);
        connectionFactory.setPassword(PASSWORD);
        connectionFactory.setVirtualHost("/");

        Connection connection = connectionFactory.newConnection();
        //声明信道
        Channel channel = connection.createChannel();
        //声明队列
        channel.queueDeclare(QUEUENAME,false,false,false,null);
        //把队列绑定到交换机上,指定路由Key
        channel.queueBind(QUEUENAME,EXCHANGE_NAME,"update.#");
        //同一时刻只发送一条消息给消费者
        channel.basicQos(1);
        //定义队列的消费者
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
        //监听队列,手动返回完成状态
        channel.basicConsume(QUEUENAME,false,queueingConsumer);
        //获取消息
        while(true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            byte[] body = delivery.getBody();
            System.out.println("消费者1接收到消息:"+new String(body,"UTF-8"));
            //返回消息确认状态
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        }

    }

    @Test
    public void consumer2() throws Exception {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost(HOST);
        connectionFactory.setPort(PORT);
        connectionFactory.setUsername(USERNAME);
        connectionFactory.setPassword(PASSWORD);
        connectionFactory.setVirtualHost("/");

        Connection connection = connectionFactory.newConnection();
        //声明通道
        Channel channel = connection.createChannel();
        //声明队列
        channel.queueDeclare(QUEUENAME2,false,false,false,null);
        //绑定队列到交换机,声明key为select
        channel.queueBind(QUEUENAME2,EXCHANGE_NAME,"select.#");
        //同一时刻只发送一条消息给消费者
        channel.basicQos(1);
        //定义队列的消费者
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
        //监听队列,手动返回消息状态
        channel.basicConsume(QUEUENAME2,false,queueingConsumer);
        //获取消息
        while(true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            byte[] body = delivery.getBody();
            System.out.println("消费者2接收到消息:"+Student.ByteToObject(body));
            //手动返回确认状态
            channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
        }
    }

}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值