副标题#e#
WildFly,前身是JBoss AS,从V8开始为区别于JBoss EAP,改名为WildFly。HornetQ是JBoss开拓的一个独立的动静中间件,被整合进WildFly作为动静子系统。
HornetQ完全支持JMS,HornetQ不单支持JMS1.1 API同时也界说属于本身的动静API(如下图中的Core Client),以最大限度地晋升HornetQ的机能和机动性。
图 1 客户措施HornetQ的两种交互模式
关于Core Client的API先容请拜见:http://docs.jboss.org/hornetq/2.3.0.CR2/docs/api/hornetq-client/
1.1.1. 动静范例
HornetQ与JMS保持一致支持两种动静范例:Point-to-Point和Publish/Subscribe。
Point-to-Point
图 2 动静范例之Point-to-Point
URL:http://www.bianceng.cn/Programming/Java/201410/45833.htm
Publish/Subscribe
图 3 动静范例之Publish/Subscribe
1.1.2. HornetQ的专用术语说明
为了可以或许更好地利用WildFly的动静子系统,有须要对其专用术语做一下说明。个中有两组观念较量重要:
Acceptors and Connectors
Invm and Netty
1.1.2.1. Acceptors and Connectors
Acceptor
指定HornetQ Server接管什么范例的毗连(Connection)
Connector
为客户端指定毗连HornetQ Server的方法
相关设置界说在standalone以及domain的profile中,以下罗列片断供参考。
<connectors> <netty-connector name="netty" socket-binding="messaging" /> <netty-connector name="netty-throughput" socket-binding="messaging-throughput"> <param key="batch-delay" value="50" /> </netty-connector> <servlet-connector name="servlet" socket-binding="http" host="default-host" /> <in-vm-connector name="in-vm" server-id="0" /> </connectors> <acceptors> <netty-acceptor name="netty" socket-binding="messaging" /> <netty-acceptor name="netty-throughput" socket-binding="messaging-throughput"> <param key="batch-delay" value="50" /> <param key="direct-deliver" value="false" /> </netty-acceptor> <in-vm-acceptor name="in-vm" server-id="0" /> </acceptors>
#p#副标题#e#
1.1.2.2. Invm and Netty
Acceptor和Connector是个相对的观念,因此界说时需要成对界说。而Invm和Netty就是用来界说Client和HornetQ Server是否在同一个JVM中。Invm标识Client和HornetQ Server在同一个JVM中;Netty标识Client和HornetQ Server在差异的JVM中
1.1.3. 动静耐久化
WildFly中的动静是默认做耐久化并耐久化到文件中(Persistent Journal, 请拜见图15客户措施HornetQ的两种交互模式)。文件操纵有以下两种方法:
Java Non-blocking IO (NIO)
操作Java尺度的NIO API操纵文件以获取更好的机能,需要Java SE 6及更新版本。
Linux Asynchronous IO (AIO)
利用Linux的当地异步IO库举办操纵,对Linux(内核2.6及以上)系统强依赖。该方法机能优于Java NIO。
WildFly默认利用AIO进动作静耐久操纵,以获取最佳机能 ,假如在不具备Linux AIO的条件下,会自动切换到Java NIO方法进动作静耐久化。
图 4 动静耐久化场景模式
从上图中可以看出,WildFly的动静子系统中动静耐久化除了支持当地文件系统操纵,也支持NFS,基于SAN的GFS V2共享文件系统的操纵。
[留意事项](1) 在利用模式2可能3时,Linux AIO为独一文件操纵方法。
(2) 假如利用模式1,即每个HornetQ处事器都将动静耐久化到地址主机的当地文件系统,在做HornetQ处事器的HA特性(Failoerver)时,需要做动静复制(将动静日志由主HornetQ处事器复制到从HornetQ处事器上)。
【笔者概念】
HornetQ的动静耐久化方法较量单一,没有机动的耐久化方法(好比数据库耐久化)供用户选择或定制。亏得提供了通过NFS可能GFS V2 on SAN进动作静耐久化共享的方法,从而制止了在集群环境下由于做动静复制而造成的机能损耗。
在动静中间件负载要求过高的场景下,假如在动静耐久层(文件系统)与HornetQ集群之间插手缓存集群(Infinispan)做动静共享,可以提供更好的HA特性。
1.1.4. 动静复制
动静复制是高可用性的前提成果,在集群情况中通过动静复制保持主(Master)节点和从(Slave)节点的状态对等(动静一致),当主节点失效后,从节点可以或许立即替代主节点担保客户应用措施的运行不受影响。在动静耐久化中讲到了动静耐久化的3种模式,集群中的各节点在模式2(NFS)和3(GFS)的场景下可以通过共享文件系统担保动静一致;在模式1的场景下,要担保主从节点间的动静一致需要通过动静复制来实现。
图 5 动静复制
URL:http://www.bianceng.cn/Programming/Java/201410/45833.htm
[留意事项]#p#分页标题#e#
在某节点被标识为从节点,并启动后,主节点上已经有动静(persistent journal)存在的环境下,从节点首先会从主节点上同步已存在的数据,在同步完成之前无法提供容错 成果。
1.1.5. 动静去重
试想以下两种动静处理惩罚场景:
场景1
动静由动静发送者(message sender)到动静方针处事器(message target),方针处事器可能网络在动静发送之后,方针处事器接管到动静之前产生妨碍。
场景2
动静由动静发送者(message sender)到动静方针处事器(message target),方针处事器可能网络在动静达到方针处事器,而且由方针处事器对动静处理惩罚完成之后,方针处事器返反响应之前产生妨碍。
动静发送者没有步伐对以上两种场景举办分辨,统一做动静从头发送。对付场景2而言,同样的动静消费了2次。这对付一些订购系统(好比网上购物)而言,假如不做动静去重,在场景2中,对付同一件物品产生2次订购,对付消费者而言是不行接管的。
HornetQ提供了动静去重的机制,实现思路如下图所示:
图 6 动静去重道理
从上图可以看出,HornetQ的动静去重实现道理很简朴:
动静发送者为每一条动静附加带独一值(官方发起用UUID)的动静头;
方针处事器在吸收动静之后,处理惩罚动静之前,先从当地缓存(Duplicate ID Cahce)中查找该动静ID是否已经存在;
假如动静头在当地缓存中已经存在则忽略该动静;假如不存在则处理惩罚该动静;
方针处事器处理惩罚完动静后在当地缓存中缓存该动静的动静头,以供去重检测用。
【笔者概念】
上述的处理惩罚逻辑在必然水平上可以制止动静去重,在极度环境下(方针处事器缓存也瓦解的时候)也难以制止动静被反复处理惩罚的环境。假如要思量到极度环境的处理惩罚,就要牺牲必然的机能出格是漫衍式场景下。在实际业务场景中,好比订单系统与积分系统,付出系统,物流系统等系统间动静投递的场景中,出于机能思量,一般不思量如此极度的场景。淘宝/阿里的动静中间件(Notify与MetaQ)都没有为极度场景做出格设计。
鉴于今朝漫衍式缓存大行其道,好比Teracotta的BigMemory,Oracle Coherence等等,可以回收雷同于统一Session打点的方案,对Duplicate ID也做统一打点,这样集群中无论哪一个节点瓦解都可以制止动静反复消费的环境。
1.1.6. 严格动静顺序担保
为了说明动静的顺序消费的重要性,下图中勾画了一个网上购物的场景。
图 7 严格动静顺序消费场景
① A客户订购一台iPad 4
② 订购动静插手动静行列
③ A客户打消①中订购的iPad4
④ 打消订购动静插手动静行列
⑤ 从行列中消费订购动静
⑥ 从行列中消费打消订购动静
⑦ 往数据库中写入订购动静
⑧ 从数据库中删除订购动静
假如⑦和⑧的处理惩罚顺序颠倒,将导致客户的订购没有打消乐成。
如何担保动静消费的顺序呢?
JMS类型(停止JMS2.0)仅仅对“一个出产者,一个QUEUE,一个消费者”的场景做了“动静的发送顺序必需与消费顺序严格一致”的划定,但对付漫衍式情况中,没有对动静发送与接管的顺序一致做强制要求。因此严格顺序担保依赖各动静中间件提供商的详细实现。
IBM的WebSphere MQ中的动静分组与Oracle的WebLogic JMS的Message Unit-of-Order都可以办理上述场景中的问题。HornetQ也提供了办理方案:Message Grouping。
1.1.6.1. Message Grouping
Message Grouping通过将同一业务范例的动静分为一组,确保该组中的所有动静被同一个消费者消费(纵然在集群情况中),从而确保动静可以或许被顺序消费。通过HornetQ的Message Grouping图21的动静消费路由将酿成(如下图所示)。
图 8 回收Message Grouping 后的动静顺序消费
【笔者概念】
HornetQ的Message Grouping方案有以下前提:
Queue中动静顺序是正确的。即需要动静发送端意识到动静的先后顺序
消费端不行以利用多线程去处理惩罚动静。
#p#分页标题#e#
别的需要留意的是,集群情况中由于负载平衡动静大概漫衍在差异的Queue上面,这种环境下HornetQ也难以担保动静消费顺序的正确性。虽然可以通过修改负载平衡算法,借助雷同于sticky session的技能未来自于同一session的动静,都发往同一个HornetQ处事器上的同一个Destination。