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 没返回,性能提高了。
确认消息: