zoukankan      html  css  js  c++  java
  • Solr5.0源码分析-SolrDispatchFilter

          年初,公司开发法律行业的搜索引擎。当时,我作为整个系统的核心成员,选择solr,并在solr根据我们的要求做了相应的二次开发。但是,对solr的还没有进行认真仔细的研究。最近,事情比较清闲,翻翻solr的源码,加深对solr的认识。在博客园上看到Ryan的Solr4.8.0源码分析(http://www.cnblogs.com/rcfeng/),跟着前人的脚步学习一下,并把5.0版本改动后的源码做一点补充。有什么不妥的地方,请Ryan谅解,或者联系我 QQ:503172601

      5.0相对于4.8版本,扩充了cloud的功能。我们以tomcat容器为例,先看SolrDispatchFilter的实现。

    1.   SolrDispatchFilter的实现

               BaseSolrFilter实现了Filter接口。

    abstract class BaseSolrFilter implements Filter {
      
      static {
        CheckLoggingConfiguration.check();
      }
      
    }
    View Code

      再看CheckLoggingConfiguration代码,主要是进行SLF4j logging jars校验,很简单没啥可说的。

     1 final class CheckLoggingConfiguration {
     2   
     3   static void check() {
     4     try {
     5       LoggerFactory.getLogger(CheckLoggingConfiguration.class);
     6     } catch (NoClassDefFoundError e) {
     7       throw new NoClassDefFoundError("Failed to initialize Apache Solr: "
     8           +"Could not find necessary SLF4j logging jars. If using Jetty, the SLF4j logging jars need to go in "
     9           +"the jetty lib/ext directory. For other containers, the corresponding directory should be used. "
    10           +"For more information, see: http://wiki.apache.org/solr/SolrLogging");
    11     }  
    12   }
    13   
    14   private CheckLoggingConfiguration() {}
    15     
    16 }
    View Code

      SolrDispatchFilter继承BaseSolrFilter,并且solr要求所有solr filter不要直接实现Filter接口,都要通过继承BaseSolrFilter。SolrDispatchFilter重写了三个方法:init,dofilter,destory。其中init和destory分别在tomcat的启动和关闭时候运行;doFilter处理用户的http请求像select查询等,放到后面来说。

        2.  Solr的启动

        tomcat的启动的时候,会运行init方法,我们先来看看init方法

    public void init(FilterConfig config) throws ServletException
      {
        
        try {
          // web.xml configuration
          this.pathPrefix = config.getInitParameter( "path-prefix" );
    
          Properties extraProperties = (Properties) config.getServletContext().getAttribute(PROPERTIES_ATTRIBUTE);
          if (extraProperties == null)
            extraProperties = new Properties();
    
          String solrHome = (String) config.getServletContext().getAttribute(SOLRHOME_ATTRIBUTE);
          if (solrHome == null)
            solrHome = SolrResourceLoader.locateSolrHome();
    
          this.cores = createCoreContainer(solrHome, extraProperties);
    
          log.info("user.dir=" + System.getProperty("user.dir"));
        }
        catch( Throwable t ) {
          // catch this so our filter still works
          log.error( "Could not start Solr. Check solr/home property and the logs");
          SolrCore.log( t );
          if (t instanceof Error) {
            throw (Error) t;
          }
        }
    
        log.info("SolrDispatchFilter.init() done");
      }
    View Code

        我们看到,先从web.xml读取path-prefix的属性值;

       (1)然后获取solrhome。

             在SolrResourceLoader.locateSolrHome()方法里通过三种方式获取solrhome

      1. JNDI: via java:comp/env/solr/home
      2. The system property solr.solr.home
      3. Look in the current working directory for a solr/ directory 

       (2)然后调用createCoreContainer来实现Solr的初始化。

    1 protected CoreContainer createCoreContainer(String solrHome,           Properties extraProperties) {
    2     NodeConfig nodeConfig = loadNodeConfig(solrHome, extraProperties);
    3     cores = new CoreContainer(nodeConfig, extraProperties);
    4     cores.load();
    5     return cores;
    6   }
    View Code

           (3) 类加载器SolrResourceLoader

        solr的初始化主要是loadNodeConfig方法。我们来看loadNodeConfig方法做了什么?

               创建SolrResourceLoader,代码如下:

    public SolrResourceLoader( String instanceDir, ClassLoader parent, Properties coreProperties )
      {
        if( instanceDir == null ) {
          this.instanceDir = SolrResourceLoader.locateSolrHome();
          log.info("new SolrResourceLoader for deduced Solr Home: '{}'", 
                   this.instanceDir);
        } else{
          this.instanceDir = normalizeDir(instanceDir);
          log.info("new SolrResourceLoader for directory: '{}'",
                   this.instanceDir);
        }
        
        this.classLoader = createClassLoader(null, parent);
        addToClassLoader("./lib/", null, true);
        reloadLuceneSPI();
        this.coreProperties = coreProperties;
      }
    View Code

        SolrResourceLoader主要是做了3个事情

        创建类装载器,加载lib目录下的类,装在LuceneSPI。

        然后

       (4)解析solr.xml文件

              解析solr.xml文件,通过sorl.xml的地方从本地或者zookeeper的获取solr.xml文件。

             然后调用SolrXmlConfig.fromSolrHome和SolrXmlConfig.fromInputStream解析solr.xml文件封装为NodeConfig。

         (5)实例化一个CoreContainer,通过CoreContainer来加载cores

    版权声明:本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    HTTP协议详解(真的很经典)
    几点建议,让Redis在你的系统中发挥更大作用
    Redis能干啥?细看11种Web应用场景
    Java中使用Jedis操作Redis
    java的锁机制——synchronized
    web开发中的两把锁之数据库锁:(高并发--乐观锁、悲观锁)
    一分钟教你知道乐观锁和悲观锁的区别
    $^,$@,$?,$<,$(@D),$(@F) of makefile
    linux shared lib 使用与编译
    makefile learning
  • 原文地址:https://www.cnblogs.com/bigdatafly/p/4990258.html
Copyright © 2011-2022 走看看