Solr5.0源码分析-SolrDispatchFilter
阅读原文时间:2024年05月31日阅读:1

年初,公司开发法律行业的搜索引擎。当时,我作为整个系统的核心成员,选择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();
}

}

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

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() {}

}

  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");  

}

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

   (1)然后获取solrhome。

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

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

protected CoreContainer createCoreContainer(String solrHome, Properties extraProperties) {
NodeConfig nodeConfig = loadNodeConfig(solrHome, extraProperties);
cores = new CoreContainer(nodeConfig, extraProperties);
cores.load();
return cores;
}

(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;  

}

    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

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章