在这里以订单服务为消息生产者,代码中都有详细的注释和说明,以下是示例:
添加依赖
首先,创建一个web工程(在这里我使用springboot2.0.2)。加入rabbitMQ所需要的依赖:
同时,我也添加了一些常用依赖
配置RabbitMQ
然后,我们需要在项目中配置RabbitMQ
1、配置连接信息
spring:
rabbitmq:
host: 116.85.38.99
port: 5672
username: xxxxx
password: xxxxx
2、配置消息交换机 exchange
新建一个配置类,配置一个消息交换机
package com.space.rbq.order.config;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 消息交换机配置 可以配置多个
* @author zhangww
* @date 2019/5/25 15:40
*/
@Configuration
public class ExchangeConfig {
/** 消息交换机1的名字*/
public final String EXCHANGE_01 = "first_exchange";
/**
* 1.定义direct exchange,绑定first_exchange
* 2.durable="true" 持久化交换机, rabbitmq重启的时候不需要创建新的交换机
* 3.direct交换器相对来说比较简单,匹配规则为:如果路由键匹配,消息就被投送到相关的队列
* fanout交换器中没有路由键的概念,他会把消息发送到所有绑定在此交换器上面的队列中。
* topic交换器你采用模糊匹配路由键的原则进行转发消息到队列中
*/
@Bean
public DirectExchange directExchange(){
DirectExchange directExchange = new DirectExchange(EXCHANGE_01,true,false);
return directExchange;
}
}
3、配置队列 queue
注:在这里,我们只使用到第一个队列 FirstQueue
package com.space.rbq.order.config;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* 队列配置 可以配置多个队列
* @author zhangww
* @date 2019/5/25 13:25
*/
@Configuration
public class QueueConfig {
/*对列名称*/
public static final String QUEUE_NAME1 = "first-queue";
public static final String QUEUE_NAME2 = "second-queue";
public static final String QUEUE_NAME3 = "third-queue";
@Bean
public Queue firstQueue() {
/**
durable="true" 持久化消息队列 , rabbitmq重启的时候不需要创建新的队列
auto-delete 表示消息队列没有在使用时将被自动删除 默认是false
exclusive 表示该消息队列是否只在当前connection生效,默认是false
*/
return new Queue(QUEUE_NAME1,true,false,false);
}
@Bean
public Queue secondQueue() {
return new Queue(QUEUE_NAME2,true,false,false);
}
@Bean
public Queue thirdQueue() {
// 配置 自动删除
Map
arguments.put("x-message-ttl", 60000);//60秒自动删除
return new Queue(QUEUE_NAME3,true,false,true,arguments);
}
}
4、将交换机和队列进行绑定
新建一个RabbitMQConfig配置类,将交换机和队列绑定
package com.space.rbq.order.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* RabbitMq配置
* @author zhangww
* @date 2019/5/25 13:37
*/
@Configuration
public class RabbitMqConfig {
/**
* key: queue在该direct-exchange中的key值,当消息发送给direct-exchange中指定key为设置值时,
* 消息将会转发给queue参数指定的消息队列
*/
/** 队列key1*/
public static final String ROUTING_KEY_1 = "queue_one_key1";
@Autowired
private QueueConfig queueConfig;
@Autowired
private ExchangeConfig exchangeConfig;
/**
* 将消息队列1和交换机1进行绑定,指定队列key1
*/
@Bean
public Binding binding_one() {
return BindingBuilder.bind(queueConfig.firstQueue()).to(exchangeConfig.directExchange()).with(RabbitMqConfig.ROUTING_KEY_1);
}
}
这样,我们就完成了RabbitMq的配置,并且成功创建了消息交换机和队列,将其进行绑定。
发送消息
新建一个Order类,模拟订单。同时新建一个OrderController,用于发送消息。
package com.space.rbq.order.bean;
import lombok.Data;
import java.io.Serializable;
/**
* Order
* @author zhangww
* @date 2019/6/7 9:49
*/
@Data
public class Order implements Serializable{
private Long id;
private Double price;
private String remark;
}
package com.space.rbq.order.controller;
import com.google.gson.Gson;
import com.space.rbq.order.bean.Order;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
/**
* @author zhangww
* @date 2019/6/7 9:48
*/
@Slf4j
@RequestMapping("/order")
@RestController
public class OrderController {
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 保存order , 同时需要向store服务发送通知减库存
* @param order
* @return
*/
@PostMapping("/save")
public Order saveOrder(Order order){
log.info(order.toString());
Gson gson = new Gson();
//将order转换为json字符串,便于传输
String json = gson.toJson(order);
String msgId = UUID.randomUUID().toString();
/**
* 发送消息
* 指定消息交换机 "first_exchange"
* 指定队列key "queue_one_key1"
*/
rabbitTemplate.convertAndSend("first_exchange", "queue_one_key1",
json, new CorrelationData(msgId));
return order;
}
}
RabbitTemplate是springboot整合rabbitMq为我们默认提供的。里面有一些默认的配置和方法,我们可以直接使用它来发送消息。我们可以大概看看
调用convertAndSend方法就可以发送消息。在这里需要指定消息交换机和key。这样就可以将消息发送给指定的队列了(队列和交换机通过key在之前已经绑定过了)
此时,我们只需要启动工程,调用saveOrder接口,就可以成功将消息发送出去。
至此,就成功实现了消息的发送。下节,我们会通过库存服务订阅该消息,实现消息的消费。