在Spring Cloud 中,对消息中间件的支持, 做了比较完善的抽象, 让使用者直接可以通过注解完成消息的生产、消费,这也是Spring框架比较厉害的特性“海纳百川”!今天,我就以“王家大少爷到江南皮革厂买皮鞋”的故事,给大家演示一下,SpringCloud 中怎么使用RabbitMQ!
故事情节是:
有一天,王家大少爷,在逛王府井的时候,发现 江南皮革厂直销店在吆喝卖皮鞋,他大摇大摆的走进了店,店长踱步迎上,大少爷见店长如此热情,二话没说,预定了600双 真皮女士皮鞋,每一双的规格都不一样(大家懂的为什么会有这么多规格,哈哈!),并要求店长 七夕情人节前一天过来提货。随手摸出一张,镀金银行卡,店员赶快将pos机递上,“哔哔”刷卡走人了。 店长兴奋的给厂里下了订单。
经过厂里工人连夜加班, 终于在情人节前一天早上将货送到了店里。
在示例中我会给大家演示SpringCloud中两种消息的收发方式:
1)@Input、@Output 注解
2) @Qualifier、@StreamListener 注解
环境依赖:
名称 | 值 | 备注 |
---|---|---|
JDK | 1.8 | |
RabbitMQ | 3.5.6 | 这里有详细介绍 https://blog.csdn.net/qq_36918149/article/details/100006373 |
SpringCloud | Greenwich.SR1 |
2.1 江南皮革厂端
1) pom依赖(主要)
1.8
Greenwich.SR1
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-stream-binder-rabbit
2)配置文件
application.properties
#服务名称
spring.application.name=leather-service
#0表示服务器随机端口
server.port=0
#rabbitmq连接信息
spring.rabbitmq.host=10.6.1.21
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=3433
#rabbitmq 服务器会根据下面的配置,将生成newOrders.leather-service的队列,并绑定上 名称为newOrders的exchange
spring.cloud.stream.bindings.newOrders.group=leather-service
3)创建一个监听类 FactoryOrderListener
@Component
@Slf4j
public class FactoryOrderListener {
@Autowired
//表示连接exchange 为finishedOrders 的channel 主表发消息
@Qualifier("finishedOrders")
private MessageChannel finishedOrdersMessageChannel;
//表示消费exchange为:newOrders 的消息
@StreamListener("newOrders")
public void processNewOrder(Map newOrder) {
Map message = new HashMap<>();
log.info("江南皮革厂收到订单购买人:{},数量:{}", newOrder.get("buyerName"), newOrder.get("count"));
try {
Thread.sleep(10L);
} catch (Exception e) {
}
finishedOrdersMessageChannel.send(MessageBuilder.withPayload(newOrder).build());
}
}
备注:上面代码, 首先收到消息, 然后又发送了消息。
2.2 江南皮革直销店端
1) pom依赖(主要)
1.8
Greenwich.SR1
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
org.springframework.boot
spring-boot-starter-web
org.springframework.cloud
spring-cloud-stream-binder-rabbit
2)配置文件
application.properties
#服务名称
spring.application.name=waiter-service
#0表示服务器随机端口
server.port=8080
#rabbitmq连接信息
spring.rabbitmq.host=10.6.1.21
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=3433
#rabbitmq 服务器会根据下面的配置,将生成finishedOrders.waiter-service的队列,并绑定上 名称为finishedOrders的exchange
spring.cloud.stream.bindings.finishedOrders.group=waiter-service
3)定义生产、订阅消息的接口 Businessman
public interface Businessman {
String NEW_ORDERS = "newOrders";
String FINISHED_ORDERS = "finishedOrders";
@Input(FINISHED_ORDERS)
SubscribableChannel finishedOrders();
@Output(NEW_ORDERS)
MessageChannel newOrders();
}
备注:注意这个接口需要绑定到启动类上
4)定义生产、订阅消息的接口 Businessman
@SpringBootApplication
@EnableJpaRepositories
@EnableCaching
@EnableDiscoveryClient
@EnableBinding({Businessman.class})
public class WaiterServiceApplication implements WebMvcConfigurer {
public static void main(String[] args) {
SpringApplication.run(WaiterServiceApplication.class, args);
}
@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonBuilderCustomizer() {
return builder -> {
builder.indentOutput(true);
builder.timeZone(TimeZone.getTimeZone("Asia/Shanghai"));
};
}
}
备注:@EnableBinding({Businessman.class}) 这是绑定相应的消息类
5)对外接口 LeatherController
@RestController
@RequestMapping("/leather")
public class LeatherController {
@Autowired
private Businessman businessman;
/**
* 江南皮革厂直销店,拼命吆喝卖皮鞋,他们采用最流行的预定模式
*
* @param buyerName
* @param count
* @return
*/
@RequestMapping("/createOrder")
public String createOrder(String buyerName, Integer count) {
Map message = new HashMap<>();
message.put("buyerName", buyerName);
message.put("count", count + "");
boolean reuslt = businessman.newOrders().send(MessageBuilder.withPayload(message).build());
return String.format("Create Order {%s}", reuslt ? "成功!" : "失败!");
}
}
2.3 验证
1)在rabbitmq web 管理页面Queues、Exchanges
2)创建订单
3)工厂店端收到订单
4)直营店端收到皮鞋
1)、SpringCloud 中生产消息、消费消息,做了比较完善的封装;
2)、Spring 中对于RabbitMQ的一些设置,后期还需要详细研究一下;
3)、RabbitMQ 中的一些特性,需要后期详细研究一下;