RabbitMQ入门示例及Channel常用函数参数阐释

1、Hello RabbitMQ的实现

在开始之前先看简单实现打印Hello RabbitMQ的过程:
实现过程:生产者将消息发送到队列(队列的名字为hello)中,消费者从队列中获取消息。
VgPIFf.png
看下具体实现:
首先是生产者:helloPro.java

    @Test
    public void helloPro() throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("localhost");
        connectionFactory.setUsername("ForMe");
        connectionFactory.setPassword("ForMe=520");
        connectionFactory.setPort(AMQP.PROTOCOL.PORT);

        Connection connection = connectionFactory.newConnection();
        Channel channel = connection.createChannel();

        String QUEUE_NAME = "hello";
        channel.queueDeclare(QUEUE_NAME,false,false,false,null);

        String message = "Hello RabbitMQ!";
        channel.basicPublish("",QUEUE_NAME,null,message.getBytes("UTF-8"));

        System.out.println("Producer Send a message:" + message);

        // 关闭资源
        channel.close();
        connection.close();
    }

然后是helloConsumer.java

    @Test
    public void helloConsumer() throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("localhost");
        connectionFactory.setUsername("ForMe");
        connectionFactory.setPassword("ForMe=520");
        connectionFactory.setPort(AMQP.PROTOCOL.PORT);

        Connection connection = connectionFactory.newConnection();
        Channel channel = connection.createChannel();

        String QUEUE_NAME = "hello";
        channel.queueDeclare(QUEUE_NAME,false,false,false,null);

        Consumer consumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("Received '" + message + "'");
            }
        };

        // 订阅消息
        channel.basicConsume(QUEUE_NAME, true, consumer);
    }

先运行helloPro,再运行helloConsumer,控制台打印结果如下:
Vg1K9H.png

Vg2CPe.png

2、常用函数解释

  • 声明队列:QueueDeclare
public static QueueDeclareOk QueueDeclare(String queue, Boolean durable, Boolean exclusive, Boolean autoDelete, IDictionary<String, Object> arguments);

1、第一个参数表示队列名称;
2、第二个参数为是否持久化(true表示是,队列将在服务器重启时生存);
3、第三个参数为是否是独占队列(创建者可以使用的私有队列,断开后自动删除);
4、第四个参数为当所有消费者客户端连接断开时是否自动删除队列;
5、第五个参数为队列的其他参数

  • 声明队列无需等待:QueueDeclareNoWait
public static Void QueueDeclareNoWait(String queue, Boolean durable, Boolean exclusive, Boolean autoDelete, IDictionary<String, Object> arguments);
  • 设置每次从队列获取消息的数量:basicQos
void basicQos(int prefetchSize,int prefetchCount,boolean global)

1、prefetchSize:0

2、prefetchCount:多个消费者消费能力不同,所以rabbitmq会在消费者消费prefetchCount个消息后,再次发送prefetchCount个消息给消费者

3、global:true/false,是否将上面的配置应用于channel,若是否,就是应用于消费者consumer

  • 发布消息
void basicPublish(String exchange,String routingKey,boolean mandatory,boolean immediate,BasicProperties props,byte[] body) throws IOException

1、exchange: 交换机的名称

2、routingKey: 队列的名称

3、mandatory: true,exchange根据自身类型和消息routingKey没有找到合适的队列queue,那么就会调用basic.return将消息返回给生产者,若为false,则broker把消息丢弃

4、immediate: true,当消息通过exchange路由到queue的时候,发现这个queue上面没有消费者,那么就不会进入这个queue,如果根据routingKey匹配到的所有的队列都是没有消费者的,那么就会调用basic.return方法返回给生产者

5、props: 表示消息的持久化,配合channel和queue的durable使用

6、body: 发送的消息

应用实例:

channel.basicPublish("",QUEUE_NAME,MessageProperties.PERSISTENT_TEXT_PLAIN,"message".getBytes());
  • 声明交换机
Exchange.DeclareOk exchangeDeclare(String exchange,String type,boolean durable,boolean autoDelete,Map<String,Object> arguments)

1、type: 有四种类型,分别为:fanout,direct,topic,headers

2、durable: 表示是否持久化,为true,表示是exchange的持久化,仅设置这一项不代表消息的持久化。

3、autoDelete: 当没有消费者消费的时候是否要删除exchange

  • exchangeBinging
Exchange.BindOk exchangeBind(String destination,String source,String routingkey)

生产者发送消息到source交换机,source根据路由键找到与其绑定的另一个交换机destination,并把消息转发到destination中,存储在destination绑定的队列queue

  • basicConsume
String basicConsume(String queue,boolean autoAck,Consumer callback)

autoAck:消息的确认模式自动应答,true表示自动应答,false需要使用basicAck、basicNack或者是basicReject进行消息应答

callback:消费者对象

注意: 关于basicConsume的第二个参数autoAck: 应答模式,true:自动应答,即消费者获取到消息,该消息就会从队列中删除掉,false:手动应答,当从队列中取出消息后,需要程序员手动调用方法应答,如果没有应答,该消息还会再放进队列中,就会出现该消息一直没有被消费掉的现象

  • 手动应答:basicAck
void basicAck(long deliveryTag,boolean multiple)

deliveryTag:消息的index

multiple:是否批量,若为true,则一次性回执所有小于deliveryTag的消息

系统会为每个队列都隐式的绑定一个默认的交换机,交换机的名称为“(AMQP default)”,类型为直连接direct,当你手动创建一个队列时,后台会自动将这个队列绑定到一个名称为空的Direct类型交换机上,绑定路由名称与队列名称相同,相当于channel.queueBind(queue:”QUEUE_NAME”, exchange:”(AMQP default)”, routingKey:”QUEUE_NAME”); 所以hello world示例虽然没有显示声明交换机,当路由键和队列名称一样时就将消息发送到这个默认的交换机里。有了这个默认的交换机和绑定,我们就可以像其他轻量级的队列,如Redis那样,直接操作队列来处理消息。不过理论上是可以的,但实际上在RabbitMQ里直接操作是不可取的。消息始终都是先发送到交换机,由交换级经过路由传送给队列,消费者再从队列中获取消息的。不过由于这个默认交换机和路由的关系,使我们只关心队列这一层即可,这个比较适合做一些简单的应用,毕竟没有发挥RabbitMQ的最大功能(RabbitMQ可以重量级消息队列),如果都用这种方式去使用的话就真是杀鸡用宰牛刀了。

推荐阅读:
RabbitMQ入门教程(三):Hello World
rabbitmq channel方法参数详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值