一、为什么使用消息队列
在实际工作当中,我们要面对各种厂商以不同技术实现的系统,把这些系统集成在一起就需要使用一个消息中间件来处理系统与系统之间的通信。引入消息队列会对我们的系统产生如下影响:
1、异构系统集成
在实际系统集成工作中常用方法:
- 数据库分享数据
- FTP等传文件的方式传递信息
- RPC
- Webservice、微服务等方式
上述方法都各有优缺点和使用场景。而消息队列提供了一个高可靠性、松耦合的方式进行系统集成。
2、减少系统瓶颈、增加系统伸缩性
在处理业务的时候,时常因为某一点处理不及时,而造成操作的堆积。这种堆积会造成多个模块等待造成性能问题的那一点处理,而产生成本的浪费。进一步会产生很多连锁反应,造成更严重后果。
消息队列将操作的产生和业务执行分离,系统间协作不需要是同步执行。我们可以通过技术手段获得比较繁忙的模块,并在此模块,通过横向扩展,增加/减少处理实例使得队列长度按我们需要的方向发展,以达到使系统能够灵活伸缩的目的。
3、提高最终用户生产率
异步特性使得用户在执行一个操作后不用等待执行完成即可进行一下一项操作。
4、提高系统灵活度
使用消息队列对程序进行抽象和解耦,在基于消息队列的系统结构中,每一个模块,子系统等都会被抽象为一个或多个能够发送或接收消息的点。
能够随着环境不同敏捷变化应对。
二、JMS模型讨论
JMS支持两种模型:点对点(Point-to-point)模型和发布/订阅 (publish-and-subscribe)模型
两种模型最大的不同是:点对点模型中,消息只会传递给一个端,而发布/订阅模式会把消息传递给所有订阅了的端(类似广播)。
1、点对点(Point-to-point)
p2p模型的消息接收者有且只有一个,发送和接收方通过一个叫做queue的虚拟通道进行通信,其中发送方被称为sender,接收方被称为receiver。尽管有可能有多个接收者连在一个队列上,mq的实现方会根据一定的算法(不同供应商可能选择不同算法),将消息传递给其中一个接收者。这个特性也常被用来实现负载均衡。
2、发布/订阅(Publish/Subscribe)
pub/sub模型中,消息的发送和接受者都可能有多个,发送和接收方通过一个叫做topic的虚拟通道进行通信,其中发送方被称为publisher,接收方被称为subscriber。在本模式中,订阅者可以有多个,且一条消息会传递给所有topic的订阅者,每个订阅者都会收到这条消息的一个副本。
pub/sub模式提供了比p2p模式更松散的耦合方式,消息的发送方不知道自己发送的消息会流向何方,也不知道消息会被怎样使用,实际上在这种场景下也不需要关心这些问题。publisher所知道的只是产生了一条消息以及传递给哪个topic,剩下的内容都与他无关了。
三、JMS API
JMS API本身并不是一个消息系统或组建,他只是客户端在连接消息系统的一组API抽象。使用JMS可以使得系统在连接消息系统的时候能超越message system的不同实现,使用同一套API。
JMS API分为以下三大块:
1、顶层抽象
- ConnectionFactory
- Destination
- Connection
- Session
- Message
- MessageProducer
- MessageConsumer
从JNDI或者直接创建连接工厂Connection Factory,有了连接工厂后,可通过连接工厂建立连接Connection。有了连接后,可在连接之上创建会话Session。有了会话,可使用会话创建消息Message、消息制造者Producer和消息消费者Consumer。然后创建出来的制造者和消费者就可以向Destination发送和接收消息了。
一个典型的Application只会建立一个连接。这里并不像JDBC中的数据库连接,需要维持一个连接池,这样可以节约资源。在这个连接上,我们可以创建出不同的会话Session,并维持了一个会话池Session pool,这些会话复用一个连接。
2、点对点模型抽象
- QueueConnectionFactory
- Queue
- QueueConnection
- QueueSession
- Message
- QueueSender
- QueueReceiver
接口逻辑同上,可以注意不同的部分,分别继承了顶层抽象对应接口,可从名称上发现。其中只有Message接口不变。
- ConnectionFactory -> QueueConnectionFactory
- Destination -> Queue
- Connection -> QueueConnection
- Session -> QueueSession
- Message -> Message
- MessageProducer -> QueueSender
- MessageConsumer -> QueueReceiver
3、发布/订阅模型抽象
- TopicConnectionFactory
- Topic
- TopicConnection
- TopicSession
- Message
- TopicPublisher
- TopicSubscriber
接口逻辑同上,可以注意不同的部分,分别继承了顶层抽象对应接口,可从名称上发现。其中只有Message接口不变。
- ConnectionFactory -> TopicConnectionFactory
- Destination -> Topic
- Connection -> TopicConnection
- Session -> TopicSession
- Message -> Message
- MessageProducer -> TopicPublisher
- MessageConsumer -> TopicSubscriber