消息系统允许我们以松耦合的方式连接不同的系统在一起,并具有一定可靠性。Java消息服务(JMS)提供商使用事务性的系统,能够原子性的提交或回滚的变化。不同于基于远程过程调用(RPC)模式的系统,消息系统主要使用异步消息传递模式,消息请求和响应之间没有紧密关系。大多数消息系统也支持请求-响应模式,但是这不是一个消息系统主要的功能。
HornetQ是一个多协议,由Red Hat开发的异步消息系统。HornetQ提供高可用性(HA),在一个服务器出现故障的情况下客户端自动切换到其他服务器,保证消息的可靠性。HornetQ还支持灵活的基于负载均衡消息的集群解决方案。
HornetQ的使用Acceptors和Connectors的概念作为一个消息系统的重要组成部分。Acceptors和Connectors分别决定接收进来连接的方式及使连接到服务器(其它HornetQ的服务器或JMS客户端)。换句话说,Acceptors决定HornetQ服务器的监听地址。另一方面,Connectors用于与HornetQ服务器通信,因此Connectors被客户端或其他HornetQ服务器使用。HornetQ的服务器使用BROADCAST GROUPS来广播自己的连接信息到其他监听广播消息(DISCOVERY GROUP)的HornetQ服务器,当JMS客户端通过JNDI查找一个ConnectionFactory并发送消息HornetQ的目的地,ConnectionFactory使用Connectors。
HornetQ提供两种类型的Acceptors和Connectors:invm和netty。如果连接在同一个JVM中invm更有效,netty用来处理不同JVM之间或不同物理机器之间JVM连接。只有Connectors和Acceptors配置的类型相同连接才能够成功建立(相同的协议,如果使用netty则相同的主机地址和端口号)。
在集群的概念中,JMS消息可以认为是集群节点的状态。由于JMS异步FIRE AND FORGET的特性,消息往往积聚在服务器上,并逐渐在新的事务中被消费,这些消息往往被设置为是持久化的,直到事务成功提交才从数据存储中删除。当一个JBoss实例失败,它可能有较多的为被处理的持久化JMS消息,这就需要一个适当的JMS服务器集群解决方案将这些消息容错复制到其他节点,让他们可以尽快在另一个节点上被消费者消费。
在HornetQ高可用性(HA)集群的配置中多个HornetQ的服务器可能会被联系在一起组成现场-备份的组,每个现场服务器可以有1个或多个备份服务器,备份服务器是不被操作,直到发生故障转移。但是有一个选择的备份服务器处于被动模式状态,等待接管活着服务器的工作。
JBoss 7/WildFly中HornetQ支持两种高可用性(HA)模式:
消息复制:当不使用共享存储时,HornetQ现在支持现场和备份的服务器组之间基于内存进行复制。在这种情况下,消息的复制是通过网络复制实现的。只要在两个服务器在同一集群且具有相同的群集的用户名和密码,两个服务器之间的所有的状态都能被复制。只有现场服务器接收到持久化的的消息才会被复制到备份服务器,所以重要的是要记住,只有持久化才能实现消息复制,达到高可用性(HA),否则不具有高可用性(HA)。
如上图中所示,当消息复制被使用,每个HornetQ服务器使用本地存储其状态。同一备份组内现场服务器的状态复制到备份服务器,这样备份服务器包含活着服务器所具有数据,并已准备在必要时接管现现场服务器。
高可用性模式的选择在很大程度上取决于集群环境。消息复制可能会导致一些网络流量增加,但共享的存储需要一个高性能的共享文件系统,但那并非是始终可用。无论怎样选择HA的模式选择,故障转移总是会发生从现场服务器到备份服务器,并且在出现故障前备份服务器是无效的。这样一台备份服务器通常不运行HornetQ的运行组件,因此不支持启用HornetQ的JBoss实例的所有功能,如部署一个消息驱动bean。当然,HornetQ服务器不是与JBoss服务器保持同步。 JBoss实>例实际上可能被配置为包括多个HornetQ服务器。
JBoss服务器为了在各个组件上支持负载平衡和故障转移,包括HornetQ,它是可以在正在运行的JBoss现场服务器实例中配置额外的HornetQ备份服务器。当使用一个共享的存储,现场服务器失败,备份服务器使用相同的共享存储拿起其职责。当共享存储关闭,该状态被复制,当现场服务器失败时备份服务器可以有复制来的状态使用。HornetQ的backup-group-name配置确定备份服务器来复制一个给定的现场服务器的状态。这使得配置备份服务器能够避免配对与现场服务器共同位于相同的JBoss服务器,这样的JBoss服务器的崩溃不会导致数据丢失。重要的是要记住,任何消费者(最明显的是MDB )通常只监听在现场服务器的目的地上,因此,当备份服务器激活时,它将有没有消费者。HornetQ的再分配功能,可>以帮助我们,因为消息目的地址会注意到缺少消费者,消息会重新发送到同一个集群服务器上有消费者的目的地址。要启用此功能,在备份服务器上必须设置redistribution-delay,其默认值为-1,表示禁用再分配功能。
在配置一个集群时,还有其他HornetQ的配置约束需要考虑到。在同一个JVM中对每个HornetQ配置netty Connectors 和 Acceptors时,我们必须分配一个唯一的端口,所以我们建议在JBoss中配置socket binding。invm 是在同一个JVM中配置Connectors 和 Acceptors,它也需要一个唯一的服务器ID。给一个JBoss实例上的每个HornetQ服务器分配一个backup-group-name是非常重要的,它必需不同于现场的服务器,否则并发服务器与现场服务器在一起,没有起到冗余备份的作用。这也就是说至少需要两个或两个以上JBoss实例交替配置backup-group-name,才能确保现场服务器和备份的服务器达到高可用的目的。
总结一下,一个简单的包括负载均衡和容错处理的JBoss集群可以是两个JBoss节点。两个JBoss节点构成的集群中,任何一个节点包括一个现场HornetQ服务器和备份HornetQ服务器。假设两个JBoss节点分为node1和node2,node1的现场服务器属于group1,而备份服务器属于group2,node2正好相反,现场服务器属于group2,备份服务器属于group1。这样才能保持现场和备份服务器之间相互派对,达到高可用目的。所有现场服务器与备份服务器将共享相同的集群配置和发现广播组,这两个JBoss节点使用端口5446配置备份服务器netty配置Connectors 和 Acceptors。在这样一个设置下,JBoss节点1上的备份服务器将配对节点2的现场服务器,并保持数据同步。在节点2失败的情况下,节点1上的备份服务器激活,包含所有未处理的消息,但没有消费者来处理他们,因此,HornetQ的再分配功能会将这些消息发送到节点1的现场服务器 ,而现场服务器将有一个MDB部署作为消费者消费这些消息。
我们在随后的系列给出HornetQ Messaging集群示例,通过示例我们可以看到HornetQ 负载均衡,高可用的集群特性。示例链接: