自定義消息提供者
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class apiProductor {
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setPort(5672);
// IP 地址
connectionFactory.setHost("122.51.242.###");
connectionFactory.setVirtualHost("/");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
channel.confirmSelect();
String exchangeName = "test_qos_exchange";
String routingKey = "qos.save";
String msg = "Hello RabbitMQ Qos Message";
for (int i = 0 ;i < 5; i++){
channel.basicPublish(exchangeName,routingKey,true,null, msg.getBytes());
}
}
}
自定義消息消費者
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class apiConsumer {
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setPort(5672);
connectionFactory.setHost("122.51.242.170");
connectionFactory.setVirtualHost("/");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
String exchangeName = "test_qos_exchange";
String routingKey = "qos.#";
String queueName = "test_qos_queue";
channel.exchangeDeclare(exchangeName,"topic",true,false, null);
channel.queueDeclare(queueName,true,false,false,null);
channel.queueBind(queueName, exchangeName, routingKey);
/*
void basicQos(int prefetchSize, int prefetchCount, boolean global) throws IOException;
basicQos參數:
prefetchSize 每條消息的大小
global 應用在channel還是 consumer 層面, false 指後者
prefetchCount 每次從block中 積攢的消息中拿取prefetchCount 條,用完後再發送,日常工作中設置爲 1
*/
channel.basicQos(0, 1, false);
/*
String basicConsume(String queue, boolean autoAck, Consumer callback) throws IOException;
限流方式, 第一件事就是 autoAck 設置爲false 取消自動簽收 選擇了手工簽收
*/
channel.basicConsume(queueName, false, new MyConsumer(channel));
}
}
自定義Consumer
注意:Spring boot 2.0 以後,取消了默認的Consumer, 而是必須採用自定義的 Consumer(可以通過繼承 DefaultConsumer 來實現)
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import java.io.IOException;
public class MyConsumer extends DefaultConsumer {
private Channel channel;
/**
* Constructs a new instance and records its association to the passed-in channel.
*
* @param channel the channel to which this consumer is attached
*/
public MyConsumer(Channel channel) {
super(channel);
this.channel = channel;
}
@Override
public void handleDelivery(String consumerTag,
Envelope envelope,
AMQP.BasicProperties properties,
byte[] body)
throws IOException
{
System.out.println("-------------consumer message---------------------");
System.out.println("consumerTag ======= >>> " + consumerTag);
System.out.println("envelope ======= >>> " + envelope);
System.out.println("properties ======= >>> " + properties);
System.out.println("body ======= >>> " + new String(body, "UTF-8"));
// multiple 設置爲false 表示不支持批量接收
// 這個方法會給blocker 一個應答,表示我們已經處理完這條消息了,可以進行下一條消息的處理
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
運行結果:
注意
如果把 自定義的 MyConsumer 中的
channel.basicAck(envelope.getDeliveryTag(), false);
註解掉, 則消費端只會顯示循環發送中的第一條消息,其他的消息堆積在服務器的Message中。