分享

Solr5.0源码分析-SolrDispatchFilter

本帖最后由 breaking 于 2015-11-26 13:29 编辑
问题导读:
1.了解SolrDispatchFilter是怎么实现的
2.了解Solr启动是怎么实现的
3.了解Solr的二次开发是怎么样的





      年初,公司开发法律行业的搜索引擎。当时,我作为整个系统的核心成员,选择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的实现。
804386-20151124005529155-1119716016.png

1.  SolrDispatchFilter的实现
           BaseSolrFilter实现了Filter接口。
[mw_shl_code=java,true]abstract class BaseSolrFilter implements Filter {
  
  static {
    CheckLoggingConfiguration.check();
  }
  
}[/mw_shl_code]
  再看CheckLoggingConfiguration代码,主要是进行SLF4j logging jars校验,很简单没啥可说的。
[mw_shl_code=java,true]final class CheckLoggingConfiguration {
  
  static void check() {
    try {
      LoggerFactory.getLogger(CheckLoggingConfiguration.class);
    } catch (NoClassDefFoundError e) {
      throw new NoClassDefFoundError("Failed to initialize Apache Solr: "
          +"Could not find necessary SLF4j logging jars. If using Jetty, the SLF4j logging jars need to go in "
          +"the jetty lib/ext directory. For other containers, the corresponding directory should be used. "
          +"For more information, see: http://wiki.apache.org/solr/SolrLogging");
    }  
  }
  
  private CheckLoggingConfiguration() {}
   
}[/mw_shl_code]
  SolrDispatchFilter继承BaseSolrFilter,并且solr要求所有solr filter不要直接实现Filter接口,都要通过继承BaseSolrFilter。SolrDispatchFilter重写了三个方法:init,dofilter,destory。其中init和destory分别在tomcat的启动和关闭时候运行;doFilter处理用户的http请求像select查询等,放到后面来说。
    2.  Solr的启动
    tomcat的启动的时候,会运行init方法,我们先来看看init方法
[mw_shl_code=java,true]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");
  }[/mw_shl_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的初始化。
[mw_shl_code=java,true]protected CoreContainer createCoreContainer(String solrHome, Properties extraProperties) {
    NodeConfig nodeConfig = loadNodeConfig(solrHome, extraProperties);
    cores = new CoreContainer(nodeConfig, extraProperties);     
    cores.load();
    return cores;
  }[/mw_shl_code]
       (3) 类加载器SolrResourceLoader
    solr的初始化主要是loadNodeConfig方法。我们来看loadNodeConfig方法做了什么?
           创建SolrResourceLoader,代码如下:
[mw_shl_code=java,true]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;
  }[/mw_shl_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://www.cnblogs.com/bigdatafly/p/4990258.html

没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条