我们先来看看在Sun OpenMQ系统中 一个持久、可靠的方式传送消息的步骤是怎么样的,如图所示:
查看大图请点击这里
在传送过程中,系统处理JMS消息分为以下两类:
■ 有效负荷消息,由生成方发送给使用方的消息。
■ 控制消息,代理与客户端运行时环境之间传送的私有消息,用于确保有效负荷消息成功传送和控制跨连接的消息流。
详细流程如下:
消息生成
1. 客户端运行时环境通过连接将消息从消息生成方传送到代理。
消息处理和路由
2. 代理从连接中读取消息并将此消息放入相应的目的地中。
3. 代理将(持久性)消息放入数据存储库中。
4. 代理向消息生成方的客户端运行时环境确认已收到消息。
5. 代理确定消息的路由。
6. 代理将消息从目的地写入适当的连接,并使用使用方的唯一标识符标记该消息。
消息使用
7. 消息使用方的客户端运行时环境将消息从连接传送到消息使用方。
8. 消息使用方的客户端运行时环境向代理确认消息已使用。
消息生命周期结束
9. 代理处理客户端确认,并在收到所有确认后删除(持久性)消息。
10. 代理向使用方的客户端运行时环境确认,告知客户端确认已得到处理。
如果管理员删除目的地中的消息,或者管理员删除或重新定义长期订阅,导致主题目的地中的消息未被传送即被删除,则代理可以在消息被使用前将它丢弃。在其他情况下,您可能希望代理将消息存储在称为停用消息队列的特殊目的地中,而不是将它们丢弃。在以下情况,消息会被放入停用消息队列中:消息过期时、消息因内存限制而被删除时,以及因客户端引发异常而导致传送失败时。通过将消息存储在停用消息队列中,您可以解决系统问题并在某些情况下恢复消息。
以下是针对JMS应用中的一些优化策略,H.E.在这里分为几点向大家进行介绍:
1.收发消息的属性
在接收端和发送端可以设置消息发送和接收的属性,对于消息发送时还需要注意客户端的消息确认模式一共有3种客户机确认模式:
■ 在AUTO_ACKNOWLEDGE 模式下开销最大,可以保证消息逐条传送的可靠性,会话自动确认客户端使用的每条消息。会话线程会被阻止,以等待代理确认它已处理了每个已使用消息的客户端确认;
■ 在CLIENT_ACKNOWLEDGE 模式下,在一条或多条消息被使用后,客户端通过调用消息对象的acknowledge() 方法来显式确认。这样该会话就确认了自上次调用该方法后使用的所有消息。会话线程会被阻止,以等待代理确认它已处理了客户端确认。Message Queue 提供使客户端可仅仅确认收到一条消息的方法,从而扩展了该模式。因此需要的带宽开销较小;
■ 在DUPS_OK_ACKNOWLEDGE 模式下,会话在使用了十条消息后进行确认。会话线程不会因等待代理确认而被阻止,因为在该模式下代理确认不是必需的。虽然该模式可保证不会丢失消息,但并不能保证不会收到重复的消息,因此名称为:DUPS_OK。
对于更关心性能而不是可靠性的客户端,Message Queue 服务通过提供NO_ACKNOWLEDGE模式来扩展JMS API。在该模式下,代理不跟踪客户端确认,所以不保证使用方客户端已成功处理了消息。对于发送至非长期订户的非持久性消息,选择该模式可提高性能。
如果你有大量的消息需要进行发送,可以采用DUPS_OK_ACKNOWLEDGE模式,因为他是最快的。
代码示例
connection = connectionFactory.createTopicConnection();
session=connection.createSession(false, Session.DUPS_OK_ACKNOWLEDGE);
2.慎用消息压缩
消息的大小对消息的效率是有影响的,跟Http/Gzip的道理一样,减少网络的负载,但是并不能提升你的运行效率,反而会将你的接收响应时间延时。以下是消息压缩的代码示例:
1.发送压缩消息的代码示例:
for (int i=0;i<10000;i++){ //循环1W次发送消息
Javabloger_Msg msg=new Javabloger_Msg (); // 自定义的对象,进行实例化
msg.setTime( [...]
文章来源:
http://www.javabloger.com/article/sun-openmq-jms-large-scale-systems.html?source=rss