目录
一、轮询
1.什么是轮询
一个消费者一条,按均分配;
2.代码
(1)生产者
package com.sj.direct;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.nio.charset.StandardCharsets;
/**
* 工作队列-轮询-生产者
*/
public class Send {
//定义队列名称
private final static String QUEUE_NAME = "work-rr";
public static void main(String[] argv) throws Exception {
//创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
//连接工厂配置
factory.setHost("安装RabbitMQ的服务器IP");
factory.setPort(5672);
factory.setUsername("admin");
factory.setPassword("admin");
factory.setVirtualHost("/");
//创建连接
try (Connection connection = factory.newConnection();
//创建信道
Channel channel = connection.createChannel()) {
/**
* 绑定队列
* 队列名称
* 持久化
* 排他队列
* (1.基于第一次创建它的连接可见,其他的连接看不到,
* 2.其他的连接不能创建同名的排他队列
* 3.它在连接或客户端关闭的情况下会自动删除)
*/
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
for (int i = 0; i < 20; i++) {
String message = "Hello World!"+i;
//发送消息
channel.basicPublish("", QUEUE_NAME, null, message.getBytes(StandardCharsets.UTF_8));
System.out.println(" [x] Sent '" + message + "'" +i);
}
}
}
}
(2)消费者1
package com.sj.direct;
import com.rabbitmq.client.*;
import java.nio.charset.StandardCharsets;
/**
* 工作队列-轮询-消费者
*/
public class Recv01 {
//定义队列名称
private final static String QUEUE_NAME = "work-rr";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("安装RabbitMQ的服务器IP");
factory.setPort(5672);
factory.setUsername("admin");
factory.setPassword("admin");
factory.setVirtualHost("/");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
//打印消息
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), StandardCharsets.UTF_8);
System.out.println(" [x] Received '" + message + "'");
};
/**
* 消费消息
* 1.队列名称
* 2.自动确认
*/
channel.basicQos(0,1,false);
channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});
}
}
(3)消费者2
package com.sj.direct;
import com.rabbitmq.client.*;
import java.nio.charset.StandardCharsets;
/**
* 工作队列-轮询-消费者
*/
public class Recv02 {
//定义队列名称
private final static String QUEUE_NAME = "work-rr";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("安装RabbitMQ的服务器IP");
factory.setPort(5672);
factory.setUsername("admin");
factory.setPassword("admin");
factory.setVirtualHost("/");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
//打印消息
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), StandardCharsets.UTF_8);
System.out.println(" [x] Received '" + message + "'");
};
/**
* 消费消息
* 1.队列名称
* 2.自动确认
*/
channel.basicQos(0,1,false);
// channel.basicConsume("queue_test",false,)
channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});
}
}
二、公平分发策略
1.什么是公平分发
根据消费者的消费能力进行公平分发,处理快的分配的多,处理慢的分配的少;按劳分配;
2.代码
(1)生产者(与轮询生产者一样)
(2)消费者1
package com.sj.level;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Receive1
{
//队列名称
private static final String QUEUE_NAME = "work-rr";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("安装RabbitMQ的服务器IP");
factory.setPort(5672);
factory.setUsername("admin");
factory.setPassword("admin");
factory.setVirtualHost("/");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
try
{
//声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//设置每次从队列里取一条数据
int prefetchCount = 1;
channel.basicQos(prefetchCount);
//定义消费者
DefaultConsumer 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("接收的第" + message);
try
{
//消费者休息1s处理业务
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
finally
{
//手动应答
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
//设置手动应答
boolean autoAck = false;
//监听队列
channel.basicConsume(QUEUE_NAME, autoAck, consumer);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
(2)消费者2
package com.sj.level;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Receive2
{
//队列名称
private static final String QUEUE_NAME = "work-rr";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("安装RabbitMQ的服务器IP");
factory.setPort(5672);
factory.setUsername("admin");
factory.setPassword("admin");
factory.setVirtualHost("/");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
try
{
//声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//设置每次从队列里取一条数据
int prefetchCount = 1;
channel.basicQos(prefetchCount);
//定义消费者
DefaultConsumer 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("接收的第" + message);
try
{
//消费者休息1s处理业务
Thread.sleep(2000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
finally
{
//手动应答
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
//设置手动应答
boolean autoAck = false;
//监听队列
channel.basicConsume(QUEUE_NAME, autoAck, consumer);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}