欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Hibernate Search + Spring + ActiveMQ

程序员文章站 2022-04-15 23:44:17
...

     使用了Hibernate Search 之后,在集群的环境下,就需要牵扯到同步index文件的问题, 《Hibernate Search In action》 提到了两种方式,一种是同步更新,一种是异步更新,下面来分别说说这种更新试的使用及实现:


1. 同步方式

      同步方式就是一个节点的更新能被其它的节点实时获得,最经典的方式就是各个节点都读写同一个文件夹,当然了,如果节点在不同的机器上,那就需要能够无验证网络访问这个文件夹。在节点比较少的情况下,这种情况可以很好的工作,如果节点很多,而且更新又比较频繁,这种情况可能会带来锁竞争及其它的一些问题。

     如何实现:《Hibernate Search In action》提到的比较多的是NFS,这是种在UNIX系统中使用的文件共享技术。windows下面也有对应的实现,但是,在64位的windows下可能会遇到一些麻烦。因为我的系统是windows64位的,所以我选用了另外一种实现方式,如在windows环境下,有两台机器A 和 B, A设置一个共享文件夹admin, 但在访问的时候需要用户名和密码,这时候可以用下面的这行命令在B机器上运行一下

                    rundll32 netplwiz.dll,UsersRunDll

命令,然后将需要访问A机器的用户名和密码设在B机器上,就可以访问这个 共享文件夹时不需要userName和Passwd了。

 

2. 异步方式

     在《Hibernate Search In action》中提及一种JMS方式,即对Index文件的更先方到一个JMS队列中,然后由一个master节点统一进行index, 其它slave节点定时去master节点同步被Index后的文件,从而达到同步文件的目的。因为是异步的,所以有新的数据会被延迟搜索出来的情况发生, 除此之外,因为使用了JSM,所以一种JMS技术需要被引入及维护,部署上也带来子一定的难度。但是相比较这些不足,这种方式比较稳定,当在节点比较多的环境下, 应该是作为首先的。下面来谈谈如何实现。

       其实在下面这篇文章中已经讲了如果去实现这种做法:   

         分布式Hibernate search



     但是按照文中的说法进行部署的时候,也遇到了一些小的问题,特在下面记录一下,以做为这篇文章的补充: 

    A.  上面这文章中提到,在你的环境中配置activemq.xml文件,然后使用如下的配置去启动,

<bean id="broker" class="org.apache.activemq.xbean.BrokerFactoryBean">  
  <property name="config" value="WEB-INF/activemq.xml" />  
  <property name="start" value="true" />  
</bean>  

     我认为不可取,应该让activemq在一上单独的Server中运行。因为当MQ是嵌在你的Application中运行时,如果你的Application挂了,那Slave节点就不可以将数据写到Q中,这样就会有丢数据的可能,而放在一个单独了Server中,如果master挂了,slave还是可以将数据放到Q中的,当master重启之后,又可以接着处理,当然了,为了保险,可能MQ也需要做集群。如单独启动,需要将下面的配置放在{ActiveMQ_HOME}/conf/activemq.xml文件中:

<amq:broker brokerName="HibernateSearchBroker"> 

     <amq:managementContext>  

         <amq:managementContext createConnector="false"/>  

     </amq:managementContext>  

       <amq:transportConnectors>  

         <amq:transportConnector uri="tcp://localhost:61616" />   

     </amq:transportConnectors>  

  </amq:broker>    

<amq:queue name="queue/hibernatesearch" physicalName="hibernateSearchQueue" /> 

启动之后,手动创建一个Q,名字叫hibernateSearchQueue。

       B. 所有的都配置好了之后,在运行的过程中,发现slave节点的message可以正常发送,Master节点也可以获取到这个message,但是就是index不正确,通过Debug才发现在取session的时候,出错了,但是没有报出来错误信息。Master节点都要包含一个类继承自AbstractJMSHibernateSearchController来处理message,需要实现getSession这个方法,一开始我的写法如下:

@Repository("hibernateSearchController")
@Tansactional
public class JMSHibernateSearchController extends AbstractJMSHibernateSearchController implements MessageListener {

    @Autowired

    private SessionFactory sessionFactory;

    @Override
    protected void cleanSessionIfNeeded(Session session) {}

    @Override
    protected Session getSession() {
        return sessionFactory.getCurrentSession();
    }

}

 


后来无论如何都不能获取到,后来改成如下的方式,成功:

   

    @Override
    protected Session getSession() {
        return sessionFactory.openSession();
    }

 

有些时候能进行Debug还是很重要的。