JMS消息模型
JMS即Java Message Service
是Java平台的消息传递标准,用于实现消息中间件的通信。JMS提供了两种消息模型:点对点模型和发布订阅模型。
-
点对点模型:消息发送者发送消息,消息代理将其放入消息队列中,消息接受者从队列中获取消息,消息读取后被移除消息队列。每个消息都被发送到一个特定的队列,接收者从队列中获取消息。队列保留着消息,直到它们被消费或超时。
虽然可能有多个客户端在队列中侦听消息,但只有一个可以读取到消息,之后消息将不存在,其他消费者将无法读取。也就是说消息队列只有唯一一个发送者和接受者,但是并不能说只有一个接收者。
它的特点是每个消息只有一个消费者,即消息一旦被消费,消息就不在消息队列中;发送者和接收者之间在时间上没有依赖性,也就是说当发送者发送了消息之后,不管接收者有没有正在运行,它不会影响到消息被发送到队列;接收者在成功接收消息之后需向队列应答成功;
-
发布订阅模型:发布者将消息发送到主题
Topic
中,多个订阅者订阅这个主题,订阅者不断的去轮询监听消息队列中的消息,那么就会在消息到达的同时接收消息。它的特点是每个消息可以有多个消费者,消费完消息之后消息不会清除;发布者和订阅者之间有时间上的依赖性:针对某个主题的订阅者,它必须创建一个订阅之后,才能消费发布者的消息,而且为了消费消息,订阅者必须保持运行的状态。当然了缓和这种严格的时间相关性,JMS允许订阅者创建一个可持久化的订阅。这样即使订阅者没有运行,它也能接收到发布者的消息;
MQ概览
JMS定义了消息传递的标准接口。它并不是一个消息中间件,而是一个规范,用于与各种实现消息中间件,如ActiveMQ
、RabbitMQ
、RocketMQ
、Kafka
进行交互。
MQ即messagequeue
消息队列,是分布式系统的重要组件,主要解决异步消息,应用解耦,流量消峰等问题。从而实现高可用,高性能,可伸缩和最终一致性的架构。使用较多的MQ有,activeMQ
,rabbitMQ
,Kafka
。
- 异步消息处理:可以将一些非核心流程,如日志,短信,邮件等,通过MQ的方式异步去处理。这样做的好处是缩短主流程的响应时间,提升用户体验;
- 应用解耦:商品服务和订单服务之间。用户下单后,订单服务会通知商品服务。不使用MQ的情况是订单服务调用商品服务的接口,这样订单服务和商品服务之间是耦合的;使用MQ,订单服务完成持久化处理,将消息写入MQ消息队列中,返回用户订单下单成功,商品服务来订阅这个下单的消息,采用拉或推的方式获得下单信息,商品服务根据商品下单信息进行商品库存信息修改,这样当下单时商品服务不可用时,也不影响正常下单,这就完成了订单服务和商品服务之间的解耦;
- 流量消峰:秒杀活动流量过大,导致流量暴增,最终可能导致应用挂掉。一般会在应用前端加入消息队列来控制活动人数,假如消息队列超过最大数量,应该直接抛弃用户请求或者跳转到错误页面。秒杀业务根据消息队列中的请求信息在做后续的业务处理。比如在抢购时,可能一下子过来了10万个请求,但MQ只接受前100个用户的请求,超过100个不接收了。这样就成功限制了用户请求;
特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafka |
---|---|---|---|---|
单机吞吐量 | 万级,比 RocketMQ、Kafka 低一个数量级 | 同 ActiveMQ | 10 万级,支撑高吞吐 | 10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景 |
Topic 数量对吞吐量的影响 | 吞吐量基本稳定 | 吞吐量基本稳定 | Topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 Topic | Topic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 Topic 数量不要过多,如果要支撑大规模的 Topic,需要增加更多的机器资源 |
时效性 | ms 级 | 微秒级,这是 RabbitMQ 的一大特点,延迟最低 | ms 级 | 延迟在 ms 级以内 |
可用性 | 高,基于主从架构实现高可用 | 同 ActiveMQ | 非常高,分布式架构 | 非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用 |
消息可靠性 | 有较低的概率丢失数据 | 基本不丢 | 经过参数优化配置,可以做到 0 丢失 | 同 RocketMQ |
功能支持 | MQ 领域的功能极其完备 | 基于 Erlang 开发,并发能力很强,性能极好,延时很低 | MQ 功能较为完善,还是分布式的,扩展性好 | 功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用 |
消息模型 | 点对点和发布订阅 | 点对点和发布订阅 | 点对点和发布/订阅 | 发布/订阅 |
一般的业务系统要引入MQ,最早大家都用ActiveMQ
,但是现在确实大家用的不多了,没经过大规模吞吐量场景的验证,社区也不是很活跃,所以大家还是算了吧,我个人不推荐用这个了。
后来大家开始用RabbitMQ
,但是确实Erlang语言阻止了大量的Java工程师去深入研究和掌控它,对公司而言,几乎处于不可控的状态,但是确实人家是开源的,比较稳定的支持,活跃度也高。
不过现在确实越来越多的公司会去用RocketMQ
,确实很不错,毕竟是阿里出品,但社区可能有突然黄掉的风险,目前RocketMQ
已捐给Apache
,但GitHub
上的活跃度其实不算高,对自己公司技术实力有绝对自信的,推荐用RocketMQ
,否则回去老老实实用RabbitMQ
吧,人家有活跃的开源社区,绝对不会黄。
所以中小型公司,技术实力较为一般,技术挑战不是特别高,用RabbitMQ
是不错的选择。大型公司,基础架构研发实力较强,用RocketMQ
是很好的选择。如果是大数据领域的实时计算、日志采集等场景,用Kafka
是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。