(二)QOS限流&消息可达性&死信队列

 QOS限流:

消息可达性:

死信队列:

         延时队列:

------------------------------

QOS限流

消费者:

ublic class TulingQosRabbtimqConsumer {

    public static void main(String[] args) throws IOException, TimeoutException {
        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        connectionFactory.setConnectionTimeout(100000);

        //创建一个连接
        Connection connection = connectionFactory.newConnection();

        //创建一个channel
        Channel channel = connection.createChannel();

        //声明交换机
        String exchangeName = "tuling.qos.direct";
        String exchangeType = "direct";
        channel.exchangeDeclare(exchangeName,exchangeType,true,false,null);

        //声明队列
        String queueName = "tuling.qos.queue";
        channel.queueDeclare(queueName,true,false,false,null);

        //交换机绑定队列
        String routingKey = "tuling.qos.key";
        channel.queueBind(queueName,exchangeName,routingKey);


        /**
         * 限流设置:  prefetchSize:每条消息大小的设置
         * prefetchCount:标识每次推送多少条消息 一般是一条
         * global:false标识channel级别的  true:标识消费的级别的
         */
        channel.basicQos(0,1,false);

        /**
         * 消费端限流 需要关闭消息自动签收
         */
        channel.basicConsume(queueName,false,new TulingQosConsumer(channel));
    }
}

2.绑定关系

3.生产者:

public class TulingQosRabbitmqProducer {

    public static void main(String[] args) throws IOException, TimeoutException {

        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        //创建一个连接
        Connection connection = connectionFactory.newConnection();

        //创建一个channel
        Channel channel = connection.createChannel();

        //定义交换机的名称
        String exchangeName = "tuling.qos.direct";

        String routingKey = "tuling.qos.key";

        String msgBody = "你好tuling";
        for(int i=0;i<100;i++) {
            channel.basicPublish(exchangeName,routingKey,null,(msgBody+i).getBytes());
        }
    }
}

复写消费者方法:

public class TulingQosConsumer extends DefaultConsumer {

    private Channel channel;

    public TulingQosConsumer(Channel channel) {
        super(channel);
        this.channel = channel;
    }

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

        /**
         * multiple:false标识不批量签收
         */
        //channel.basicAck(envelope.getDeliveryTag(),false);
    }
}

5.效果:

消息可达性

demo:

生产者:

package com.tuling.return_listener;

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

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeoutException;


public class ReturingListenerProducer {

    public static void main(String[] args) throws IOException, TimeoutException {
        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        connectionFactory.setConnectionTimeout(100000);

        //创建一个连接
        Connection connection = connectionFactory.newConnection();

        //创建一个channel
        Channel channel = connection.createChannel();

        //准备发送消息
        String exchangeName = "tuling.retrun.direct";
        String okRoutingKey = "tuling.retrun.key.ok";
        String errorRoutingKey = "tuling.retrun.key.error";

        /**
         * 设置监听不可达消息
         */
        channel.addReturnListener(new TulingRetrunListener());


        //设置消息属性
        Map<String,Object> tulingInfo = new HashMap<>();
        tulingInfo.put("company","tuling");
        tulingInfo.put("location","长沙");

        AMQP.BasicProperties basicProperties = new AMQP.BasicProperties().builder()
                .deliveryMode(2)
                .correlationId(UUID.randomUUID().toString())
                .timestamp(new Date())
                .headers(tulingInfo)
                .build();

        String msgContext = "你好 图灵...."+System.currentTimeMillis();

        /**
         * 发送消息
         * mandatory:该属性设置为false,那么不可达消息就会被mq broker给删除掉
         *          :true,那么mq会调用我们得retrunListener 来告诉我们业务系统 说该消息
         *          不能成功发送.
         */
        channel.basicPublish(exchangeName,okRoutingKey,true,basicProperties,msgContext.getBytes());


        String errorMsg1 = "你好 图灵 mandotory为false...."+System.currentTimeMillis();

        //错误发送   mandotory为false
        channel.basicPublish(exchangeName,errorRoutingKey,false,basicProperties,errorMsg1.getBytes());

        String errorMsg2 = "你好 图灵 mandotory为true...."+System.currentTimeMillis();

        //错误发送 mandotory 为true
        channel.basicPublish(exchangeName,errorRoutingKey,true,basicProperties,errorMsg2.getBytes());


    }
}

消费者:

package com.tuling.return_listener;

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

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


public class RetruningListenerConsumer {

    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {

        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        connectionFactory.setConnectionTimeout(100000);

        //创建一个连接
        Connection connection = connectionFactory.newConnection();

        //创建一个channel
        Channel channel = connection.createChannel();

        //声明交换机
        String exchangeName = "tuling.retrun.direct";
        channel.exchangeDeclare(exchangeName,"direct",true,false,null);

        //声明队列
        String queueName = "t04.retrunlistener.queue";
        channel.queueDeclare(queueName,true,false,false,null);

        //声明一个绑定
        String routingKey = "tuling.retrun.key.ok";
        channel.queueBind(queueName,exchangeName,routingKey);

        //创建一个消费者
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);

        channel.basicConsume(queueName,true,queueingConsumer);

        while (true) {
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            System.out.println("接受的消息:"+new String(delivery.getBody()));
        }

    }
}

3.建立绑定关系如图:


 

4.消息回调:

public class TulingRetrunListener implements ReturnListener {
    @Override
    public void handleReturn(int replyCode, String replyText, String exchange, String routingKey, AMQP.BasicProperties properties, byte[] body) throws IOException {
        System.out.println("replyCode:"+replyCode);
        System.out.println("replyText:"+replyText);
        System.out.println("exchange:"+exchange);
        System.out.println("routingKey:"+routingKey);
        System.out.println("properties:"+properties);
        System.out.println("msg body:"+new String(body));

    }
}

5.结果:

队列写错了,无法建立对应关系:

死信队列:

延时队列的使用(延时队列)

延时队列:


第一步: 把消息发送到一个 过期的队列中q1,10s  我们的消费者不能监听我们的q1,
第二步:  过了十秒钟,让q1 的消息转到私信队列上,然后我们的消费者监听我们的私信队列。
半个消息不适用的,支付的订单创建中,状态更改,没有点支付,没有支付,把订单给删了。
可靠性投递,延迟deletecheck,
第一步:
1.biz 数据库,
2.发送 Order 服务
3.发送延时消息
4.库存服务监听我们的业务小心
5.发送确认消息
6.监听第五部确认消息
7.入库第5部发送得确认消息
8.监听延时检查消息。

业务数据入库,下游服务不可能30s 没返回,性能提高了。

确认消息:


 

发布了668 篇原创文章 · 获赞 12 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/xiamaocheng/article/details/105173024
今日推荐