RABBITMQ JAVA
来源:互联网 发布:线切割3b编程实例匕首 编辑:程序博客网 时间:2024/05/20 13:05
一:”Hello RabbitMQ”
下面有一幅图,其中P表示生产者,C表示消费者,红色部分为消息队列
客户端:
package rabbitmq;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[] argv) throws Exception { //创建连接工厂 ConnectionFactory factory = new ConnectionFactory(); //设置连接信息 factory.setHost("1y2812381"); factory.setUsername("wang"); factory.setPassword("wang"); //创建连接 Connection connection = factory.newConnection(); //打开通道 Channel channel = connection.createChannel(); //声明一个消息队列 /*注1:queueDeclare第一个参数表示队列名称、第二个参数为是否持久化(true表示是,队列将在服务器重启时生存) 、第三个参数为是否是独占队列(创建者可以使用的私有队列,断开后自动删除) 、第四个参数为当所有消费者客户端连接断开时是否自动删除队列、第五个参数为队列的其他参数*/ channel.queueDeclare(QUEUE_NAME, false, false, false, null); String message = "Hello World!"; //消息推送 /*注2:basicPublish第一个参数为交换机名称、第二个参数为队列映射的路由key 、第三个参数为消息的其他属性、第四个参数为发送信息的主体*/ channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8")); System.out.println(" [x] Sent '" + message + "'"); //关闭通道,断开连接 channel.close(); connection.close(); }}
接收端:
import com.rabbitmq.client.*;import java.io.IOException;public class Recv { private final static String QUEUE_NAME = "hello"; public static void main(String[] argv) throws Exception { // 创建连接工厂 ConnectionFactory factory = new ConnectionFactory(); // 设置连接信息 factory.setHost("1y2812381"); factory.setUsername("wang"); factory.setPassword("wang"); // 创建连接 Connection connection = factory.newConnection(); // 打开通道 Channel channel = connection.createChannel(); // 声明一个消息队列(此队列和发送端的队列信息保持一致,否则会报错(Channel Error)) channel.queueDeclare(QUEUE_NAME, false, false, false, null); System.out.println(" [*] Waiting for messages. To exit press CTRL+C"); // DefaultConsumer类实现了Consumer接口,通过传入一个频道, // 告诉服务器我们需要那个频道的消息,如果频道中有消息,就会执行回调函数handleDelivery 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 + "'"); } }; // 自动回复队列应答 -- RabbitMQ中的消息确认机制 // 第一个参数是消息队列,第二个参数是手动应答标志如果为true的话,每次生产者只要发送信息就会从内存中删除 // 第三个参数是消费者 channel.basicConsume(QUEUE_NAME, true, consumer); }}
二:实现任务分发
工作队列
一个队列的优点就是很容易处理并行化的工作能力,但是如果我们积累了大量的工作,我们就需要更多的工作者来处理,这里就要采用分布机制了。
发送端:
import com.rabbitmq.client.Channel;import com.rabbitmq.client.Connection;import com.rabbitmq.client.ConnectionFactory;import com.rabbitmq.client.MessageProperties;public class NewTask { private static final String TASK_QUEUE_NAME = "task_queue12"; public static void main(String[] argv) throws Exception { //创建工厂 ConnectionFactory factory = new ConnectionFactory(); //创建工厂连接信息 factory.setHost("1y2812381"); factory.setUsername("wang"); factory.setPassword("wang"); //创建连接 Connection connection = factory.newConnection(); //创建通道 Channel channel = connection.createChannel(); //创建队列 消息本地持久化 channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null); for (int i = 0; i < 10; i++) { String message = "hello" + i; channel.basicPublish("", TASK_QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes("UTF-8")); System.out.println(" [x] Sent '" + message + "'"); } channel.close(); connection.close(); }}
接收端1:
package rabbitmq;import com.rabbitmq.client.*;import java.io.IOException;public class Worker2 { private static final String TASK_QUEUE_NAME = "task_queue12"; public static void main(String[] argv) throws Exception { // 创建工厂 ConnectionFactory factory = new ConnectionFactory(); // 创建工厂连接信息 factory.setHost("1y2812381"); factory.setUsername("wang"); factory.setPassword("wang"); // 创建连接 Connection connection = factory.newConnection(); // 创建通道 Channel channel = connection.createChannel(); // 创建队列 消息本地持久化 channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null); System.out.println(" [*] Waiting for messages. To exit press CTRL+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); } finally { System.out.println(" [x] Done"); // channel.basicAck(envelope.getDeliveryTag(), false); } } }; //手动消息确认默认打开。在前面的例子中,我们明确地通过设置为true 标志关闭了它们。 //一旦我们完成了一项任务,现在是时候将这个标志设置为false,并且向工作人员发送一个正确的确认。 channel.basicConsume(TASK_QUEUE_NAME, false, consumer); } private static void doWork(String task) { try { Thread.sleep(1000); } catch (InterruptedException _ignored) { Thread.currentThread().interrupt(); } }}
接收端2和接收端1代码一样
三:发布/订阅
在上一篇说到的队列都指定了名称,但是现在我们不需要这么做,我们需要所有的日志信息,而不只是其中的一个。如果要做这样的队列,我们需要2件事,一个就是获取一个新的空的队列,这样我就需要创建一个随机名称的队列,最好让服务器帮我们做出选择,第一个就是我们断开用户的队列,应该自动进行删除。ok下面是一副工作图。
交换机有几种类型: direct, topic, headers and fanout.
XCHANGE_TYPE:fanout
//fanout表示分发,所有的消费者得到同样的队列信息
发送端:
package rabbitmq;import com.rabbitmq.client.BuiltinExchangeType;import com.rabbitmq.client.ConnectionFactory;import com.rabbitmq.client.Connection;import com.rabbitmq.client.Channel;public class EmitLog { private static final String EXCHANGE_NAME = "logs"; public static void main(String[] argv) throws Exception { //创建工厂 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("1y2812381"); factory.setUsername("wang"); factory.setPassword("wang"); //新建连接 Connection connection = factory.newConnection(); //新建通道 Channel channel = connection.createChannel(); //fanout表示分发,所有的消费者得到同样的队列信息 //建立交换机 第一个参数交换机名称 ,第二个参数交换机类型 channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT); String message = "hello"; //消息推送 channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes("UTF-8")); System.out.println(" [x] Sent '" + message + "'"); channel.close(); connection.close(); }}
接收端:
package rabbitmq;import com.rabbitmq.client.*;import java.io.IOException;public class Worker2 { private static final String EXCHANGE_NAME = "logsq"; public static void main(String[] argv) throws Exception { // 创建工厂 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("1y2812381"); factory.setUsername("wang"); factory.setPassword("wang"); // 新建连接 Connection connection = factory.newConnection(); // 新建通道 Channel channel = connection.createChannel(); //交换机信息设置 channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT); //系统随机生成对列名 String queueName = channel.queueDeclare().getQueue(); //对列绑定交换机 channel.queueBind(queueName, EXCHANGE_NAME, ""); 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 '" + message + "'"); } }; //队列会自动删除 channel.basicConsume(queueName, true, consumer); }}
XCHANGE_TYPE:direct
发送端:
package rabbitmq;import com.rabbitmq.client.BuiltinExchangeType;import com.rabbitmq.client.Channel;import com.rabbitmq.client.Connection;import com.rabbitmq.client.ConnectionFactory;import java.util.Random;import java.util.UUID;/** * 生产者根据routing 分别将信息发送给不同的消费者,如果没有消费者接受,那么消息将丢弃 */public class DirectProducer { // 交换名称 private static final String EXCHANGE_NAME = "ex_direct"; public static void main(String[] args) throws Exception { // 创建一个频道 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("1y2812381"); factory.setUsername("wang"); factory.setPassword("wang"); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); // 声明转发器的类型 channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT); String message = "123"; // 发布消息至转发器,指定routingkey channel.basicPublish(EXCHANGE_NAME, "severity", null, message.getBytes()); System.out.println(" [x] Sent '" + message + "'"); channel.close(); }}
接收端:
package rabbitmq;import java.io.IOException;import java.util.Random;import com.rabbitmq.client.AMQP;import com.rabbitmq.client.BuiltinExchangeType;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 DirectConsumer { private static final String EXCHANGE_NAME = "ex_direct"; public static void main(String[] args) throws Exception { // 创建一个频道 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("1y2812381"); factory.setUsername("wang"); factory.setPassword("wang"); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); // 声明direct类型转发器 channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT); String queueName = channel.queueDeclare().getQueue(); // 指定binding_key channel.queueBind(queueName, EXCHANGE_NAME, "severity"); System.out.println(" [*] Waiting for "+"severity"+" logs. 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 '" + message + "'"); } }; channel.basicConsume(queueName, true, consumer); }}
Topics
发送端:
package rabbitmq;import java.util.UUID; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; public class EmitLogTopic { private static final String EXCHANGE_NAME = "topic_logs"; public static void main(String[] argv) throws Exception { // 创建连接和频道 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("192.168.71.127"); factory.setUsername("wang"); factory.setPassword("wang"); //创建连接 Connection connection = factory.newConnection(); //创建通道 Channel channel = connection.createChannel(); //设置交换机主题类型 channel.exchangeDeclare(EXCHANGE_NAME, "topic"); String[] routing_keys = new String[] { "kernel.info.on", "cron.warning", "auth.info", "kernel.critical" }; //信息推送 for (String routing_key : routing_keys) { String msg = UUID.randomUUID().toString(); channel.basicPublish(EXCHANGE_NAME, routing_key, null, msg .getBytes()); System.out.println(" [x] Sent routingKey = "+routing_key+" ,msg = " + msg + "."); } channel.close(); connection.close(); } }
接收端1:
package rabbitmq;import java.io.IOException;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;import com.rabbitmq.client.QueueingConsumer; public class ReceiveLogsTopicForCritical{ private static final String EXCHANGE_NAME = "topic_logs"; public static void main(String[] argv) throws Exception { // 创建连接和频道 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("192.168.71.127"); factory.setUsername("wang"); factory.setPassword("wang"); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); // 声明转发器 channel.exchangeDeclare(EXCHANGE_NAME, "topic"); // 随机生成一个队列 String queueName = channel.queueDeclare().getQueue(); //接收所有与kernel相关的消息 * 代表一个单词 #代表一个或多个单词 channel.queueBind(queueName, EXCHANGE_NAME, "*.critical"); System.out.println(" [*] Waiting for critical 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 *.critical'"+envelope.getRoutingKey() + message + "'"); } }; channel.basicConsume(queueName, true, consumer); } }
接收端2:
package rabbitmq;import java.io.IOException;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;import com.rabbitmq.client.QueueingConsumer; public class ReceiveLogsTopicForKernel1 { private static final String EXCHANGE_NAME = "topic_logs"; public static void main(String[] argv) throws Exception { // 创建连接和频道 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("192.168.71.127"); factory.setUsername("wang"); factory.setPassword("wang"); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); // 声明转发器 channel.exchangeDeclare(EXCHANGE_NAME, "topic"); // 随机生成一个队列 String queueName = channel.queueDeclare().getQueue(); //接收所有与kernel相关的消息 * 代表一个单词 #代表一个或多个单词 channel.queueBind(queueName, EXCHANGE_NAME, "kernel.#"); System.out.println(" [*] Waiting for messages about kernel. 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 kernel.*'"+envelope.getRoutingKey() + message + "'"); } }; channel.basicConsume(queueName, true, consumer); }}
阅读全文
0 0
- RABBITMQ JAVA
- RabbitMQ(二) java简单的实现RabbitMQ
- java rabbitMQ demo
- rabbitmq java demo详解
- java rabbitMQ demo
- Java Message Service - RabbitMQ
- java访问rabbitMQ 一
- RabbitMQ初探-JAVA
- rabbitmq rpc java
- java的RabbitMQ 实例
- RabbitMQ java API中文翻译
- 用JAVA操作RabbitMQ
- RabbitMQ Java 实例
- RabbitMQ java Topics主题
- rabbitmq 路由 java实现
- rabbitmq RPC java实现
- RabbitMQ指南(Java)
- RabbitMQ的RPC【JAVA】
- SVN使用教程总结
- 如何在Recent App不显示某个应用
- android UI调试工具SwissArmyKnife
- eclipse插件和market市场下载过慢导致频繁失败问题解决
- hdfs工作机制
- RABBITMQ JAVA
- 欧拉角的计算
- redis、memcache和mongodb比较
- js获取当前时间,并格式化为"yyyy-MM-dd HH:mm:ss"
- java.net.SocketException: Connection reset
- outlook登陆邮件接收服务器(POP3)失败问题
- QT小结
- windows编程(2)-进程,线程
- 将string直接返回网页,不能作为json处理的解决方法