Loading

RabbitMQ:生产者消费者模型构建/为消息自定义属性/自定义消费者

一.pom.xml

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>3.6.5</version>
        </dependency>
    </dependencies>

二.生产者

public class Producer {
    public static void main(String[] args) throws IOException, TimeoutException {
        //创建一个连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.10.132");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        //创建连接
        Connection connection = connectionFactory.newConnection();
        //通过连接创建一个Channel
        Channel channel = connection.createChannel();
        //通过Channel发送数据
        channel.basicPublish("","hello",null,"hello world".getBytes());
        //关闭连接
        channel.close();
        connection.close();
    }
}

这里注意channel.basicPublish方法的第一个参数(exchange)和第二个参数(routingKey),如果没有指定exchange,指定了routingKey,而routingKey与消费者类中指定的queue的name相同,会通过RabbitMQ的默认Exchange(AMQP default)进行路由。

三.消费者

public class Consumer {
    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //创建一个连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.10.132");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        //创建连接
        Connection connection = connectionFactory.newConnection();
        //通过连接创建一个Channel
        Channel channel = connection.createChannel();
        //创建一个队列
        String queueName = "hello";
        channel.queueDeclare(queueName,true,false,false,null);
        //创建一个消费者
        QueueingConsumer consumer = new QueueingConsumer(channel);
        //设置Channel
        channel.basicConsume(queueName,true,consumer);
        //获取消息
        while (true){
            QueueingConsumer.Delivery delivery = consumer.nextDelivery();
            String msg = new String(delivery.getBody());
            System.out.println("消费端:"+msg);
        }

    }
}

四.运行

先运行消费者,再运行生产者。

在消费者的控制台可以接收到生产者发送的消息。

五.为消息定义属性

1.在生产者这边:

先设置properties:

        //自定义属性
        Map<String, Object> headers = new HashMap<>();
        headers.put("w","123");
        headers.put("w2","456");
        //为消息定义属性
        AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
                .deliveryMode(2)  //为1时,则不持久化,为2持久化消息
                .contentEncoding("UTF-8")
                .expiration("100000")//过期时间
                .headers(headers)//自定义属性
                .build();

再将properties作为参数,传到basicPublish方法中

channel.basicPublish("","hello",properties,"hello world".getBytes());

2.消费者

消费者这边,需要通过Delivery获取properties的相关属性。

        while (true){
            QueueingConsumer.Delivery delivery = consumer.nextDelivery();
            String msg = new String(delivery.getBody());
            Map<String, Object> headers = delivery.getProperties().getHeaders();
            headers.forEach((x,y)-> System.out.println(x+":"+y));
            System.out.println("消费端:"+msg);
        }

打印结果:

六.自定义消费者

可以继承DefaultConsumer类,实现handleDelivery方法

public class MyConsumer extends DefaultConsumer {

    public MyConsumer(Channel channel) {
        super(channel);
    }

    @Override
    public void handleDelivery(String consumerTag,
                               Envelope envelope,
                               AMQP.BasicProperties properties,
                               byte[] body) throws IOException {
        System.out.println(consumerTag);
        System.out.println(envelope);
        System.out.println(properties);
        System.out.println(new String(body));
    }
}

 在消费端创建消费者的时候,就可以使用自定义的消费者。

        //创建一个连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.10.132");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        //创建连接
        Connection connection = connectionFactory.newConnection();
        //通过连接创建一个Channel
        Channel channel = connection.createChannel();
        //创建一个队列
        String queueName = "myConsumer";
        channel.queueDeclare(queueName,true,false,false,null);
        //创建一个消费者
        //QueueingConsumer consumer = new QueueingConsumer(channel);
        MyConsumer consumer = new MyConsumer(channel);
        //设置Channel
        channel.basicConsume(queueName,true,consumer);

 运行结果:

 

posted @ 2020-05-27 13:25  秋风飒飒吹  阅读(754)  评论(0编辑  收藏  举报