JMS

demo:

http://yunpan.cn/cLKBCnj9waCQw  访问密码 ab18

 

一.JMS是什么

Java消息服务(Java Message Service,JMS)是一组Java应用程序接口,用于在两个应用程序之间,或分布式系统中发送信息,进行异步通信,它提供创建、发送、接收、读取信息的服务。JMS是一个与具体平台无关的API,绝大多数消息中间件(MOM)提供商都对JMS提供支持。

二.JMS特点

1)         JMS是一种与厂商无关的API,用来访问消息收发系统信息。它类似于JDBC,JDBC是可以用来访问许多不同关系数据库的API,而JMS则提供同样与厂商无关的访问方式,以访问消息收发服务。

2)         可移植性:应用程序开发人员无需了解远程调用过程和网络/通信协议的细节,提供了程序的可移植性。

3)         松散耦合:JMS实现了松散耦合的分布式通信,组件发送信息到目的地(destination),消息接收者从该目的地提取消息。但是,消息的发送和接收却不是同时进行的。实际上,发送者不必去了解接收者,同样接收者也不必了解发送者:它们只需要知道消息格式和消息目的。

4)         可靠:事务,在一次会话过程,可以像JDBC那样,处理多条信息,然后确认提交。遗憾的是接收支持事务,大多数发送不支持事务(RocketMQ提供事务)。JMS规范定义了消息的持久化,内存放一份,持久化介质中放一份,系统崩溃了不要紧,重启后从介质中恢复消息,确保数据不会丢失。

三.为什么要用JMS

1)         解耦

在项目启动之初来预测将来项目会碰到什么需求,是极其困难的。消息系统在处理过程中间插入了一个隐含的、基于数据的接口层,两边的处理过程都要实现这一接口。这允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。

2)         冗余

有些情况下,处理数据的过程会失败。除非数据被持久化,否则将造成丢失。消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。许多消息队列所采用的”插入-获取-删除”范式中,在把一个消息从队列中删除之前,需要你的处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕。

3)         扩展性

因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的,只要另外增加处理过程即可。不需要改变代码、不需要调节参数。扩展就像调大电力按钮一样简单。

4)         灵活性&峰值处理能力

在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见;如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。

5)         可恢复性

系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。

6)         顺序保证

在大多使用场景下,数据处理的顺序都很重要。大部分消息队列本来就是排序的,并且能保证数据会按照特定的顺序来处理。Kafka保证一个Partition内的消息的有序性。

7)         缓冲

在任何重要的系统中,都会有需要不同的处理时间的元素。例如,加载一张图片比应用过滤器花费更少的时间。消息队列通过一个缓冲层来帮助任务最高效率的执行———写入队列的处理会尽可能的快速。该缓冲有助于控制和优化数据流经过系统的速度。

8)         异步通信

很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。

四.JMS两种模型

1)         点对点模型:生产者发送消息到一个特定的队列,而消费者从一个消息队列中得到信息。

特点:

  1. 每条消息有一个消费者,如果一条消息被消费者接收,那么其他的消费者就不能得到这条信息。
  2. 发送和接收消息与时间没有关系,也就是说,生产者在发送消息后,消费者可以在任意时候接收,但有两个前提:1.消息未过期;2.消息没有被其他消费者接收

2)         发布/订阅模型:生产者发布信息,而消费者订阅消息,生产者将消息和一个特定的主题连在一起,消息传递系统根据消费者注册的兴趣,将消息传递给消费者。

特点:

  1. 每个消息都可以有多个订阅者
  2. 消费者必须先订阅,然后才能接到生产者发送的消息。

五.JMS应用

 

发送消息基本步骤:

1)         创建连接使用的工厂类JMS ConnectionFactory

2)         使用管理对象JMS ConnectionFactory建立连接Connection,并启动

3)         使用连接Connection 建立会话Session

4)         使用会话Session和管理对象Destination创建消息生产者MessageSender

5)         使用消息生产者MessageSender发送消息

消息接收者从JMS接受消息的步骤:

6)         创建连接使用的工厂类JMS ConnectionFactory

7)         使用管理对象JMS ConnectionFactory建立连接Connection,并启动

8)         使用连接Connection 建立会话Session

9)         使用会话Session和管理对象Destination创建消息接收者MessageReceiver

10)     使用消息接收者MessageReceiver接受消息,需要用setMessageListener将MessageListener接口绑定到MessageReceiver消息接收者必须实现了MessageListener接口,需要定义onMessage事件方法。

JMS应用程序接口:

JMS公共

点对点

发布订阅

ConnectionFactory

QueueConnectionFactory

TopicConnectionFactory

Connection

QueueConnection

TopicConnection

Destination

Queue

Topic

Session

QueueSession

TopicSession

MessageProducer

QueueSender

TopicPublisher

MessageConsumer

QueueReceiver

TopicSubscriber

 

ConnectionFactory 接口(连接工厂)

        用户用来创建到JMS提供者的连接的被管对象。JMS客户通过可移植的接口访问连 接,这样当下层的实现改变时,代码不需要进行修改。 管理员在JNDI名字空间中配置连接工厂,这样,JMS客户才能够查找到它们。根据消息类型的不同,用户将使用队列连接工厂,或者主题连接工厂。

Connection 接口(连接)

        连接代表了应用程序和消息服务器之间的通信链路。在获得了连接工厂后,就可以创建一个与JMS提供者的连接。根据不同的连接类型,连接允许用户创建会话,以发送和接收队列和主题到目标。

Destination 接口(目标)

        目标是一个包装了消息目标标识符的被管对象,消息目标是指消息发布和接收的地点,或者是队列,或者是主题。JMS管理员创建这些对象,然后用户通过JNDI发现它们。和连接工厂一样,管理员可以创建两种类型的目标,点对点模型的队列,以及发布者/订阅者模型的主题。

MessageConsumer 接口(消息消费者)

        由会话创建的对象,用于接收发送到目标的消息。消费者可以同步地(阻塞模式),或异步(非阻塞)接收队列和主题类型的消息。

MessageProducer 接口(消息生产者)

        由会话创建的对象,用于发送消息到目标。用户可以创建某个目标的发送者,也可以创建一个通用的发送者,在发送消息时指定目标。

Message 接口(消息)

        是在消费者和生产者之间传送的对象,也就是说从一个应用程序传送到另一个应用程序。一个消息有三个主要部分:

  消息头(必须):包含用于识别和为消息寻找路由的操作设置。

  一组消息属性(可选):包含额外的属性,支持其他提供者和用户的兼容。可以创建定制的字段和过滤器(消息选择器)。

  一个消息体(可选):允许用户创建五种类型的消息(文本消息,映射消息,字节消息,流消息和对象消息)。

  消息接口非常灵活,并提供了许多方式来定制消息的内容。

消息类型

说明

常用方法

TextMessage

文本消息

getText,setText

MapMessage

映射消息

setString,getString

BytesMessage

字节消息

writeBytes,readBytes

StreamMessage

流消息

writeString,readString

ObjectMessage

对象消息

setObject,getObject

 

Session 接口(会话)

        表示一个单线程的上下文,用于发送和接收消息。由于会话是单线程的,所以消息是连续的,就是说消息是按照发送的顺序一个一个接收的。会话的好处是它支持事务。如果用户选择了事务支持,会话上下文将保存一组消息,直到事务被提交才发送这 些消息。在提交事务之前,用户可以使用回滚操作取消这些消息。一个会话允许用户创建消息生产者来发送消息,创建消息消费者来接收消息。

六.JMS供应商

a)         ActiveMQ

  1. 消息的安全性

在集群环境下,通过Zookeeper选出master,其余节点均为slave,只有master接受和处理客户端连接,其余slave节点均连接至master,并同步所有的持久化操作。(但是此种模式不支持延迟消息和计划消息,因为他们存储在KahaDB文件里。)如果master挂了,最后更新的slave将被选中当master。

并且,所有的消息操作需要集群一定节点(N/2+1)都操作成功才会返回操作成功的结果,如果是N=3个replicas节点,那么需要集群中有3/2+1=2个节点都确认操作成功。

所以如果结合JMS规范的ACK指令,消息的安全性在一个健康的集群中完全可以得到保障,三个节点的集群可以忍受1个节点挂掉仍可以提供服务。

 

  1. 服务的稳定容错性

客户端通过failover协议连接集群服务,所以AMQ的稳定性主要依赖于ZK和自身集群的节点状态,稳定性还是可以的,唯一担心的就是客户端的读写链接压力全部在master上。

  1. 吞吐量

目前主备集群中所有的topic和queue的读写都在单节点的master上进行,所以吞吐量完全依赖单点master,看官网上AMQ是支持Broker clusters的,但是这个支持缺点很多,首先它依然采用failover协议,这看起来与主备集群冲突了,第二点如果其中一个broker挂了,那它所属的还没有被消费的消息将无法消费直到broker重启成功。

如果将Broker集群与主备集群结合起来倒是满足去除单点又达到负载均衡的需求,可惜两者都通过failover协议连接,目测需要改造后才能使用。

 

b)         Kafka

Kafka是一个高性能、分布式的消息系统,广泛用于日志收集、流式数据处理、在线和离线消息分发等场景。虽然不是作为传统的MQ来设计,在大部分情况,Kafaka 也可以代替原先ActiveMQ 等传统的消息系统。

Kafka 集群需要zookeeper 支持来实现集群,最新的kafka 发行包中已经包含了zookeeper,部署的时候可以在一台服务器上同时启动一个zookeeper Server 和 一个Kafka Server,也可以使用已有的其他zookeeper集群。

Activemq、Kafka、rabbitmq性能对比:

 

  1. 分布式可高扩展:Kafka 集群可以透明的扩展,增加新的服务器进集群。
  2. 高性能:Kafka 的性能大大超过传统的ActiveMQ、RabbitMQ等MQ 实现,尤其是Kafka 还支持batch 操作。
  3. 容错:Kafka每个Partition的数据都会复制到几台服务器上。当某个Broker故障失效时,ZooKeeper服务将通知生产者和消费者,生产者和消费者转而使用其它Broker。

c)         RocketMQ(阿里)

d)         jbossmq(jboss 4)

e)         jboss messaging (jboss 5)

f)          RabbitMQ

g)         joram-4.3.21 2006-09-22

h)         openjms-0.7.7-alpha-3.zip December 26,2005

i)           mantamq

j)           ubermq

k)         SomnifugiJMS 2005-7-27

l)           IBM WebSphereMQ

m)       BEAWebLogicJMS

n)         OracleAQ

  • o)         NonStop Server for Java Message Service(JMS)

p)         Sun Java System Message Queue

q)         Sonic jms

r)          TIBCO Enterprise For JMS

s)         iLinkMQ (国内)

 

posted @ 2015-11-06 10:07  刘尊礼  阅读(205)  评论(0)    收藏  举报