1.JMS是什么
JMS:(Java Message Service缩写)Java消息服务
- 是JAVA EE中一个重要规范:消息通信规范
- 是一个Java平台中关于面向消息中间件(MOM)与厂商无关的API,就如JDBC用来访问许多不同关系数据库(mysql,sqlserver,oracle等)的
API,而 JMS 则提供同样与厂商无关的访问方法,以访问消息收发服务
2.JMS作用
用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信,即用来访问消息收发系统消息。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持(百度得来)。JMS的客户端之间可以通过JMS服务进行异步的消息传输
3.消息模型
java消息服务应用程序结构支持两种模型:
- Point-to-Point:点对点或队列模型
- Publish/subscribe(Pub/Sub)发布者/订阅者模型
3.1PTP模式
A.模型图
PTP:Point to Point 发送者和接收者中有一个消息队列(messages quene),发送者发送消息则把消息加入到队列中,接收者接收消息则把消息从队列中取出;如果接收者没有接收,则这条消息永远保存在队列中(除非已过期)
B.特点
- 每个消息只有一个消费者(Consumer)(即一旦被消费,消息就不再在消息队列中)
- 发送者和接收者之间在时间上没有依赖性,也就是说当发送者发送了消息之后,不管接收者有没有正在运行,它不会影响到消息被发送到队列
- 接收者在成功接收消息之后需向队列应答成功
C.使用场景
如果你希望发送的每个消息都应该被成功处理的话,那么你需要P2P模式
3.2Pub/Sub模式
A.模型图
Publish/Subscribe 发送者把消息挂在一个主题下(类似电子公告板),接收者先订阅这个主题,当这个主题有新消息发布时,接收者就可以接收这个主题下的消息了,这个消息一直保持到所有订阅这个消息的人(在线的)都接收了才删除
B.特点
- 每个消息可以有多个消费者
- 发布者和订阅者之间有时间上的依赖性。针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息,而且为了消费消息,订阅者必须保持运行的状态
- 为了缓和这样严格的时间相关性,JMS允许订阅者创建一个可持久化的订阅。这样,即使订阅者没有被激活(运行),它也能接收到发布者的消息
C.使用场景
如果你希望发送的消息可以不被做任何处理、或者被一个消息者处理、或者可以被多个消费者处理的话,那么可以采用Pub/Sub模型
4.消息类型
消息是 JMS 中的一种类型对象,由两部分组成:报头和消息主体。报头由路由信息以及有关该消息的元数据组成。消息主体则携带着应用程序的数据或有效负载。根据正文格式可以将消息分为几种类型:
- 简单文本(TextMessage),即一个字符串对象
- 可序列化的对象 (ObjectMessage),即一个序列化的 Java对象
- 属性集合 (MapMessage),即一套名称-值对
- 字节流 (BytesMessage),即一个未解释字节的数据流
- 原始值流 (StreamMessage),即Java原始值的数据流
5.JMS编程模型
(1) ConnectionFactory
创建Connection对象的工厂,针对两种不同的jms消息模型,分别有QueueConnectionFactory和TopicConnectionFactory两种。可以通过JNDI来查找ConnectionFactory对象。
(2) Connection
Connection表示在客户端和JMS系统之间建立的链接(对TCP/IP socket的包装)。Connection可以产生一个或多个Session。跟ConnectionFactory一样,Connection也有两种类型:QueueConnection和TopicConnection。
(3) Session
Session是我们操作消息的接口。可以通过session创建生产者、消费者、消息等。Session提供了事务的功能。当我们需要使用session发送/接收多个消息时,可以将这些发送/接收动作放到一个事务中。同样,也分QueueSession和TopicSession。
(4) Destination
Destination的意思是消息生产者的消息发送目标或者说消息消费者的消息来源。对于消息生产者来说,它的Destination是某个队列(Queue)或某个主题(Topic);对于消息消费者来说,它的Destination也是某个队列或主题(即消息来源)。所以,Destination实际上就是两种类型的对象:Queue、Topic可以通过JNDI来查找Destination。
(5) 消息的生产者
消息生产者由Session创建,并用于将消息发送到Destination。同样,消息生产者分两种类型:QueueSender和TopicPublisher。可以调用消息生产者的方法(send或publish方法)发送消息。
(6) 消息消费者
消息消费者由Session创建,用于接收被发送到Destination的消息。两种类型:QueueReceiver和TopicSubscriber。可分别通过session的createReceiver(Queue)或createSubscriber(Topic)来创建。当然,也可以session的creatDurableSubscriber方法来创建持久化的订阅者。
(7) MessageListener
消息监听器。如果注册了消息监听器,一旦消息到达,将自动调用监听器的onMessage方法。EJB中的MDB(Message-Driven Bean)就是一种MessageListener
6.好处
在分布式程序中,当程序A的实现要调用B程序,如果不猜用JMS,那么A就会依赖B,当启动A程序时就必须先启动B程序,所有这样就形成了程序的耦合;如果使用JMS,B完全可以发消息到服务器上,然后A从服务器上取消息,可看出有很多好处:
- 提供消息灵活性
- 松散耦合
- 异步性
但是所有的应用都直接和ActiveMQ中介进行交互,所以必须考虑网络设计