官网上所有的Demo代码
Chapter1
producer:译名是生产者,实际工作就是发送消息给queue或者server
queue:队列,只受限制于主机内存和磁盘大小,是一个大的消息缓存区
consumer:消费者,等待接收消息
package rabbitMQDemo.a_helloWord;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* 消息发送者
* rabbitMQ的默认端口是:15672
* @author gaomeiling
*
*/
public class Send {
private final static String QUEUE_NAME="hello";
public static void main(String[] args) throws Exception{
//创建与rabbitMQ服务器的连接
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");//连接的broker,可以是名字、ip
Connection connection = factory.newConnection();
//获取channel
Channel channel = connection.createChannel();
channel.queueDeclareNoWait(QUEUE_NAME, false, false, false, null);
String message = "hello world!say 4.";
//把消息放入队列
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println("[x]Sent'"+message+"'");
//关闭通道
channel.close();
//关闭连接
connection.close();
}
}
package rabbitMQDemo.a_helloWord;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
/**
* 消息接收者
* rabbitMQ的默认端口是:15672
* @author gaomeiling
*
*/
public class Recv {
private static final String QUEUE_NAME = "hello";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println("[*]waiting for message.To exit press ctr+c");
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope,
AMQP.BasicProperties properties, byte[] body) throws UnsupportedEncodingException {
String message = new String(body,"utf-8");
System.out.println("[x]Received'"+message+"'");
}
};
//以对象的形式回调
channel.basicConsume(QUEUE_NAME, true,consumer);
}
}
Chapter2
一个queue里的消息被多个消费者交替读取
package rabbitMQDemo.b_workQueues;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.MessageProperties;
/**
* producer
* @author gaomeiling
* @date 2018年10月19日
*/
public class NewTask {
private static final String TASK_QUEUE_NAME = "hello";
public static void main(String[] args) throws Exception{
//创建与rabbitMQ服务器的连接
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");//连接的 broker,可以是名字、ip
Connection connection = factory.newConnection();
//获取channel
Channel channel = connection.createChannel();
boolean durable = true;//持久度,确保rabbitMQ不丢失queue
channel.queueDeclareNoWait("task_queue", durable, false, false, null);
String[] argv = new String[] {"first message..."};
String message = getMessage(argv);
//把消息放入队列
channel.basicPublish("", TASK_QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());
System.out.println("[x] Sent'"+message+"'");
//关闭通道
channel.close();
//关闭连接
connection.close();
}
private static String getMessage(String[] strings) {
if(strings.length<1)
return "hello world!";
return joinString(strings,".");
}
private static String joinString(String[] strings, String delimiter) {
int length = strings.length;
if(length == 0)
return "";
StringBuilder words = new StringBuilder(strings[0]);
for(int i=1;i<length;i++) {
words.append(delimiter).append(strings[i]);
}
return words.toString();
}
}
package rabbitMQDemo.b_workQueues;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
/**
* consumer
* @author gaomeiling
* @date 2018年10月19日
*/
public class Worker {
private static final String TASK_QUEUE_NAME = "task_queue";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
//声明queue
channel.queueDeclare(TASK_QUEUE_NAME, false, false, false, null);
System.out.println("[*] waiting for message.To exit press ctr+c");
channel.basicQos(1);//一次只能接收一条未确认消息
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("[x] Received'"+message+"'");
try {
doWork(message);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("[x] Done");
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
boolean autoAck = false;//是否自动返回确认,如果设置为false,只有worker完成一个task才返回,确保一个任务不会丢失
//以对象的形式回调
channel.basicConsume(TASK_QUEUE_NAME, autoAck,consumer);
}
protected static void doWork(String task) throws InterruptedException {
for(char ch : task.toCharArray()) {
if(ch == '.') Thread.sleep(3000);
}
}
}
Chapter3
在queue前增加exchange,由exchange决定消息由哪个queue送至consumer,exchange的类型:direct、topic、header和fanout。本章讲的是fanout,只要是与exchange绑定的queue就会得到exchange的消息。
package rabbitMQDemo.c_publish_subscribe;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* producer
* @author gaomeiling
* 使用的exchange类型为fanout
* @date 2018年10月19日
*/
public class EmitLog {
private static final String EXCHANGE_NAME = "logs";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
//连接服务器
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
//声明exchange
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
String message = "What do you want to say?";
//连接producer与exchange,将消息发布到exchange
channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'");
channel.close();
connection.close();
}
}
package rabbitMQDemo.c_publish_subscribe;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
/**
* consumer
* 使用的exchange类型为fanout
* @author gaomeiling
* @date 2018年10月19日
*/
public class ReciveLogs {
private static final String EXCHANGE_NAME = "logs";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
//声明exchange
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
//声明queue,自动生成一个queue,特点:带有名字、短暂的、单独的、自动删除
String queueName = channel.queueDeclare().getQueue();
//绑定exchange与queue
channel.queueBind(queueName, EXCHANGE_NAME, "");
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
//声明consumer
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(" [x] Received '" + message + "'");
}
};
//连接consumer与queue
channel.basicConsume(queueName, true, consumer);
}
}
Chapter4
exchange类型topic,只有绑定的routing key对应才可以获得exchange的消息。
package rabbitMQDemo.d_routing;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* producer
* 使用的exchange类型为direct
* @author gaomeiling
* @date 2018年10月19日
*/
public class EmitLogDirect {
private static final String EXCHANG_NAME = "direct_logs";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
String exchangeType = "direct";
channel.exchangeDeclare(EXCHANG_NAME, exchangeType);
String severity = "error";
String message = "say you!";
//连接producer与exchange
channel.basicPublish(EXCHANG_NAME, severity, null, message.getBytes());
System.out.println(" [x] Sent '" + severity + "':'" + message + "'");
channel.close();
connection.close();
}
}
package rabbitMQDemo.d_routing;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
/**
* consumer
* 使用的exchange类型为direct
* @author gaomeiling
* @date 2018年10月19日
*/
public class ReceiveLogsDirect {
private static final String EXCHANGE_NAME = "direct_logs";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
//声明exchange
String exchangeType = "direct";
channel.exchangeDeclare(EXCHANGE_NAME, exchangeType);
//声明queue
String queueName = channel.queueDeclare().getQueue();
//routing key
String[] args1 = new String[] {"error"};
String[] args2 = new String[] {"error","info","warning"};
//绑定exchange与queue,给定routing key
for(String severity : args2) {
channel.queueBind(queueName , EXCHANGE_NAME , severity);
}
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
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(" [x] Received '" + envelope.getRoutingKey() + "':'" + message + "'");
}
};
//连接queue与consumer
channel.basicConsume(queueName, true, consumer);
}
}
Chapter5
exchange类型为topic,可以理解为routing key不再是简单的单词,而是由一系列由“.”断开的单词,可以是任意的单词,但是长度限制是255bytes。
package rabbitMQDemo.e_topic;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* producer
* 使用的exchange类型为direct
* @author gaomeiling
* @date 2018年10月19日
*/
public class EmitLogTopic {
private static final String EXCHANG_NAME = "topic_logs";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
String exchangeType = "topic";
channel.exchangeDeclare(EXCHANG_NAME, exchangeType);
String routingKey = "kern.you.critical";
String message = "say you!";
//连接producer与exchange
channel.basicPublish(EXCHANG_NAME, routingKey, null, message.getBytes());
System.out.println(" [x] Sent '" + routingKey + "':'" + message + "'");
channel.close();
connection.close();
}
}
package rabbitMQDemo.e_topic;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
/**
* consumer
* 使用的exchange类型为direct
* @author gaomeiling
* @date 2018年10月19日
*/
public class ReceiveLogsTopic {
private static final String EXCHANGE_NAME = "topic_logs";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
//声明exchange
String exchangeType = "topic";
channel.exchangeDeclare(EXCHANGE_NAME, exchangeType);
//声明queue
String queueName = channel.queueDeclare().getQueue();
//routing key
String[] args1 = new String[] {"kern.*"};
String[] args2 = new String[] {"kern.*","*.critical"};
String[] args3 = new String[] {"*.critical"};
String[] args4 = new String[] {"#"};
//绑定exchange与queue,给定routing key
for(String bindingKey : args3) {
channel.queueBind(queueName , EXCHANGE_NAME , bindingKey);
}
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
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(" [x] Received '" + envelope.getRoutingKey() + "':'" + message + "'");
}
};
//连接queue与consumer
channel.basicConsume(queueName, true, consumer);
}
}
Chapter6
相当于由客户端发送一段信息,经由服务端处理返回给客户端结果。
package rabbitMQDemo.f_RPC;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Envelope;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeoutException;
/**
* consumer
* @author gaomeiling
* @date 2018年10月22日
*/
public class RPCClient {
private Connection connection;
private Channel channel;
private String requestQueueName = "rpc_queue";
public RPCClient() throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
connection = factory.newConnection();
channel = connection.createChannel();
}
public String call(String message) throws IOException, InterruptedException {
final String corrId = UUID.randomUUID().toString();
String replyQueueName = channel.queueDeclare().getQueue();
AMQP.BasicProperties props = new AMQP.BasicProperties
.Builder()
.correlationId(corrId)
.replyTo(replyQueueName)
.build();
channel.basicPublish("", requestQueueName, props, message.getBytes("UTF-8"));
final BlockingQueue<String> response = new ArrayBlockingQueue<String>(1);
String ctag = channel.basicConsume(replyQueueName, true, new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
if (properties.getCorrelationId().equals(corrId)) {
response.offer(new String(body, "UTF-8"));
}
}
});
String result = response.take();
channel.basicCancel(ctag);
return result;
}
public void close() throws IOException {
connection.close();
}
public static void main(String[] argv) {
RPCClient fibonacciRpc = null;
String response = null;
try {
fibonacciRpc = new RPCClient();
for (int i = 0; i < 32; i++) {
String i_str = Integer.toString(i);
System.out.println(" [x] Requesting fib(" + i_str + ")");
response = fibonacciRpc.call(i_str);
System.out.println(" [.] Got '" + response + "'");
}
}
catch (IOException | TimeoutException | InterruptedException e) {
e.printStackTrace();
}
finally {
if (fibonacciRpc!= null) {
try {
fibonacciRpc.close();
}
catch (IOException _ignore) {}
}
}
}
}
package rabbitMQDemo.f_RPC;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
/**
* server
* @author gaomeiling
* @date 2018年10月19日
*/
public class RPCServer {
private static final String RPC_QUEUE_NAME = "rpc_queue";
//斐波那契函数
private static int fib(int n) {
if (n ==0) return 0;
if (n == 1) return 1;
return fib(n-1) + fib(n-2);
}
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = null;
try {
connection = factory.newConnection();
final Channel channel = connection.createChannel();
channel.queueDeclare(RPC_QUEUE_NAME, false, false, false, null);
channel.queuePurge(RPC_QUEUE_NAME);
channel.basicQos(1);
System.out.println(" [x] Awaiting RPC requests");
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope,
AMQP.BasicProperties properties, byte[] body) throws IOException {
AMQP.BasicProperties replyProps = new AMQP.BasicProperties
.Builder()
.correlationId(properties.getCorrelationId())
.build();
String response = "";
try {
String message = new String(body,"UTF-8");
int n = Integer.parseInt(message);
System.out.println(" [.] fib(" + message + ")");
response += fib(n);
}
catch (RuntimeException e){
System.out.println(" [.] " + e.toString());
}
finally {
channel.basicPublish( "", properties.getReplyTo(), replyProps, response.getBytes("UTF-8"));
channel.basicAck(envelope.getDeliveryTag(), false);
// RabbitMq consumer worker thread notifies the RPC server owner thread
synchronized(this) {
this.notify();
}
}
}
};
//连接queue与consumer
channel.basicConsume(RPC_QUEUE_NAME, false, consumer);
while (true) {
synchronized(consumer) {
try {
consumer.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} catch (IOException | TimeoutException e) {
e.printStackTrace();
}
finally {
if (connection != null)
try {
connection.close();
} catch (IOException _ignore) {}
}
}
}