文章目录
相关文章: 【同步通讯与异步通讯】
1、消息
消息的发送方,即生产者。消息的接收方,即消费者。同步通信就行打视频,等着对方接电话才能继续往下,而异步通信就像发消息,发完我就干其他事儿了,啥时候回随你。
![](https://file.jishuzhan.net/article/1710481960784105474/be4f364cf031e70384b6f0617692cb81.webp)
这种异步的模式,对应在生产中就是:
![](https://file.jishuzhan.net/article/1710481960784105474/b8cce1058a4197ed2a7d272e6fc6b23f.webp)
2、JMS
JMS(Java Message Service):它是
一个规范
,等同于JDBC规范,提供了与消息服务相关的API接口
JMS的消息模型有:
peer-2-peer
:点对点模型,消息发送到一个队列中,队列保存消息。队列的消息只能被一个消费者消费,或超时publish-subscribe
:发布订阅模型,消息可以被多个消费者消费,生产者和消费者完全独立,不需要感知对方的存在
JMS的消息种类有:
- TextMessage
- MapMessage
- BytesMessage
- StreamMessage
- ObjectMessage
- Message (只有消息头和属性)
JMS的实现技术有(类比实现JDBC的各个数据库驱动):ActiveMQ、Redis、HornetMQ、RabbitMQ、RocketMQ(没有完全遵守JMS规范)
3、AMQP
AMQP(advanced message queuing protocol):
一种协议
(高级消息队列协议,也是消息代理规范),规范了网络交换的数据格式
,兼容JMS。优点是具有跨平台性,服务器供应商,生产者、消费者可以使用不同的语言来实现
AMQP消息模型有:
- direct exchange
- fanout exchange
- topic exchange
- headers exchange
- system exchange
AMQP消息种类有:
- byte[](byte跨平台,字节哪儿都能通)
AMQP的实现技术有:RabbitMQ、StormMQ、RocketMQ
4、案例:模拟订单短信通知
正常的一个购物订单业务,包含流程很多,比如:
- 登录状态检测
- 生成主单
- 生成子单
- 库存检测与变更
- 积分变更
- 支付
- 短信通知
- 购物车维护
- 运单信息初始化
- 商品库存维护
- 会员维护
- ...
这里模拟下单后给用户异步发送通知短信,先不用MQ,用一个集合模拟MQ来实现这个业务:首先写消息处理的Service层,模拟消费队列中的信息,发送短信给用户
java
public interface MessageService {
/**
* 模拟往队列里放消息
* @param id
*/
void sendMessage(String id);
/**
* 模拟取消息,消费
*/
String doMessage();
}
java
@Service
@Slf4j
public class MessageServiceImpl implements MessageService {
private List<String> msgQueue = new ArrayList<>(); //用它模拟队列
@Override
public void sendMessage(String id) {
msgQueue.add(id);
log.info("待发送短信的订单已纳入处理队列,id:" + id);
}
@Override
public String doMessage() {
String id = msgQueue.remove(0);
log.info("已完成发送短信业务,订单id:" + id);
return id;
}
}
写订单业务的Service层,模拟下单后,把订单编号等信息放到队列中
java
public interface OrderService {
void order(String id);
}
java
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
@Resource
private MessageService messageService;
@Override
public void order(String id) {
//一系列操作,调用其他服务,处理业务
//...
log.info("订单处理开始...");
//短信消息处理
messageService.sendMessage(id);
log.info("订单处理结束...");
System.out.println(); //换行一下
}
}
完善下Controller层:
java
@RestController
@RequestMapping("/order")
public class OrderController {
@Resource
private OrderService orderService;
@PostMapping("{id}")
public void order(@PathVariable String id){
orderService.order(id);
}
}
java
@RestController
@RequestMapping("/msg")
public class MessageController {
@Resource
private MessageService messageService;
@PostMapping
public String doMsg(){
return messageService.doMessage();
}
}
看下效果,调用订单接口,处理业务并且订单编号被扔进队列:
![](https://file.jishuzhan.net/article/1710481960784105474/6841d7449e18e7bbc74445df738dc254.webp)
消费,完成短信发送:
再往下是整合各种MQ技术实现消息的发送与接收,分别为:
- ActiveMQ
- RabbitMQ
- RocketMQ
- Kafka
对上面的代码,换一个实现类,重写sendMessage和doMessage这两个消息发送与处理的方法,就相当于换了一种MQ的实现技术
。