想想生活中的邮局,我们将信件发送给邮局,邮局再根据我们填写的收件人,最终将信件发送到每个收件人手中。
RabbitMQ的原理类似邮局,最大不同的是RabbitMQ没有使用纸张来作为信件,而是使用数据来代替—messages
邮局有邮局的术语,如信件,信箱等等。RabbitMQ也有自己的术语:
message:消息,类似于邮局中的信件 |
queue:队列,类似于邮局中的信箱,消息可能贯穿整个application,但是可以存储在queue中。 |
Producer:生产者,类似于邮局中的发件人,产生消息。 |
Consumer:消费者,类似于邮局中的收件人,接受(消费)消息。 |
下面这幅图,给出了RabbitMQ的入门程序的原理:
生产者产生消息,消费者消费消息。
下面我们将用代码来实现,首先我们需要添加jar包。
下载地址:http://www.rabbitmq.com/download.html
另外,由于RabbitMQ的运行需要记录日志,我们还需要下载日志的jar包:
下载地址:
http://central.maven.org/maven2/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar
http://central.maven.org/maven2/org/slf4j/slf4j-simple/1.7.22/slf4j-simple-1.7.22.jar
在src下新建logback.xml
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%npattern>
encoder>
appender>
<root level="debug">
<appender-ref ref="STDOUT" />
root>
configuration>
新建发送端程序Send.java:
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class Send {
private final static 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);
//定义消息
String message = "this is a message";
// 发送消息
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
// 断开连接
channel.close();
connection.close();
}
}
新建接受者Recv.java
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.AMQP.BasicProperties;
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;
public class Recv {
private final static String QUEUE_NAME = "hello";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection conection = factory.newConnection();
Channel channel = conection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//创建消费者,在回调函数中处理结果
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
throws IOException {
String message = new String(body, "UTF-8");
System.out.println("从队列"+QUEUE_NAME+"接受到:" + message);
}
};
channel.basicConsume(QUEUE_NAME, true, consumer);
}
}
运行说明:如果有条件的建议用两个ide,如IDEA运行发送端,eclipse运行接收端。 |
如果没有条件的,建议先运行Send.java,再运行Recv.java,运行结果:
当然,被消费了,消息也就不存在了。
如果想再次体验,需要首先结束Recv.java,再重新运行Send.java,否则可能会因为eclipse的console的覆盖问题,看不到运行结果。当然,如果有IDEA那就无需担心了。
下一篇,我们将实现work模式:一个生产者,多个消费者。
【若有笔误还望指出】