AMQ 是一个 系统间使用JMS协议进程远程通信的 消息代理
企业消息软件不仅是一种应用间的通信方式,也是集成的方式。一直以来没有解决方案,apche amq就是一种解决方案。 提供了一个基于异步通信的松散耦合的,高可用,高性能,高可扩展的企业消息中间件(MOM)。
其作用是调解分布式应用中的时间和消息,保证他们能够到达预期的接收者手里。所以高可用,高可扩展,高性能对他来讲就至关重要了。
1. 顺应JMS规范, 具有了JMS协议的一些优点和保障,包括同步及异步消息的传递,有且仅有一次消息传递,订阅者消息持久性,以及更多。
2. 连通性: 更多的链接选项: http,https,tcp,广播等等。 多种协议的连通性会减少其他平台的接入。
3. 可插拔的持久性和安全性: 多种持久性方式和安全性选项,比如可以使用他自己的KahaDB超快速的方式,还可以使用JDBC,。 安全性可以使用属性文件或者是JAAS登录模块。
4. 使用Java构建应用
5. 与常见的容器整合
6. 多语言支持的客户端API
7. 集群代理
8. 简单的管理
松散耦合设计 和 AMQ
借用AMQ可以很好的把松散耦合引入系统中,以解决RPC调用的耦合问题, 这种异步通信的方式,使得系统之间不存在相互依存的关系。另外AMP的能力保证消息的发送及一定被接收,且不会重复发送。 发送者只发送不关心接收者。
紧耦合的缺点: 会造成阻塞,要等待应答才结束。 修改及新增功能的成本很高
松耦合:更容易扩展,大家都跟MOM打交道
什么时候使用:
1. 最终一致性
2. 可用于不同语言间的通讯
3. 用来代替RPC风格的,因为可以动态扩展可能会更快,不会造成RPC带来的峰值的上限。
4. 松散耦合架构的系统,减少依赖关系,利用异步通信,实现事件驱动的架构(整个虚拟的业务都是这样的)。 横向扩展(仅仅通过增加消费节点的数量就能够提高处理能力)
5. 为了提高应用程序的可伸缩性 , 跟上面一个意思啊
包下面自带的例子的使用:
\apache-activemq-5.13.2\examples\openwire\advanced-scenarios
jms-example-queue这个工程,下面直接执行Consumer和Producer
消息中间件是发送者和接收者的信息中介。
提供异步的松散耦合的,可靠的,可扩展的,安全的通信
分布式应用程序或系统之间的方式。
信息通过消息中间件从一个应用传递给另外一个应用。这样就使得发送者和接收者解耦。
因为不限制同时发送和接收,发送者和接收者互相不认识,这样成为异步消息传递。
消息中间件还提供了消息持久性,复杂的消息路由,消息转换。
持久性防丢和排错。
复杂的路由有很广阔的想象。
消息转换,允许两个应用通过同样的格式通讯。
Active MQ提供了上面所有的支持。
各种消息中间件使用不同的API对外提供服务,知道JMS来了
目的是提供Java程序发送和接收消息的标准话的API。
最大限度的减少Java程序员开发复杂通讯程序所需要的知识,同时提供一定的可扩展性
类似于JDBC是一种高抽象的接口。
1998年开始2002年JMS1.1。提供了如下的概念:
1. JMS client Java开发的发送和接受消息的程序
2. Non-JMS client 使用JMS provider提供的原生的客户端,而不是Java开发的。
3. JMS producer 创建和发送消息的程序
4. JMS consumer 接收和处理消息的程序
5. JMS provider JAVA开发的JMS协议的实现
6. JMS message 被JMS Client和producer发送和接收的消息。
7. JMS domains 消息类型。 点对点和发布/订阅模式
8. Administered objects 能够通过JNDI访问的一些预制的配置数据
9. Connection factory 从工厂得到到JMS提供者的链接
10. Destination 消息从那里收,消息发到哪里去。
客户端通过JMS API跟JMS 提供者进行通讯, 类似于JDBC。
但是JMS provider一般不是存的JMS的,一般都是看上了他的额外的功能。因此在换中间件的时候有可能带来额外的工作。
分为了发送消息的生产者,和接收消息的消费者。 有可能兼具有二者的功能
1. JMS Producer
向目的地发送消息。用Session.createProducer() 创建,被MessageProducer.send()覆盖
2. JMS Consumer
从目的地同步receive的,或者异步的MessageListener.onMessage()接收消息。
是JMS规范中最重要的概念。允许文本,二进制数据作为体,以及头,其消息格式如图:
包含报头和payload。 被设计成灵活和易于理解,唯一复杂的地方在于头信息
大部分自动设置, 可以是标注的JMS或者是JMS Provider提供的方法
JMSDestination
JMSDeliveryMode
传递方式, 支持两种:持久性和非持久性。
持久性:让provider持久化消息。 牺牲性能,换取可靠性,在provider宕机之后不会丢失消息
非持久性,保证非持久化并且传递且只传递一次消息。 性能更好。
设置在provider对所有都生效。 但是会被单独消息的设置覆盖
JMSExpiration
消息过期时间。 producer.settimetolive方法设定所有该producer发出的,或者 MessageProducer.send()中设定该次发出的。 JMS使用当前时间+timetolive的设置来得到过期时间,因此如果时间设置的有问题,是有可能发不出去消息的。
默认是永不过期。
JMSMessageID
provider指定的唯一标示, 可以用在存储中。 因为生成这个有一定的开销,可以通过producer.setdisablemessageid来建议provider忽略,但是仅仅是个建议。
JMSPriority
producer设置,优先级,10个级别,可以被单个消息的覆盖。 跟java线程的优先级类似
JMSTimestamp
JMS producer发出消息的时间,可以建议忽略,且为空值
jmsClient设置的:
JMSCorrelationID
通常用来关联多个Message。例如需要回复一个消息,可以把JMSCorrelationID设置为所收到的消息的JMSMessageID
JMSReplyTo
有时消息生产者希望消费者回复一个消息,JMSReplyTo为一个Destination,表示需要回复的目的地。当然消费者可以不理会它
JMSType
Headers set optionally by the JMS provider:
JMSRedelivered
消息重发,没有收到nok
头中的附件参数。getpropertynames()得到一个枚举 分为了:自定义属性,JMS定义属性,provider定义属性。
自定义属性:
使用getbooleanproperty() /
setbooleanproperty(),getstringproperty() / setstringproperty()等方法任意定义。
JMS定义属性:
JMSX开头的一些属性。有很多,用到再说
provider属性:
JMS_
供应商自定义的。
有时客户端订阅到一个目的地,但是只想接收指定的部分消息。 这样可以每个消息都带有一个标示,然后客户端可以告诉provider只接收这样标示的消息。
只能设置消息头和属性
public void sendStockMessage(Session session,
MessageProducer producer,
Destination destination,
String payload,
String symbol,
double price)
throws JMSException {
TextMessage textMessage = session.createTextMessage();
textMessage.setText(payload);
textMessage.setStringProperty(“SYMBOL”, symbol);
textMessage.setDoubleProperty(“PRICE”, price);
producer.send(destination, textMessage);
}
String selector = “SYMBOL = ‘AAPL’”;
MessageConsumer consumer =
session.createConsumer(destination, selector);
…
六种类型消息体:payload
Message base类,包含了head和属性
TextMessae payload是String
MapMessage
ByteMessage
StreamMessage
ObjectMessage
支持两种方式:point-to-point and publish/subscribe
- 发送消息到主题,所有订阅者都会收到
- 也有异步同步两种
- 可以持久订阅,当时短线的消费者会产生挤压,等连上之后又会继续消费掉
- 持久性与持久化 DURABILITY PERSISTENCE
有点差别,持久性是订阅的一个属性,仅有发布\订阅模式才有,仅仅用于离线后是否仍然记录那些消息没有发给订阅者
虽然协议里没有,但是确实提供了一些消息头能够处理基本的请求/应答模式
JMSReplyTo 指定 应答需要发送的目的地。
应答的消息的JMSCorrelationID 指定为请求消息的JMSMessageID 这样把1请求和应答关联起来, 有便利的类:QueueRequestor
管理对象。 本来应该由JMS管理员创建的一些包含特定的provider提供的配置信息。
用来隐藏特定的供应商的细节,有点像JNDI,或者dubbo.只关心接口不关心实现。
JMS定义了两种这种对象:ConnecitonFactory和Destination