Rabbitmq的六种工作模式(附代码)

Rabbitmq的六种工作模式(附代码)

简单模式
pom依赖
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.tedu</groupId>
	<artifactId>rabbitmq</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<dependencies>
		<dependency>
			<groupId>com.rabbitmq</groupId>
			<artifactId>amqp-client</artifactId>
			<version>5.4.3</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>1.8.0-alpha2</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.8.0-alpha2</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.0</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

生产者发送消息
package rabbitmq.simple;

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 Sender {

	//生产者
	public static void main(String[] args) throws IOException, TimeoutException {
		//链接rabbitmq服务器
		ConnectionFactory f =new ConnectionFactory();
		f.setHost("192.168.64.140");
		f.setPort(5672);
		f.setUsername("admin");
		f.setPassword("admin");
		//创建连接
		Connection con = f.newConnection();
		//建立通道
		Channel c= con.createChannel();

		/*
		 * 声明队列,会在rabbitmq中创建一个队列
		 * 如果已经创建过该队列,就不能再使用其他参数来创建
		 * 
		 * 参数含义:
		 *   -queue: 队列名称
		 *   -durable: 队列持久化,true表示RabbitMQ重启后队列仍存在
		 *   -exclusive: 排他,true表示限制仅当前连接可用
		 *   -autoDelete: 当最后一个消费者断开后,是否删除队列
		 *   -arguments: 其他参数
		 */
		c.queueDeclare("hellworld", false, false, false, null);
		
		/*
		 * 发布消息
		 * 这里把消息向默认交换机发送.
		 * 默认交换机隐含与所有队列绑定,routing key即为队列名称
		 * 
		 * 参数含义:
		 * 	-exchange: 交换机名称,空串表示默认交换机"(AMQP default)",不能用 null 
		 * 	-routingKey: 对于默认交换机,路由键就是目标队列名称
		 * 	-props: 其他参数,例如头信息
		 * 	-body: 消息内容byte[]数组
		 */
		c.basicPublish("", "hellworld", null,
				   ("hellworld"+System.currentTimeMillis()).getBytes());
		System.out.println("消息已发送");
		
		//断开连接
		c.close();
		con.close();
		
	}
}

消费者接受消息
package rabbitmq.simple;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmq.client.Delivery;

public class Receive {

	//消费者
	public static void main(String[] args) throws IOException, TimeoutException {
		//连接rabbitmq服务器
		ConnectionFactory f = new ConnectionFactory();
		f.setHost("192.168.64.140");
		f.setPort(5672);
		f.setUsername("admin");
		f.setPassword("admin");
		
		//建立连接
		Connection con = f.newConnection();
		//建立连接通道
		Channel c = con.createChannel();
		 
	   //声明队列定义队列
		c.queueDeclare("hellworld", false, false, false, null);
		
		//收到消息后用来处理消息的回调
		DeliverCallback deliverCallback =new DeliverCallback() {
			
			@Override
			public void handle(String consumerTag, Delivery message) throws IOException {
				byte[] a = message.getBody();
				String s = new String(a);
				System.out.println("消息已收到:"+ s);
			}
		};
		//消费者取消时的回调函数
		CancelCallback cancelCallback = new CancelCallback() {
			@Override
			public void handle(String consumerTag) throws IOException {
				
			}
		};
		//开始消费消息
		c.basicConsume("hellworld",true , deliverCallback,cancelCallback);
	}
}

工作模式
生产者发送消息
package rabbitmq.workqueue;

import java.io.IOException;
import java.util.Scanner;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.MessageProperties;

public class Sender {

	//生产者
	public static void main(String[] args) throws IOException, TimeoutException {
		//链接rabbitmq服务器
		ConnectionFactory f =new ConnectionFactory();
		f.setHost("192.168.64.140");
		f.setPort(5672);
		f.setUsername("admin");
		f.setPassword("admin");
		//创建连接
		Connection con = f.newConnection();
		//建立通道
		Channel c= con.createChannel();

	    //声明队列
		c.queueDeclare("hellworld", false, false, false, null);
		while (true) {
			System.out.println("输入:");
			String s = new Scanner(System.in).nextLine();
			//发送消息
			c.basicPublish("", "hellworld", MessageProperties.PERSISTENT_TEXT_PLAIN,s.getBytes());
		}
		
		
	}
}

消费者接受消息
package rabbitmq.workqueue;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmq.client.Delivery;

public class Receive {

	//消费者
	public static void main(String[] args) throws IOException, TimeoutException {
		//连接rabbitmq服务器
		ConnectionFactory f = new ConnectionFactory();
		f.setHost("192.168.64.140");
		f.setPort(5672);
		f.setUsername("admin");
		f.setPassword("admin");
		
		//建立连接
		Connection con = f.newConnection();
		//建立连接通道
		Channel c = con.createChannel();
		 
	   //声明队列定义队列
		c.queueDeclare("hellworld", true, false, false, null);
		
		//收到消息后用来处理消息的回调
		DeliverCallback deliverCallback =new DeliverCallback() {
			
			@Override
			public void handle(String consumerTag, Delivery message) throws IOException {
				String s = new String(message.getBody());
				System.out.println("消息已收到:"+ s);
				for (int i = 0; i < s.length(); i++) {
					//每遇到一个.字符暂停一秒
					if (s.charAt(i)=='.') {
						try {
							Thread.sleep(1000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
				//手动ack操作,手动向服务器发送回执   false表示是否确认多条消息(否)
				c.basicAck(message.getEnvelope().getDeliveryTag(), false);
				System.out.println("消息处理结束---------------------\n");
			}
		};
		//消费者取消时的回调函数
		CancelCallback cancelCallback = new CancelCallback() {
			@Override
			public void handle(String consumerTag) throws IOException {
				
			}
		};
		//设置每次只接受一条数据
		c.basicQos(1);
		//开始消费消息
		//第二个参数true  自动ack  false  手动ack
		c.basicConsume("hellworld",false , deliverCallback,cancelCallback);
	}
}

合理分发
  • 手动 ack
    c.basicConsume(“队列”, false, …)
    c.basicAck(消息标签, false)
    qos=1, 每次只接收处理一条消息
  • 一条消息处理完成之前,不接收下一条消息
    c.basicQos(1)
  • 持久化
    队列持久化: c.queueDeclare(“队列名”, true, …)
    消息持久化: c.basicPublish("", “队列名”, MessageProperties.PERSISTENT_TEXT_PLAIN, 消息)
发布订阅模式

Exchanges 交换机

有几种可用的交换类型:direct、topic、header和fanout。我们将关注最后一个——fanout。让我们创建一个这种类型的交换机,并称之为 logs: ch.exchangeDeclare(“logs”, “fanout”);
fanout交换机非常简单。它只是将接收到的所有消息广播给它所知道的所有队列。这正是我们的日志系统所需要的。

fanout交换机

生产者
package rabbitmq.publishsubscribe;
import java.util.Scanner;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class Sender {

    //fanout交换机	
	public static void main(String[] args) throws Exception {
		//建立连接
		ConnectionFactory f = new ConnectionFactory();
		f.setHost("192.168.64.140");
		f.setPort(5672);
		f.setUsername("admin");
		f.setPassword("admin");
		
		//创建链接
		Connection con = f.newConnection();
		//建立通道
		Channel c = con.createChannel();
		
		//定义fanout类型的交换机,注意现在的生产者不定义队列
		//rabbitmq服务器中,如果交换机不存在则新建   反之,空操作
		c.exchangeDeclare("logs", "fanout");
		
		//向交换机发送数据
		while (true) {
			System.out.println("输入:");
			String msg = new Scanner(System.in).nextLine();
			/**
			 * 参数:1.交换机   2.指定队列,指定任何对列名无效
			 *     3.其他参数    4.消息
			 */
			c.basicPublish("logs", "", null, msg.getBytes());
		}
	}
}

消费者
package rabbitmq.publishsubscribe;

import java.io.IOException;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmq.client.Delivery;

public class Receive {

	public static void main(String[] args) throws Exception{
		//建立连接
		ConnectionFactory f = new ConnectionFactory();
		f.setHost("192.168.64.140");
		f.setPort(5672);
		f.setUsername("admin");
		f.setPassword("admin");
		
		//创建链接
		Connection con = f.newConnection();
		//建立通道
		Channel c = con.createChannel();
		
		
		//1.定义队列   fanout类型的队列   随机命名,非持久,独占,自动删除
		String queue = c.queueDeclare().getQueue();
		//2.定义交换机
		c.exchangeDeclare("logs", "fanout");
		//3.绑定
		c.queueBind(queue, "logs", "");//发布订阅模式中第三个参数无效
		
		DeliverCallback deliverCallback = new DeliverCallback() {
			@Override
			public void handle(String consumerTag, Delivery message) throws IOException {
                String msg = new String(message.getBody()); 
                System.out.println("收到:"+msg);
			}
		};
		CancelCallback cancelCallback = new CancelCallback() {
			@Override
			public void handle(String consumerTag) throws IOException {
			}
		};
		
		//消费数据
		c.basicConsume(queue, true, deliverCallback, cancelCallback);
	}
}

路由模式

直连交换机 Direct exchange

生产者
package rabbitmq.route;

import java.util.Scanner;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class Sender {

	//路由模式
	//直连交换机
	public static void main(String[] args) throws Exception{
		//建立连接
				ConnectionFactory f = new ConnectionFactory();
				f.setHost("192.168.64.140");
				f.setPort(5672);
				f.setUsername("admin");
				f.setPassword("admin");
				
				//创建链接
				Connection con = f.newConnection();
				//建立通道
				Channel c = con.createChannel();
				
				//定义交换机
				c.exchangeDeclare("direct-logs", BuiltinExchangeType.DIRECT);
				
				//发送消息
				while (true) {
				   System.out.println("输入消息:");	
				   String  msg = new Scanner(System.in).nextLine();
				   System.out.println("输入key:");	
				   String  key = new Scanner(System.in).nextLine();
				   c.basicPublish("direct-logs", key, null, msg.getBytes());
				   
				}
	}
}

消费者
package rabbitmq.route;

import java.io.IOException;
import java.util.Scanner;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmq.client.Delivery;

public class Receive {

	public static void main(String[] args) throws Exception{
		
		//建立连接
		ConnectionFactory f = new ConnectionFactory();
		f.setHost("192.168.64.140");
		f.setPort(5672);
		f.setUsername("admin");
		f.setPassword("admin");
		
		//创建链接
		Connection con = f.newConnection();
		//建立通道
		Channel c = con.createChannel();
		
		//定义队列
		String queue = c.queueDeclare().getQueue();
		//定义交换机
		c.exchangeDeclare("direct-logs", BuiltinExchangeType.DIRECT);
		//绑定
		System.out.println("输入绑定建,用空格隔开: ");
		String s = new Scanner(System.in).nextLine();
		String[] b = s.split("\\s+");
		for (String key : b) {
			c.queueBind(queue, "direct-logs", key);
		}
		
		DeliverCallback deliverCallback = new DeliverCallback() {
			@Override
			public void handle(String consumerTag, Delivery message) throws IOException {
              String msg = new String(message.getBody());
              String key = message.getEnvelope().getRoutingKey();
              System.out.println(key + "-" + msg);
			}
		};
		CancelCallback cancelCallback = new CancelCallback() {
			@Override
			public void handle(String consumerTag) throws IOException {
			}
		};
		c.basicConsume(queue, true, deliverCallback, cancelCallback);
			
	}
}

主题模式

主题交换机 Topic exchange

  • 使用* 可以通配单个单词。
  • 使用# 可以通配零个或多个单词。
    在这里插入图片描述
生产者
package rabbitmq.topic;

import java.util.Scanner;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class Sender {
	//主题模式(topic)
	public static void main(String[] args) throws Exception{
		//建立连接
		ConnectionFactory f = new ConnectionFactory();
		f.setHost("192.168.64.140");
		f.setPort(5672);
		f.setUsername("admin");
		f.setPassword("admin");
		
		//创建链接
		Connection con = f.newConnection();
		//建立通道
		Channel c = con.createChannel();
		//定义交换机
		c.exchangeDeclare("topic-logs", BuiltinExchangeType.TOPIC);
		
		while (true) {
			System.out.println("输入消息:");
			String msg = new Scanner(System.in).next();
			System.out.println("输入key:");
			String key = new Scanner(System.in).next();
			
			c.basicPublish("topic-logs", key, null, msg.getBytes());
		}
		
	}
}

消费者
package rabbitmq.topic;

import java.io.IOException;
import java.util.Scanner;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmq.client.Delivery;

public class Receive {

	public static void main(String[] args) throws Exception{
		//建立连接
				ConnectionFactory f = new ConnectionFactory();
				f.setHost("192.168.64.140");
				f.setPort(5672);
				f.setUsername("admin");
				f.setPassword("admin");
				
				//创建链接
				Connection con = f.newConnection();
				//建立通道
				Channel c = con.createChannel();
				//定义交换机
				c.exchangeDeclare("topic-logs", BuiltinExchangeType.TOPIC);
				//定义队列
				String queue = c.queueDeclare().getQueue();
				//绑定
				System.out.println("获取绑定建,用空格隔开:");
				String s = new Scanner(System.in).nextLine();
				String[] b = s.split("\\s+");
				for (String key : b) {
					c.queueBind(queue, "topic-logs", key);
				}
				DeliverCallback deliverCallback = new DeliverCallback() {
					@Override
					public void handle(String consumerTag, Delivery message) throws IOException {
						String msg = new String(message.getBody());
						String key = message.getEnvelope().getRoutingKey();
						System.out.println(key + "-" +msg);
					}
				};
				CancelCallback cancelCallback = new CancelCallback() {
					
					@Override
					public void handle(String consumerTag) throws IOException {
						// TODO Auto-generated method stub
						
					}
				};
				c.basicConsume(queue, true, deliverCallback, cancelCallback);
				
	}
}

RPC模式

在这里插入图片描述
RPC的工作方式:

  • 对于RPC请求,客户端发送一条带有两个属性的消息:replyTo,设置为仅为请求创建的匿名独占队列,和correlationId,设置为每个请求的惟一id值。
  • 请求被发送到rpc_queue队列
  • RPC工作进程(即:服务器)在队列上等待请求。当一个请求出现时,它执行任务,并使用replyTo字段中的队列将结果发回客户机
  • 客户机在回应消息队列上等待数据。当消息出现时,它检查correlationId属性。如果匹配请求中的值,则向程序返回该响应数据
服务端
package rabbitmq.rpc;

import java.io.IOException;

import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmq.client.Delivery;

public class RPCServer {

	public static void main(String[] args) throws Exception{
		//建立连接
		ConnectionFactory f = new ConnectionFactory();
		f.setHost("192.168.64.140");
		f.setPort(5672);
		f.setUsername("admin");
		f.setPassword("admin");
		
		//创建链接
		Connection con = f.newConnection();
		//建立通道
		Channel c = con.createChannel();
		//1.接收调用信息
		//2.执行业务运算
		//3.吧结果发回去
		//定义队列
		c.queueDeclare("rpc_queue", false, false, false, null);
		
		DeliverCallback deliverCallback = new DeliverCallback() {
			@Override
			public void handle(String consumerTag, Delivery message) throws IOException {
               String s = new String(message.getBody());
               int n = Integer.parseInt(s);
               //求第N个斐波那契数
               long r =fbnq(n);
               
               //去出返回队列名和关联id
               //replyTo返回队列名
               String replyTo = message.getProperties().getReplyTo();
               String correlationId  = message.getProperties().getCorrelationId();
               //将correlationId放置BasicProperties属性
               BasicProperties props = new BasicProperties().builder().correlationId(correlationId).build();
               c.basicPublish("", replyTo, props, (""+r).getBytes());
			}
		};
		CancelCallback cancelCallback = new CancelCallback() {
			@Override
			public void handle(String consumerTag) throws IOException {
			}
		};
		
		
		c.basicConsume("rpc_queue", true, deliverCallback, cancelCallback);
		
		
	}
	//求第n个斐波那契数
	//1,1,2,3,5,8.....
	static long fbnq(int n) {
		if (n == 1 || n == 2) {
			return 1;
		}
		return fbnq(n-1)+fbnq(n-2);
	}
	
}

客户端
package rabbitmq.rpc;

import java.io.IOException;
import java.util.Scanner;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeoutException;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmq.client.Delivery;
import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.CancelCallback;

public class RPCClient {
	public static BlockingQueue<Long> q =new ArrayBlockingQueue<>(10);

	public static void main(String[] args) throws Exception{
		System.out.println("求第几个斐波那契数:");
		int  n = new Scanner(System.in).nextInt();
		long  r = fbnq(n);
		System.out.println(r);
	}
	
	public static long fbnq(int n) throws Exception {
		//建立连接
		ConnectionFactory f = new ConnectionFactory();
				f.setHost("192.168.64.140");
				f.setPort(5672);
				f.setUsername("admin");
				f.setPassword("admin");
				
				//创建链接
				Connection con = f.newConnection();
				//建立通道
				Channel c = con.createChannel();
				
				//1.发送调用信息
				c.queueDeclare("rpc_queue", false, false, false, null);
				//返回队列名和关联id
				String replyTo = c.queueDeclare().getQueue();
				String correlationId = UUID.randomUUID().toString();
				//将返回队列名和关联id放置属性里面
				BasicProperties props = 
						new BasicProperties()
						.builder()
						.replyTo(replyTo)
						.correlationId(correlationId)
						.build();
				c.basicPublish("", "rpc_queue", props, (""+n).getBytes());
				
				//2.模拟继续执行主线程其他运算
				System.out.println("其他运算.........");
				//3.直到取到结果时,返回结果
				DeliverCallback deliverCallback = new DeliverCallback() {
					@Override
					public void handle(String consumerTag, Delivery message) throws IOException {
					//返回的斐波那契数结果与关联id
						String msg = new String(message.getBody());
						String cid = message.getProperties().getCorrelationId();
						if (cid.equals(correlationId)) {
							//消息处理线程放数据
							q.offer(Long.parseLong(msg));
						}
						try {
							c.close();
						} catch (Exception e) {
							e.printStackTrace();
						} 
						con.close();
					}
				};
				CancelCallback cancelCallback = new CancelCallback() {
					@Override
					public void handle(String consumerTag) throws IOException {
					}
				};
				
				c.basicConsume(replyTo,true, deliverCallback, cancelCallback);
				
				//主线程拿数据
				return q.take();
	}
}

virtual host

在RabbitMQ中叫做虚拟消息服务器VirtualHost,每个VirtualHost相当于一个相对独立的RabbitMQ服务器,每个VirtualHost之间是相互隔离的。exchange、queue、message不能互通

创建virtual host:
admin–virtual host:
在这里插入图片描述
在这里插入图片描述
Rabbmq(什么是RabbmitMQ,RabbmitMQ的六种工作模式)
RabbitMQ整合springboot(附代码)

最后
需要资料软件,解决问题可私信博主
更多参考精彩博文请看这里:RR-Shmily
喜欢博主的小伙伴可以加个关注、点个赞,欢迎评论哦,持续更新嘿嘿!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值