在本文中,solr作为一个封装了lucene的web服务我们首先看一下solr的web.xml
<env-entry>
<env-entry-name>solr/home</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>E:\\solr_home</env-entry-value>
</env-entry>
<filter>
<filter-name>SolrRequestFilter</filter-name>
<filter-class>org.apache.solr.servlet.SolrDispatchFilter</filter-class>
<init-param>
<param-name>excludePatterns</param-name>
<param-value>/css/*,/js/*,/img/*,/tpl/*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SolrRequestFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>Zookeeper</servlet-name>
<servlet-class>org.apache.solr.servlet.ZookeeperInfoServlet</servlet-class>
</servlet>
。。。。。。
。。。。。。
可以看出solr的请求首先发到了filter进行处理在org.apache.solr.servlet.SolrDispatchFilter.java文件中
这个filter做的第一件事是初始化,主要是去solrhome里面解析solr.xml以及加载所有的core
@Override
public void init(FilterConfig config) throws ServletException
{
log.info("SolrDispatchFilter.init()" + this.getClass().getClassLoader());
String exclude = config.getInitParameter("excludePatterns");
if(exclude != null) { //排除一些不被filter的请求
String[] excludeArray = exclude.split(",");
excludePatterns = new ArrayList<>();
for (String element : excludeArray) {
excludePatterns.add(Pattern.compile(element));
}
}
try {
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)
//从web.xml中获取solrhome的地址
solrHome = SolrResourceLoader.locateSolrHome();
//利用solrhome生成CoreContainer把所有的core状态维护起来
this.cores = createCoreContainer(solrHome, extraProperties);
if (this.cores.getAuthenticationPlugin() != null) {
HttpClientConfigurer configurer = this.cores.getAuthenticationPlugin().getDefaultConfigurer();
if (configurer != null) {
configurer.configure((DefaultHttpClient)httpClient, new ModifiableSolrParams());
}
}
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");
}
每一次不被排除的查询都会执行具体的filter:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain, boolean retry) throws IOException, ServletException {
if (!(request instanceof HttpServletRequest)) return;
AtomicReference<ServletRequest> wrappedRequest = new AtomicReference();
//进行一些验证,并填充wrappedRequest
if (!authenticateRequest(request, response, wrappedRequest)) { // the response and status code have already been sent
return;
}
if (wrappedRequest.get() != null) {
request = wrappedRequest.get();
}
if (cores.getAuthenticationPlugin() != null) {
log.debug("User principal: "+((HttpServletRequest)request).getUserPrincipal());
}
// No need to even create the HttpSolrCall object if this path is excluded.
if(excludePatterns != null) {
String servletPath = ((HttpServletRequest) request).getServletPath().toString();
for (Pattern p : excludePatterns) {
Matcher matcher = p.matcher(servletPath);
if (matcher.lookingAt()) {
chain.doFilter(request, response);
return;
}
}
}
HttpSolrCall call = getHttpSolrCall((HttpServletRequest) request, (HttpServletResponse) response, retry);
try {
Action result = call.call();
switch (result) {
case PASSTHROUGH:
chain.doFilter(request, response);
break;
case RETRY:
doFilter(request, response, chain, true);
break;
case FORWARD:
request.getRequestDispatcher(call.getPath()).forward(request, response);
break;
}
} finally {
call.destroy();
}
}
在 HttpSolrCall call = getHttpSolrCall((HttpServletRequest) request, (HttpServletResponse) response, retry);中solr做了大量的处理,具体是什么,下一篇文章来分析