Topic交换器-编写消费者

我们接着来编写Consumer,回到我们的代码当中,打开我们的topic-consumer,配置文件我们已经改完了,

先放到这里,看我们的代码,我们先改第一个InfoReceiver,InfoReceive这一块我们需要改什么呢,还是@RabbitListener这,

首先第一个,像队列的名称我们不需要动,队列名称我们还是叫log.info,我们给他准备了三个队列,log.info,log.error,

和全日志的队列,这两个我们都不要动,所以这里不用动,交换器我们也不用动,我们已经把后面的value改成log.topic了

mq.config.exchange=log.topic

但是这里得改,这个type得改

type=ExchangeTypes.TOPIC

现在这个type里面给定的还是direct交换器,我们要把它改成TOPIC,所以一定要注意,然后接下来就是key,我们用的是完全匹配

的路由key,那么我们在这个交换器,在这个队列当中,接收什么样的消息呢,只要是你log.info的,不管你是user的还是product的,

还是order的,只要是log.info的,都会进入到这里,那么前面的前缀,就得去匹配,所以我们这个key就是*.log.info

看到了吗,也就是我们这个路由key,其实给的就是*.log.info,能明白吧,这样消息队列就会根据后缀进行模糊匹配,只要是后缀

相同的,就把消息发送到这个队列当中,那么这个队列是谁呢,就是我们的log.info了,这样我们就把一个infoReceive就改好了,

接下来还有Error,Error也是这样的,首先我们要把交换器类型改成Topic,其次是这个key,这个key我们看一下,是*.log.error,

拥有log.error的key,就会进入到这个队列当中

key="*.log.error"

注意这一块我是直接写死到里面的,我之所以这么做的目的呢,就是可以直观的看到怎么去写他的通配,其实如果我们是在真正的

开发过程当中,这些也是可以放到properties文件当中的,这样我们就设置了第二个消息队列的这样的一个路由key,接下来我们

是不是还有一个全日志队列,我们再copy一个,这个我们叫LogsReceiver,然后打开他,这里我们有什么要改的呢,看一下,配置文件,

这个队列名称,是不是已经改了

mq.config.queue.logs=log.all

这个在原本拷贝的例子里是没有的,要换成这个队列名称,然后其次就是他的交换器,交换器不用动,还是Topic,然后就是这个路由key,

在全日志的处理当中,只要你路由key含有log的消息,是不是都会进入到这里,所以这块我们得改成*.log.*

key="*.log.*"

只要你的路由key中含有log,都会进入到我们的全队列当中,这样我们这块就改完了,然后我们还有什么需要改动,现在这一块,

这块到底打印的是什么信息,这块我们还得改一下,这个我们是叫all receiver

public class LogsReceiver {

	/**
	 * 接收消息的方法。采用消息队列监听机制
	 * @param msg
	 */
	@RabbitHandler
	public void process(String msg){
		System.out.println("......All........receiver: "+msg);
	}
}

这表示消息队列打印的前缀,再加后面的消息,我们把这个copy一下,我们把这几个改一下

public class ErrorReceiver {

	/**
	 * 接收消息的方法。采用消息队列监听机制
	 * @param msg
	 */
	@RabbitHandler
	public void process(String msg){
		System.out.println("......Error........receiver: "+msg);
	}
}

这个是error,然后info

public class InfoReceiver {

	/**
	 * 接收消息的方法。采用消息队列监听机制
	 * @param msg
	 */
	@RabbitHandler
	public void process(String msg){
		System.out.println("......Info........receiver: "+msg);
	}
}

这样我们的Consumer的代码就写好了,然后我们把它整理到笔记当中,这个是info里面的代码,然后这里需要注意的,

一个是这个,type=ExchangeTypes.TOPIC,还有一个是key="*.log.info"这个,然后第二个,ErrorReceiver,把它copy下来

放到我们的笔记当中,然后这里需要注意的是,type=ExchangeTypes.TOPIC,还有一个是key,key="*.log.error",然后最后

一个是LogsReceiver,这里也是type=ExchangeTypes.TOPIC,还有key="*.log.*",这样我们的consumer代码就写好了,

接下来我们就测试我们的是否可用,回到我们的Provider当中,我们要去修改一下我们的测试代码,现在我们的代码

就不用while循环了,我们直接发送消息就行了,现在这个是UserSender,我们还有OrderSender,还有ProductSender,

都得注入进来,

@Autowired
private UserSender usersender;

@Autowired
private ProductSender productsender;

@Autowired
private OrderSender ordersender;

我们需要把ProductSender注入进来,然后还有一个,OrderSender,然后我们让这三个服务都去发送消息,

@Test
public void test1(){
	this.usersender.send("UserSender.....");
	this.productsender.send("ProductSender....");
	this.ordersender.send("OrderSender......");
}

这样是12条消息,应该是12条消息,每个里面有四个,然后我们三个都发一遍,接下来我们就来测试一下,代码是否可用,

我们把接收者启动,就是topic-consumer,然后我们再去运行我们的测试类,运行我们的测试代码,我们观察控制台,这个时候

我们可以看到,消息拿到了,我们先看info的,这是我的info Receiver,

......All........receiver: user.log.debug.....UserSender.....
......Info........receiver: user.log.info.....UserSender.....
......Error........receiver: user.log.error.....UserSender.....
......Info........receiver: product.log.info.....ProductSender....
......Error........receiver: product.log.error.....ProductSender....
......All........receiver: user.log.info.....UserSender.....
......Info........receiver: order.log.info.....OrderSender......
......Error........receiver: order.log.error.....OrderSender......
......All........receiver: user.log.warn.....UserSender.....
......All........receiver: user.log.error.....UserSender.....
......All........receiver: product.log.debug.....ProductSender....
......All........receiver: product.log.info.....ProductSender....
......All........receiver: product.log.warn.....ProductSender....
......All........receiver: product.log.error.....ProductSender....
......All........receiver: order.log.debug.....OrderSender......
......All........receiver: order.log.info.....OrderSender......
......All........receiver: order.log.warn.....OrderSender......
......All........receiver: order.log.error.....OrderSender......

由于我们ALL当中配的是什么,我们配的是key="*.log.*",那么也就意味着,只要你的路由key当中,含有log,是不是都会进入到这个

队列当中,是不是都会进入到这个队列当中,那么这里的信息肯定是最多的,应该有几个,12条信息就对了,所以说呢,在*.log.*里面,

他就是把所有的消息都放在全日志的级别当中,所以以上我们通过这个案例,就演示了对Topic的一个使用,topic最大的一个特点是什么呢,

可以节省我们的队列,是某一部分的消息,可以对应一个队列,这样可以降低我们队列的一个数量,其实你细想这个问题也是这样的,

我这个队列只是记录log.info的信息,我管你是用户的log.info,还是商品的log.info,还是订单的log.info,只要是你产生的

log.info的信息,都放到我这个队列里就可以了,所以对于这样的一个需求呢,我们就得通过topic交换器来实现了,

并且配置这种通配的路由key,所以说topic的交换器呢,他也叫规则匹配,那个星号就是规则,测试代码我们也加进去了,

那么对于topic的交换器我们就讲解完了

  4.0.0
  com.learn
  rabbitmq-topic-consumer
  0.0.1-SNAPSHOT
  jar
  
	
		org.springframework.boot
		spring-boot-starter-parent
		1.5.12.RELEASE
		 
	
	
	
		UTF-8
		UTF-8
		1.8
		3.0.9.RELEASE
		2.2.2
	
	
	
		
			org.springframework.boot
			spring-boot-starter-amqp
		
		
			org.springframework.boot
			spring-boot-starter-web
		
		
			org.springframework.boot
			spring-boot-starter-test
			test
		
	
	
	
	
	    
	        
	            org.springframework.boot
	            spring-boot-maven-plugin
	        
	    
	
  
  
spring.application.name=rabbitmq-topic-consumer

spring.rabbitmq.host=59.110.158.145
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

mq.config.exchange=log.topic
mq.config.queue.info=log.info
mq.config.queue.error=log.error
mq.config.queue.logs=log.all
package com.learn;

import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * 消息接收者
 * @author Administrator
 * @RabbitListener bindings:绑定队列
 * @QueueBinding  value:绑定队列的名称
 *                exchange:配置交换器
 * 
 * @Queue value:配置队列名称
 *        autoDelete:是否是一个可删除的临时队列
 * 
 * @Exchange value:为交换器起个名称
 *           type:指定具体的交换器类型
 */
@Component
@RabbitListener(
			bindings=@QueueBinding(
					value=@Queue(value="${mq.config.queue.info}",autoDelete="true"),
					exchange=@Exchange(value="${mq.config.exchange}",type=ExchangeTypes.TOPIC),
					key="*.log.info"
			)
		)
public class InfoReceiver {

	/**
	 * 接收消息的方法。采用消息队列监听机制
	 * @param msg
	 */
	@RabbitHandler
	public void process(String msg){
		System.out.println("......Info........receiver: "+msg);
	}
}
package com.learn;

import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * 消息接收者
 * @author Administrator
 * @RabbitListener bindings:绑定队列
 * @QueueBinding  value:绑定队列的名称
 *                exchange:配置交换器
 * 
 * @Queue value:配置队列名称
 *        autoDelete:是否是一个可删除的临时队列
 * 
 * @Exchange value:为交换器起个名称
 *           type:指定具体的交换器类型
 */
@Component
@RabbitListener(
			bindings=@QueueBinding(
					value=@Queue(value="${mq.config.queue.error}",autoDelete="true"),
					exchange=@Exchange(value="${mq.config.exchange}",type=ExchangeTypes.TOPIC),
					key="*.log.error"
			)
		)
public class ErrorReceiver {

	/**
	 * 接收消息的方法。采用消息队列监听机制
	 * @param msg
	 */
	@RabbitHandler
	public void process(String msg){
		System.out.println("......Error........receiver: "+msg);
	}
}
package com.learn;

import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * 消息接收者
 * @author Administrator
 * @RabbitListener bindings:绑定队列
 * @QueueBinding  value:绑定队列的名称
 *                exchange:配置交换器
 * 
 * @Queue value:配置队列名称
 *        autoDelete:是否是一个可删除的临时队列
 * 
 * @Exchange value:为交换器起个名称
 *           type:指定具体的交换器类型
 */
@Component
@RabbitListener(
			bindings=@QueueBinding(
					value=@Queue(value="${mq.config.queue.logs}",autoDelete="true"),
					exchange=@Exchange(value="${mq.config.exchange}",type=ExchangeTypes.TOPIC),
					key="*.log.*"
			)
		)
public class LogsReceiver {

	/**
	 * 接收消息的方法。采用消息队列监听机制
	 * @param msg
	 */
	@RabbitHandler
	public void process(String msg){
		System.out.println("......All........receiver: "+msg);
	}
}
package com.learn;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RabbitTopicConsumerApplication {

	public static void main(String[] args) {
		SpringApplication.run(RabbitTopicConsumerApplication.class, args);
	}
}

 

你可能感兴趣的:(Topic交换器-编写消费者)