赞
踩
作者简介:☕️大家好,我是intelligent_M,一个Java后端开发者!
当前专栏:intelligent_M—— 微服务(SpringCloud) ,CSDN博客。后续会更新Java相关技术栈以及链表哈希表二叉树…,回溯算法贪心算法…等等算法题。
创作不易 欢迎点赞评论!!!
我们先来看看什么是同步通讯和异步通讯。如图:
同步通讯:就如同打视频电话,双方的交互都是实时的。因此同一时刻你只能跟一个人打视频电话。
异步通讯:就如同发微信聊天,双方的交互不是实时的,你不需要立刻给对方回应。因此你可以多线操作,同时跟多人聊天。
两种方式各有优劣,打电话可以立即得到响应,但是你却不能跟多个人同时通话。发微信可以同时与多个人收发微信,但是往往响应会有延迟。
所以,如果我们的业务需要实时得到服务提供方的响应,则应该选择同步通讯(同步调用)。而如果我们追求更高的效率,并且不需要实时响应,则应该选择异步通讯(异步调用)。
目前的业务相对简单,但是随着业务规模扩大,产品的功能也在不断完善。也就是说每次有新的需求,现有支付逻辑都要跟着变化,代码经常变动,不符合开闭原则,拓展性不好。
由于我们采用了同步调用,调用者需要等待服务提供者执行完返回结果后,才能继续向下执行,也就是说每次远程调用,调用者都是阻塞等待状态。最终整个业务的响应时长就是每次远程调用的执行时长之和:
假如每个微服务的执行时长都是50ms,则最终整个业务的耗时可能高达300ms,性能太差了。
但是大家思考一下,我们假设用户余额充足,扣款已经成功,此时我们应该确保支付流水单更新为已支付,确保交易成功。毕竟收到手里的钱没道理再退回去吧。因此,这里不能因为短信通知、更新订单状态失败而回滚整个事务。
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
void testSendMessage2Queue() {
//队列名称
String queueName = "simple.queue";
//消息
String msg = "hello, amqp!";
//发送消息
rabbitTemplate.convertAndSend(queueName, msg);
}
@Slf4j//日志
@Component//注册为一个Bean
public class MqListener {
@RabbitListener(queues = "simple.queue")
public void listenSimpleQueue(String msg){
System.out.println("消费者收到了simple.queue的消息:【" + msg +"】");
}
}
@RabbitListener(queues = "fanout.queue1")
public void listenFanoutQueue1(String msg) throws InterruptedException {
System.out.println("消费者1 收到了 fanout.queue1的消息:【" + msg +"】");
}
@RabbitListener(queues = "fanout.queue2")
public void listenFanoutQueue2(String msg) throws InterruptedException {
System.out.println("消费者2 收到了 fanout.queue2的消息:【" + msg +"】");
}
@Test
void testSendFanout() {
String exchangeName = "hmall.fanout";
String msg = "hello, everyone!";
rabbitTemplate.convertAndSend(exchangeName, null, msg);
}
@RabbitListener(queues = "topic.queue1")
public void listenTopicQueue1(String msg) throws InterruptedException {
System.out.println("消费者1 收到了 topic.queue1的消息:【" + msg +"】");
}
@RabbitListener(queues = "topic.queue2")
public void listenTopicQueue2(String msg) throws InterruptedException {
System.out.println("消费者2 收到了 topic.queue2的消息:【" + msg +"】");
}
@Test
void testSendTopic() {
String exchangeName = "hmall.topic";
String msg = "今天天气挺不错,我的心情的挺好的";
rabbitTemplate.convertAndSend(exchangeName, "china.weather", msg);
}
@Configuration public class FanoutConfiguration { @Bean//声明fanout交换机 public FanoutExchange fanoutExchange(){ // ExchangeBuilder.fanoutExchange("").build(); return new FanoutExchange("hmall.fanout2"); } @Bean//声明队列 public Queue fanoutQueue3(){ // QueueBuilder.durable("ff").build();//durable 耐用的持久的(持久化把队列写入磁盘) return new Queue("fanout.queue3"); } @Bean//声明绑定关系 public Binding fanoutBinding3(Queue fanoutQueue3, FanoutExchange fanoutExchange){ return BindingBuilder.bind(fanoutQueue3).to(fanoutExchange); } @Bean//声明队列 public Queue fanoutQueue4(){ return new Queue("fanout.queue4"); } @Bean//声明绑定关系 public Binding fanoutBinding4(){ return BindingBuilder.bind(fanoutQueue4()).to(fanoutExchange()); } }
@RabbitListener(bindings = @QueueBinding( value = @Queue(name = "direct.queue1", durable = "true"), exchange = @Exchange(name = "hmall.direct", type = ExchangeTypes.DIRECT), key = {"red", "blue"} )) public void listenDirectQueue1(String msg) throws InterruptedException { System.out.println("消费者1 收到了 direct.queue1的消息:【" + msg +"】"); } @RabbitListener(bindings = @QueueBinding( value = @Queue(name = "direct.queue2", durable = "true"), exchange = @Exchange(name = "hmall.direct", type = ExchangeTypes.DIRECT), key = {"red", "yellow"} )) public void listenDirectQueue2(String msg) throws InterruptedException { System.out.println("消费者2 收到了 direct.queue2的消息:【" + msg +"】"); }
需求:测试利用SpringAMQP发送对象类型的消息
1.声明一个队列,名为object.queue
2.编写单元测试,向队列中直接发送一条消息,消息类型为Map
3.在控制台查看消息,总结问题
这里可以看到它对我们发送的消息做了序列化,jdk自带的对象字节流给我们的消息转成字节了
Spring的对消息对象的处理是由org.springframework.amqp.support.converter.MessageConverter来处理的。而默认实现是SimpleMessageConverter,基于JDK的ObjectOutputStream完成序列化。
存在以下问题
建议采用JSON序列化代替默认的JDK序列化,需要做两件事情
1.在publisher和consumer中都要引入依赖:
<!--Jackson-->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
@Bean
public MessageConverter jacksonMessageConvertor(){
return new Jackson2JsonMessageConverter();
}
看完本篇请前往SpringCloud微服务第五篇
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。