JMS
java message service,定义的一种java消息规范
消息模型
1. 点对点/队列
1.1 消息生产者生产消息发送到queue中,然后消费者从queue中取出并且消费消息。
1,2 消息被消费以后,queue中不再存储,所以消息消费者不再消费已经被消费的消息。
1.3 queue支持存在多个消费者,但一个消息只会被一个消费者消费。
特点:每个消息只有一个消费者,消息在中间件中可以被持久化,发送者和消费者没有时间限制。
2. 发布者/订阅者
消息生产者(发布)将消息发布到topic中,同时有多个消息消费者(订阅)消费该消息。发布到topic的消息会被所有订阅者消费。
特点:每个消息可以被多个订阅者消费,消息分为持久订阅和非持久订阅。持久订阅:订阅关系确立后,消息就不会消失,不管订阅者是否在线;非持久订阅,订阅者必须保持在线才能接受到消息
实现JMS的消息中间件
常见有ActiveMQ、RocketMQ、RabbitMQ,Kafka等
消息中间件
- 分布式系统中完成消息的发送和接收的组件
作用:典型的异步处理;应用解耦;流量削锋;消息通讯
现有两个独立的系统A和B
异步处理:
A通过调用消息中间件的API,推送消息到消息中间件的主题或队列,且无需等待,
B通过向消息中间订阅或监听可以获取此消息。
A和B之间无需同步回应,整个过程是异步的
解耦:
A(发送者)和B(接收者)不需了解对方API,只需要确认消息
A和B不需要同时在线,不需要向对方回应
如:交易系统为了保持数据一致性,支付系统把支付结果放在消息中间件中,通知订单系统修改订单状态,完成解耦
流量削锋
当两个"上下游"系统处理能力存在差距时,利用消息队列做一个通用的"漏斗",进行限流控制。在下游有能力处理的时候,再进行分发。
如:用户在支付系统成功结账后,订单系统会通过短信系统向用户推送扣费通知。 短信系统可能由于短板效应,速度卡在网关上(每秒几百次请求),容易造成支付系统和短信系统的处理能力出现差异化。然而用户晚点收到短信,一般是不会有太大问题的。如果没有消息队列,两个系统可能存在定时、拥塞等问题。可以将消息队列当成可靠的消息暂存地,进行一定程度的消息堆积
利用中间件转储两个系统的通信内容,并在下游系统有能力处理这些消息的时候,再处理这些消息。
消息通讯
如:短信系统,邮件系统都是常见的利用中间件进行操作的实例
我在业务中常遇到一次性消费的问题,如某个流程是A用户给B用户开单或转发派单,每次操作都要求发送给B通知短信。当时没有用到中间件,只能在数据库中添加字段,标记是否已发送短信。开单时如果状态值是未发送,就发送一次短信,将状态值修改为已发送,发送成功后重新修改为未发送,防止下次操作不发送短信。
但这样有许多问题,第一数据库的字段不是能随便加的,第二会经常对数据库进行读写操作,给数据库带来压力,第三如果并发量增加,可能会造成短信平台拥堵,本系统与短信平台耦合性较高造成数据错误
因此如果能使用消息队列或成熟的消息件,就能利用中间件的特性良好的解决此问题。