本文已参与「新人创作礼」活动,一起开启掘金创作之路
1.maven工程引入amqp-client-5.0.0.jar
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.0.0</version>
</dependency>
2.生产者和消费者一般用法
2.1创建生产者DirectProducer
package com.rabbit.fisher;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
*direct类型交换器的生产者
*/
public class DirectProducer
{
//定义一个直接交换器
public final static String EXCHANGE_NAME="direct_logs";
public static void main( String[] args ) throws IOException, TimeoutException {
//创建链接、连接到MQ
ConnectionFactory connectionFactory = new ConnectionFactory();
//设置连接工厂的连接地址(默认端口5672)
connectionFactory.setHost("192.168.42.111");
//设置虚拟主机
connectionFactory.setVirtualHost("fisher");
//设置用户名
connectionFactory.setUsername("fisher");
//设置密码
connectionFactory.setPassword("123456");
//创建连接
Connection connection = connectionFactory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//在信道中设置交换器(这里选择直接交换器direct)
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
//在消费者中申明队列
//申明路由键及消息体
String[] routeKeys={"rabbit","rocket","kafka"};
for (int i = 0; i < 6; i++) {
String route = routeKeys[i % 3];
String msg = "Hello World" + (i+1);
//发布消息(设置交换器、路由键、参数、消息内容)
channel.basicPublish(EXCHANGE_NAME, route, null, msg.getBytes());
System.out.println("Send:" + route + ";" + msg);
}
//关闭信道
channel.close();
//关闭连接
connection.close();
}
}
2.2创建消费者DirectConsumer,只绑定rabbit路由键
package com.rabbit.fisher;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
*direct类型交换器的消费者
*/
public class DirectConsumer
{
public static void main( String[] args ) throws IOException, TimeoutException {
//创建链接、连接到MQ
ConnectionFactory connectionFactory = new ConnectionFactory();
//设置连接工厂的连接地址(默认端口5672)
connectionFactory.setHost("192.168.42.111");
//设置虚拟主机
connectionFactory.setVirtualHost("fisher");
//设置用户名
connectionFactory.setUsername("fisher");
//设置密码
connectionFactory.setPassword("123456");
//创建连接
Connection connection = connectionFactory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//在信道中设置交换器(这里选择直接交换器direct)
channel.exchangeDeclare(DirectProducer.EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
//申明队列
String queueName = "queue-fisher";
channel.queueDeclare(queueName, false, false, false, null);
//绑定:将队列(queue-fisher)与交换器通过路由键绑定(rabbit)
String routeKey = "rabbit";
channel.queueBind(queueName, DirectProducer.EXCHANGE_NAME, routeKey);
System.out.println("waiting for message ......");
//申明一个消费者
final Consumer 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("Receive[" + envelope.getRoutingKey() + "]" + message);
}
};
//消费者在指定的队列上消费(queue-fisher),true表示自动确认
channel.basicConsume(queueName, true, consumer);
}
}
2.3先启动消费者
2.4再启动生产者
2.5查看消费者打印,只消费了rabbit内的消息
3.队列和交换器的多重绑定
3.1创建消费者MultiBindConsumer,绑定多个路由键
package com.rabbit.fisher;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
*队列与交换器多重绑定
*/
public class MultiBindConsumer
{
public static void main( String[] args ) throws IOException, TimeoutException {
//创建链接、连接到MQ
ConnectionFactory connectionFactory = new ConnectionFactory();
//设置连接工厂的连接地址(默认端口5672)
connectionFactory.setHost("192.168.42.111");
//设置虚拟主机
connectionFactory.setVirtualHost("fisher");
//设置用户名
connectionFactory.setUsername("fisher");
//设置密码
connectionFactory.setPassword("123456");
//创建连接
Connection connection = connectionFactory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//在信道中设置交换器(这里选择直接交换器direct)
channel.exchangeDeclare(DirectProducer.EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
//申明一个随机队列
String queueName = channel.queueDeclare().getQueue();
//队列绑定到交换器上时,允许绑定多个路由键
String[] routeKeys = {"rabbit", "rocket", "kafka"};
for (String routeKey : routeKeys) {
channel.queueBind(queueName, DirectProducer.EXCHANGE_NAME, routeKey);
}
System.out.println("[*] waiting for message ......");
//申明一个消费者
final Consumer 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("Receive[" + envelope.getRoutingKey() + "]" + message);
}
};
channel.basicConsume(queueName, true, consumer);
}
}
3.2先启动消费者
3.3再启动生产者
3.4查看消费者打印,消息全部被消费
4.一个连接多个信道
4.1创建消费者MultiChannelConsumer,使用2个线程
package com.rabbit.fisher;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
*一个连接多个信道
*/
public class MultiChannelConsumer {
//定义一个内部类
private static class ConsumerWorker implements Runnable{
final Connection connection;
private ConsumerWorker(Connection connection) {
this.connection = connection;
}
@Override
public void run() {
try {
//创建一个信道,意味每个线程单独一个信道
Channel channel = connection.createChannel();
//信道设置交换器类型(direct)
channel.exchangeDeclare(DirectProducer.EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
//申明一个随机队列
String queueName = channel.queueDeclare().getQueue();
//获取消费者名称,用于打印
final String consumerName = Thread.currentThread().getName();
//将队列绑定到交换器上,允许绑定多个路由键
String[] routeKeys = {"rabbit", "rocket", "kafka"};
for (String routeKey : routeKeys) {
channel.queueBind(queueName, DirectProducer.EXCHANGE_NAME, routeKey);
}
System.out.println("[" + consumerName + "] waiting for message");
//创建消费者
final Consumer 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(consumerName + ",Receive[" + envelope.getRoutingKey() + "]" + message);
}
};
channel.basicConsume(queueName, true, consumer);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException, TimeoutException {
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//设置连接工厂的连接地址(默认端口5672)
connectionFactory.setHost("192.168.42.111");
//设置虚拟主机
connectionFactory.setVirtualHost("fisher");
//设置用户名
connectionFactory.setUsername("fisher");
//设置密码
connectionFactory.setPassword("123456");
//创建连接
Connection connection = connectionFactory.newConnection();
//一个连接多个信道
for (int i = 0; i < 2; i++) {
//将连接作为参数,传递给每个线程
Thread worker = new Thread(new ConsumerWorker(connection));
worker.start();
}
}
}
4.2先启动消费者
4.3再启动生产者
4.4查看消费者打印,消息被消费了2次
5.一个队列多个消费者
5.1创建消费者MultiConsumerOneQueue
package com.rabbit.fisher;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
*一个队列多个消费者,消息会在消费者之间的轮询发送
*/
public class MultiConsumerOneQueue {
//定义一个内部类
private static class ConsumerWorker implements Runnable{
final Connection connection;
final String queueName;
private ConsumerWorker(Connection connection,String queueName) {
this.connection = connection;
this.queueName = queueName;
}
@Override
public void run() {
try {
//创建一个信道,意味每个线程单独一个信道
Channel channel = connection.createChannel();
//信道设置交换器类型(direct)
channel.exchangeDeclare(DirectProducer.EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
//申明一个队列
channel.queueDeclare(queueName, false, false, false, null);
//获取消费者名称,用于打印
final String consumerName = Thread.currentThread().getName();
//将队列绑定到交换器上,允许绑定多个路由键
String[] routeKeys = {"rabbit", "rocket", "kafka"};
for (String routeKey : routeKeys) {
channel.queueBind(queueName, DirectProducer.EXCHANGE_NAME, routeKey);
}
System.out.println("[" + consumerName + "] waiting for message");
//创建消费者
final Consumer 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(consumerName + ",Receive[" + envelope.getRoutingKey() + "]" + message);
}
};
channel.basicConsume(queueName, true, consumer);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException, TimeoutException {
//创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//设置连接工厂的连接地址(默认端口5672)
connectionFactory.setHost("192.168.42.111");
//设置虚拟主机
connectionFactory.setVirtualHost("fisher");
//设置用户名
connectionFactory.setUsername("fisher");
//设置密码
connectionFactory.setPassword("123456");
//创建连接
Connection connection = connectionFactory.newConnection();
//一个队列多个消费者
String queueName = "focusAll";
for (int i = 0; i < 3; i++) {
//将连接作为参数,传递给每个线程
Thread worker = new Thread(new ConsumerWorker(connection,queueName));
worker.start();
}
}
}