我们在开发程序的过程中,避免少不了使用队列,所以给大家介绍一下rabbitMq的使用。
RabbitMq是当前主要的消息中间件之一。RabbitMq是一个开源的AMQP实现,服务器端用Erlang语言编写,rabbitMq的强大是在于它支持多种客户端,C,PHP,JAVA等,而且支持AJAX。它的性质:易用性,扩展性,高可用性。
安装RabbitMq的方法在这里就不做介绍了。
安装完RabbitMq之后。输入http://ip:15672/就能看到一个后台管理页面
我们在这个页面中,可以创建交换机,创建队列,分配权限等等。还可以查看消费信息,推送率等。
rabbitMq工作机制流程图:
生产者产生推送消息到交换机,交换机根据队列名进行寻找相应的队列进行数据处理最后到消费者获取对应的监听消息。
RabbitMq共存在四种交换机:
分别是Direct exchange、Fanout exchange、Topic exchange、Headers exchange
Direct exchange:(直连交换机)处理路由键。需要将一个队列绑定在交换机上,并绑定一个routing key。当生产者推送消息的时候,routing key带着这个被推送的消息推送交换机,交换机根据这个routing key去寻找也绑定相同routing key的队列。
Fanout exchange:(扇形交换机) 不处理路由键。只需要简单的将队列绑定到交换机上。交换机在接收消息之后,会直接转发到绑定到他的所有队列。Fanout交换机转发消息是最快的.
Topic Exchange:(主题交换机)将路由键和某模式进行匹配
规则:""只能匹配一个词 "xxx.“只会匹配到"xxx.123”
"#"可以匹配到0个或多个词 "xxx.#“可以匹配到"xxx.123.456”
Headers exchange:(头交换机)不处理路由键。根据发送消息内容中的headers属性进行匹配。在绑定队列和交换机时指定一组键值对,当消息发送到rabbitMq时会获取到该消息的headers与交换机绑定时指定的键值对进行匹配。headers属性是一个键值对,可以是任何类型。而其他三种类型的路由键都是字符串形式
匹配规则x-match有下列两种类型:
x-match = all :表示所有的键值对都匹配才能接受到消息
x-match = any :表示只要有键值对匹配就能接受到消息
通过上面的描述我们知道了,要想使用队列一定要有生产者和消费者,所以代码如下:
<!--rabbitmq-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
在配置文件中添加如下配置:
spring.rabbitmq.addresses=xxxx:5672
spring.rabbitmq.username=账号
spring.rabbitmq.password=密码
spring.rabbitmq.template.mandatory=true
spring.rabbitmq.connection-timeout=10000
生产者具体代码如下:
@Configuration
public class RabbitmqConfig {
@Bean
public DirectExchange SendTaskSimpleExchange() {
return new DirectExchange(sendTaskSimpleExchange, true, false);
}
@Bean
public Binding bindingSimple() {
return BindingBuilder.bind(SimpleQueue()).to(SendTaskSimpleExchange()).with("simple.user");
}
@Bean
public Queue SimpleQueue() {
return new Queue(simpleUserQueue, true, false, false);
}
}
@Override
public void sendSimpleMq(MessageObject messageObject) {
String jsonString = JSON.toJSONString(messageObject);
messageSend.sendSimpleRmq(jsonString,sendTaskSimpleExchange);
}
@Component
public class MessageSend {
//创建普通队列
public void sendSimpleRmq(Object msg,String sendTaskSimpleExchange) {
// 构建correlationData 用于做可靠性投递得,ID:必须为全局唯一的 根据业务规则
String id = "";
try {
Long generateId = SnowflakeIdWorker.generateId();
id = String.valueOf(generateId);
} catch (Exception e) {
logger.error("SnowflakeIdWorker generate id is error:{}", e);
id = UUID.randomUUID().toString().replaceAll("-", "");
}
CorrelationData correlationData = new CorrelationData(id);
try {
rabbitTemplate.convertAndSend(sendTaskSimpleExchange,"simple.user", msg );
} catch (Exception e) {
sendMqExceptionLog.error("message:{},exchange:{},simpleExchangeTime:{},e:{}", sendTaskSimpleExchange,
msg, e);
}
}
}
消费者代码具体如下:
@Service
public class RcsSimpleConsumer {
@Autowired
AsynchronousRcsSimpleConsumer asynchronousRcsSimpleConsumer;
//添加普通队列的消息监听
@RabbitListener(queues = {"${simple.queue.name}"})//simpleUserQueue就是simple.queue.name
public void rcsQueue(String text, Channel channel){
asynchronousRcsSimpleConsumer.asynchronousRcsSimple(text,channel);
}
@Async//异步处理
public void asynchronousRcsSimple(String text, Channel channel) {
//消费的代码逻辑
}