消息中间件介绍
笔记
windows安装:https://www.cnblogs.com/vaiyanzi/p/9531607.html
RabbitMQ用户角色分类
RabbitMQ各类角色描述:
none
不能访问 management plugin
management
用户可以通过AMQP做的任何事外加:
列出自己可以通过AMQP登入的virtual hosts
查看自己的virtual hosts中的queues, exchanges 和 bindings
查看和关闭自己的channels 和 connections
查看有关自己的virtual hosts的“全局”的统计信息,包含其他用户在这些virtual hosts中的活动。
policymaker
management可以做的任何事外加:
查看、创建和删除自己的virtual hosts所属的policies和parameters
monitoring
management可以做的任何事外加:
列出所有virtual hosts,包括他们不能登录的virtual hosts
查看其他用户的connections和channels
查看节点级别的数据如clustering和memory使用情况
查看真正的关于所有virtual hosts的全局的统计信息
administrator
policymaker和monitoring可以做的任何事外加:
创建和删除virtual hosts
查看、创建和删除users
查看创建和删除permissions
关闭其他用户的connections
不同的消息分发模式
1.简单模式

1.导入依赖
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.10.0</version>
</dependency>
2.消息生产者
public class Producer { public static void main(String[] args){ // 所有的中间件技术都是基于Tcp/ip协议基础之上构建新型的协议规范 // 只不过rabbitmq遵循的是amqp // 1.创建连接工程 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); factory.setPort(5672); factory.setUsername("guest"); factory.setPassword("guest"); factory.setVirtualHost("/"); // 2.创建连接Connection Connection connection = null; Channel channel = null; try { connection = factory.newConnection("生产者"); // 3.通过连接过去通道Channel channel = connection.createChannel(); // 4.通过通道创建交换机,声明队列,绑定关系,路由key,发送消息和接收消息 String queueName = "queue1"; // 队列名称,是否持久化,是否有排他性,是否自动删除, channel.queueDeclare(queueName,false,false,false,null); // 5.准备消息内容 String message = "你好,RabbitMQ"; // 6.发送消息给队列 channel.basicPublish("",queueName,null,message.getBytes()); System.out.println("消息发送成功!"); } catch (Exception e) { e.printStackTrace(); } finally { // 7.关闭连接 if (channel != null && channel.isOpen()){ try { channel.close(); } catch (Exception e){ e.printStackTrace(); } } // 8.关闭连接 if (connection != null && connection.isOpen()){ try { connection.close(); } catch (Exception e){ e.printStackTrace(); } } } } }
3.消息消费者
public class Consumer { public static void main(String[] args) { // 1.创建连接工程 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); factory.setPort(5672); factory.setUsername("guest"); factory.setPassword("guest"); factory.setVirtualHost("/"); // 2.创建连接Connection Connection connection = null; Channel channel = null; try { connection = factory.newConnection("消费者"); // 3.通过连接获取通道Channel channel = connection.createChannel(); // 4.通过通道创建交换机,声明队列,绑定关系,路由key,发送消息和接收消息 channel.basicConsume("queue1", true, new DeliverCallback() { @Override public void handle(String s, Delivery delivery) throws IOException { System.out.println("收到的消息是:\n" + new String(delivery.getBody(), "UTF-8")); } },new CancelCallback(){ @Override public void handle(String s) throws IOException { System.out.println("接受消息失败"); } }); /* DeliverCallback deliverCallback = (consumerTag, delivery) -> { String message = new String(delivery.getBody(), "UTF-8"); System.out.println(" [x] Received '" + message + "'"); }; channel.basicConsume("queue1", true, deliverCallback, consumerTag -> { }); */ } catch (Exception e) { e.printStackTrace(); } finally { // 7.关闭连接 if (channel != null && channel.isOpen()){ try { channel.close(); } catch (Exception e){ e.printStackTrace(); } } // 8.关闭连接 if (connection != null && connection.isOpen()){ try { connection.close(); } catch (Exception e){ e.printStackTrace(); } } } } }
2.fanout模式
发布订阅者模式,发布者发布消息,所有订阅的人都可以接收到消息
public class Producer { public static void main(String[] args){ // 所有的中间件技术都是基于Tcp/ip协议基础之上构建新型的协议规范 // 只不过rabbitmq遵循的是amqp // 1.创建连接工程 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); factory.setPort(5672); factory.setUsername("guest"); factory.setPassword("guest"); factory.setVirtualHost("/"); // 2.创建连接Connection Connection connection = null; Channel channel = null; try { connection = factory.newConnection("生产者"); // 3.通过连接过去通道Channel channel = connection.createChannel(); // 4.准备消息内容 String message = "fanout模式消息"; // 5.准备交换机 String exchangeName = "fanout-exchange"; // 6.定义路由 String routerKey = ""; // 7.指定交换机的类型 String type = "fanout"; // 8.发送消息给消息中间件rabbitmq-server,没有定义路由 channel.basicPublish(exchangeName,routerKey,null,message.getBytes()); System.out.println("消息发送成功!"); } catch (Exception e) { e.printStackTrace(); System.out.println("消息发送异常"); } finally { // 关闭连接 if (channel != null && channel.isOpen()){ try { channel.close(); } catch (Exception e){ e.printStackTrace(); } } // 关闭连接 if (connection != null && connection.isOpen()){ try { connection.close(); } catch (Exception e){ e.printStackTrace(); } } } } } =============================================================== // 线程开启三个队列接收消息 public class Consumer { public static void main(String[] args) { // Thread thread = new Thread(runnable,"queue1"); // thread.start(); new Thread(runnable,"queue1").start(); new Thread(runnable,"queue2").start(); new Thread(runnable,"queue3").start(); } private static Runnable runnable = new Runnable() { @Override public void run() { // 1.创建连接工程 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); factory.setPort(5672); factory.setUsername("guest"); factory.setPassword("guest"); factory.setVirtualHost("/"); final String queueName = Thread.currentThread().getName(); // 2.创建连接Connection Connection connection = null; Channel channel = null; try { connection = factory.newConnection("消费者"); // 3.通过连接过去通道Channel channel = connection.createChannel(); // 4.通过通道创建交换机,声明队列,绑定关系,路由key,发送消息和接收消息 channel.basicConsume(queueName, true, new DeliverCallback() { @Override public void handle(String s, Delivery delivery) throws IOException { System.out.println(queueName+"\n"+"收到的消息是:\n" + new String(delivery.getBody(), "UTF-8")); } },new CancelCallback(){ @Override public void handle(String s) throws IOException { System.out.println("接受消息失败"); } }); System.out.println("开始接收消息"); System.in.read(); /* 这是官网的原实现例子 DeliverCallback deliverCallback = (consumerTag, delivery) -> { String message = new String(delivery.getBody(), "UTF-8"); System.out.println(" [x] Received '" + message + "'"); }; channel.basicConsume("queue1", true, deliverCallback, consumerTag -> { }); */ } catch (Exception e) { e.printStackTrace(); System.out.println("接收异常"); } finally { // 关闭连接 if (channel != null && channel.isOpen()){ try { channel.close(); } catch (Exception e){ e.printStackTrace(); } } // 关闭连接 if (connection != null && connection.isOpen()){ try { connection.close(); } catch (Exception e){ e.printStackTrace(); } } } } }; }
3.Direct模式
在fanout模式基础上添加路由过滤
public class Producer { public static void main(String[] args){ // 所有的中间件技术都是基于Tcp/ip协议基础之上构建新型的协议规范 // 只不过rabbitmq遵循的是amqp // 1.创建连接工程 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); factory.setPort(5672); factory.setUsername("guest"); factory.setPassword("guest"); factory.setVirtualHost("/"); // 2.创建连接Connection Connection connection = null; Channel channel = null; try { connection = factory.newConnection("生产者"); // 3.通过连接过去通道Channel channel = connection.createChannel(); // 4.准备消息内容 String message = "routing模式"; // 5.准备交换机 String exchangeName = "direct_exchange"; // 6.定义路由 只有routerKey是email的订阅者才可以接收到消息 String routerKey = "email"; // 7.指定交换机的类型 String type = "direct"; // 8.发送消息给消息中间件rabbitmq-server channel.basicPublish(exchangeName,routerKey,null,message.getBytes()); System.out.println("消息发送成功!"); } catch (Exception e) { e.printStackTrace(); System.out.println("消息发送异常"); } finally { // 关闭连接 if (channel != null && channel.isOpen()){ try { channel.close(); } catch (Exception e){ e.printStackTrace(); } } // 关闭连接 if (connection != null && connection.isOpen()){ try { connection.close(); } catch (Exception e){ e.printStackTrace(); } } } } } ============= 接收方的实现与fanout相同
4.Topic模式
在Direct模式基础上添加匹配类型
* 代表至少有1个等级
# 代表可以有0个或多个等级
public class Producer { public static void main(String[] args){ // 所有的中间件技术都是基于Tcp/ip协议基础之上构建新型的协议规范 // 只不过rabbitmq遵循的是amqp // 1.创建连接工程 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); factory.setPort(5672); factory.setUsername("guest"); factory.setPassword("guest"); factory.setVirtualHost("/"); // 2.创建连接Connection Connection connection = null; Channel channel = null; try { connection = factory.newConnection("生产者"); // 3.通过连接过去通道Channel channel = connection.createChannel(); // 4.准备消息内容 String message = "topic模式"; // 5.准备交换机 String exchangeName = "topic_exchange"; // 6.定义路由 topic匹配模式,匹配com.# *.course.* #.order.# String routerKey = "com.course.order"; // 7.指定交换机的类型 String type = "topic"; // 8.发送消息给消息中间件rabbitmq-server channel.basicPublish(exchangeName,routerKey,null,message.getBytes()); System.out.println("消息发送成功!"); } catch (Exception e) { e.printStackTrace(); System.out.println("消息发送异常"); } finally { // 关闭连接 if (channel != null && channel.isOpen()){ try { channel.close(); } catch (Exception e){ e.printStackTrace(); } } // 关闭连接 if (connection != null && connection.isOpen()){ try { connection.close(); } catch (Exception e){ e.printStackTrace(); } } } } }
5.Headers模式
添加参数条件匹配
用代码声明交换机和队列并绑定
String exchangeName = "direct_message_exchange"; // 定义路由 String routerKey = "56test"; // 指定交换机的类型 String type = "direct"; // 声明交换机:exchangeDeclare(交换机名称,交换机模式,是否持久化) channel.exchangeDeclare(exchangeName,type,true); // 声明队列:queueDeclare(队列名称,是否持久化,是否具有排他性,是否自动删除,参数) channel.queueDeclare("queue5",true,false,false,null); channel.queueDeclare("queue6",true,false,false,null); channel.queueDeclare("queue7",true,false,false,null); // 绑定队列和交换机的关系 channel.queueBind("queue5",exchangeName,"56test"); channel.queueBind("queue6",exchangeName,"56test"); channel.queueBind("queue7",exchangeName,"nothing"); // 8.发送消息给消息中间件rabbitmq-server channel.basicPublish(exchangeName,routerKey,null,message.getBytes());
Work模式
1.轮询模式(均分)
不会因为服务器性能影响消费的数
一个消息分发者
public class Producer { public static void main(String[] args){ // 所有的中间件技术都是基于Tcp/ip协议基础之上构建新型的协议规范 // 只不过rabbitmq遵循的是amqp // 1.创建连接工程 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); factory.setPort(5672); factory.setUsername("guest"); factory.setPassword("guest"); factory.setVirtualHost("/"); // 2.创建连接Connection Connection connection = null; Channel channel = null; try { connection = factory.newConnection("生产者"); // 3.通过连接过去通道Channel channel = connection.createChannel(); for (int i = 0; i <= 20; i++) { String message = "work_lunXun"+i; // 8.发送消息给消息中间件rabbitmq-server channel.basicPublish("","queue1",null,message.getBytes()); } System.out.println("消息发送成功!"); } catch (Exception e) { e.printStackTrace(); System.out.println("消息发送异常"); } finally { // 关闭连接 if (channel != null && channel.isOpen()){ try { channel.close(); } catch (Exception e){ e.printStackTrace(); } } // 关闭连接 if (connection != null && connection.isOpen()){ try { connection.close(); } catch (Exception e){ e.printStackTrace(); } } } } }
两个消息接收者
public class Work1 { public static void main(String[] args) { // 1.创建连接工程 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); factory.setPort(5672); factory.setUsername("guest"); factory.setPassword("guest"); factory.setVirtualHost("/"); // 2.创建连接Connection Connection connection = null; Channel channel = null; try { connection = factory.newConnection("消费者-work1"); // 3.通过连接过去通道Channel channel = connection.createChannel(); // 4.通过通道创建交换机,声明队列,绑定关系,路由key,发送消息和接收消息 // channel.basicQos(1); channel.basicConsume("queue1", true, new DeliverCallback() { @Override public void handle(String s, Delivery delivery) throws IOException { System.out.println("Work1-收到的消息是:\n" + new String(delivery.getBody(), "UTF-8")); try { // 为什么要延时? Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } },new CancelCallback(){ @Override public void handle(String s) throws IOException { System.out.println("接受消息失败"); } }); System.out.println("Work1-开始接收消息"); System.in.read(); } catch (Exception e) { e.printStackTrace(); System.out.println("接收异常"); } finally { // 关闭连接 if (channel != null && channel.isOpen()){ try { channel.close(); } catch (Exception e){ e.printStackTrace(); } } // 关闭连接 if (connection != null && connection.isOpen()){ try { connection.close(); } catch (Exception e){ e.printStackTrace(); } } } } } public class Work2 { public static void main(String[] args) { // 1.创建连接工程 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); factory.setPort(5672); factory.setUsername("guest"); factory.setPassword("guest"); factory.setVirtualHost("/"); // 2.创建连接Connection Connection connection = null; Channel channel = null; try { connection = factory.newConnection("消费者-work2"); // 3.通过连接过去通道Channel channel = connection.createChannel(); // 4.通过通道创建交换机,声明队列,绑定关系,路由key,发送消息和接收消息 // channel.basicQos(1); channel.basicConsume("queue1", true, new DeliverCallback() { @Override public void handle(String s, Delivery delivery) throws IOException { System.out.println("Work2-收到的消息是:\n" + new String(delivery.getBody(), "UTF-8")); try { // 为什么要延时? Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } },new CancelCallback(){ @Override public void handle(String s) throws IOException { System.out.println("接受消息失败"); } }); System.out.println("Work2-开始接收消息"); System.in.read(); } catch (Exception e) { e.printStackTrace(); System.out.println("接收异常"); } finally { // 关闭连接 if (channel != null && channel.isOpen()){ try { channel.close(); } catch (Exception e){ e.printStackTrace(); } } // 关闭连接 if (connection != null && connection.isOpen()){ try { connection.close(); } catch (Exception e){ e.printStackTrace(); } } } } }
2.公平分发
服务器性能好的会偷任务执行
public class Producer { public static void main(String[] args){ // 所有的中间件技术都是基于Tcp/ip协议基础之上构建新型的协议规范 // 只不过rabbitmq遵循的是amqp // 1.创建连接工程 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); factory.setPort(5672); factory.setUsername("guest"); factory.setPassword("guest"); factory.setVirtualHost("/"); // 2.创建连接Connection Connection connection = null; Channel channel = null; try { connection = factory.newConnection("生产者"); // 3.通过连接过去通道Channel channel = connection.createChannel(); for (int i = 0; i <= 20; i++) { String message = "work_lunXun"+i; // 8.发送消息给消息中间件rabbitmq-server channel.basicPublish("","queue1",null,message.getBytes()); } System.out.println("消息发送成功!"); } catch (Exception e) { e.printStackTrace(); System.out.println("消息发送异常"); } finally { // 关闭连接 if (channel != null && channel.isOpen()){ try { channel.close(); } catch (Exception e){ e.printStackTrace(); } } // 关闭连接 if (connection != null && connection.isOpen()){ try { connection.close(); } catch (Exception e){ e.printStackTrace(); } } } } } ================================================ public class Work1 { public static void main(String[] args) { // 1.创建连接工程 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); factory.setPort(5672); factory.setUsername("guest"); factory.setPassword("guest"); factory.setVirtualHost("/"); // 2.创建连接Connection Connection connection = null; Channel channel = null; try { connection = factory.newConnection("消费者-work2"); // 3.通过连接过去通道Channel channel = connection.createChannel(); // 4.通过通道创建交换机,声明队列,绑定关系,路由key,发送消息和接收消息 channel.basicQos(2); Channel finalChannel = channel; /* 需要改成channel.basicConsume("queue1", false, new DeliverCallback() { * 原来: channel.basicConsume("queue1", true, new DeliverCallback() { * */ channel.basicConsume("queue1", false, new DeliverCallback() { @Override public void handle(String s, Delivery delivery) throws IOException { System.out.println("Work2-收到的消息是:\n" + new String(delivery.getBody(), "UTF-8")); try { // 为什么要延时?比较不同性能是否影响消费数量 Thread.sleep(5000); finalChannel.basicAck(delivery.getEnvelope().getDeliveryTag(),false); } catch (InterruptedException e) { e.printStackTrace(); } } },new CancelCallback(){ @Override public void handle(String s) throws IOException { System.out.println("接受消息失败"); } }); System.out.println("Work2-开始接收消息"); System.in.read(); /* DeliverCallback deliverCallback = (consumerTag, delivery) -> { String message = new String(delivery.getBody(), "UTF-8"); System.out.println(" [x] Received '" + message + "'"); }; channel.basicConsume("queue1", true, deliverCallback, consumerTag -> { }); */ } catch (Exception e) { e.printStackTrace(); System.out.println("接收异常"); } finally { // 关闭连接 if (channel != null && channel.isOpen()){ try { channel.close(); } catch (Exception e){ e.printStackTrace(); } } // 关闭连接 if (connection != null && connection.isOpen()){ try { connection.close(); } catch (Exception e){ e.printStackTrace(); } } } } } ============================ public class Work2 { public static void main(String[] args) { // 1.创建连接工程 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); factory.setPort(5672); factory.setUsername("guest"); factory.setPassword("guest"); factory.setVirtualHost("/"); // 2.创建连接Connection Connection connection = null; Channel channel = null; try { connection = factory.newConnection("消费者-work2"); // 3.通过连接过去通道Channel channel = connection.createChannel(); // 4.通过通道创建交换机,声明队列,绑定关系,路由key,发送消息和接收消息 channel.basicQos(2); // 下面内部类中也用到了channel,所以需要中间变量防止冲突 Channel finalChannel = channel; /* 需要改成channel.basicConsume("queue1", false, new DeliverCallback() { * 原来: channel.basicConsume("queue1", true, new DeliverCallback() { * */ channel.basicConsume("queue1", false, new DeliverCallback() { @Override public void handle(String s, Delivery delivery) throws IOException { System.out.println("Work2-收到的消息是:\n" + new String(delivery.getBody(), "UTF-8")); try { // 为什么要延时?比较不同性能是否影响消费数量 Thread.sleep(2000); finalChannel.basicAck(delivery.getEnvelope().getDeliveryTag(),false); } catch (InterruptedException e) { e.printStackTrace(); } } },new CancelCallback(){ @Override public void handle(String s) throws IOException { System.out.println("接受消息失败"); } }); System.out.println("Work2-开始接收消息"); System.in.read(); } catch (Exception e) { e.printStackTrace(); System.out.println("接收异常"); } finally { // 关闭连接 if (channel != null && channel.isOpen()){ try { channel.close(); } catch (Exception e){ e.printStackTrace(); } } // 关闭连接 if (connection != null && connection.isOpen()){ try { connection.close(); } catch (Exception e){ e.printStackTrace(); } } } } }
时间花在哪里,成就就在哪里

浙公网安备 33010602011771号