這兩天給客戶部署獨立的solr服務器遇到的錯誤,如今總結一下。java
具體的錯誤信息以下:web
org.apache.solr.client.solrj.SolrServerException: Error executing query at org.apache.solr.client.solrj.request.QueryRequest.process(QueryRequest.java:100) at org.apache.solr.client.solrj.SolrServer.query(SolrServer.java:301) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at ognl.OgnlRuntime.invokeMethod(OgnlRuntime.java:897) at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1299) at ognl.ObjectMethodAccessor.callMethod(ObjectMethodAccessor.java:68) at com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethodWithDebugInfo(XWorkMethodAccessor.java:117) at com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethod(XWorkMethodAccessor.java:108) at ognl.OgnlRuntime.callMethod(OgnlRuntime.java:1375) at ognl.ASTMethod.getValueBody(ASTMethod.java:91) at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212) at ognl.SimpleNode.getValue(SimpleNode.java:258) at ognl.Ognl.getValue(Ognl.java:470) at ognl.Ognl.getValue(Ognl.java:434) at com.opensymphony.xwork2.ognl.OgnlUtil$3.execute(OgnlUtil.java:398) at com.opensymphony.xwork2.ognl.OgnlUtil.compileAndExecuteMethod(OgnlUtil.java:450) at com.opensymphony.xwork2.ognl.OgnlUtil.callMethod(OgnlUtil.java:396) at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:430) at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:290) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:251) at com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor.intercept(AnnotationWorkflowInterceptor.java:135) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245) at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245) at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229) at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245) at org.apache.struts2.interceptor.ProfilingActivationInterceptor.intercept(ProfilingActivationInterceptor.java:104) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245) at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171) at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245) at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:245) at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54) at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:575) at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:81) at org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter.doFilter(StrutsExecuteFilter.java:93) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter.doFilter(StrutsPrepareFilter.java:91) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:176) at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:145) at org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:92) at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:394) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at com.svorx.core.web.filter.NoCacheFilter.doFilterInternal(NoCacheFilter.java:48) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:442) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1083) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:640) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745) Caused by: org.apache.http.ParseException: Invalid content type: at org.apache.http.entity.ContentType.parse(ContentType.java:233) at org.apache.solr.client.solrj.impl.HttpSolrServer.executeMethod(HttpSolrServer.java:496) at org.apache.solr.client.solrj.impl.HttpSolrServer.request(HttpSolrServer.java:210) at org.apache.solr.client.solrj.impl.HttpSolrServer.request(HttpSolrServer.java:206) at org.apache.solr.client.solrj.request.QueryRequest.process(QueryRequest.java:91) ... 90 more
緣由:GET向solr傳遞參數的時候參數過長致使的。以下方法,solrServer是 org.apache.solr.client.solrj.impl.HttpSolrServer 實例spring
// 執行查詢 QueryResponse response = solrServer.query(solrQuery);
解決辦法:改成POST提交apache
SolrServer solrServer = new HttpSolrServer("xx"); SolrQuery solrQuery = new SolrQuery(); solrServer.query(solrQuery, METHOD.POST);
解決辦法: 修改solr配置
配置文件位置:SOLRHOME/CORE_NAME/conf/solrconfig.xmltomcat
找到以下配置:服務器
<maxBooleanClauses>1024</maxBooleanClauses>app
1024 改成10240ide
其中,SOLRHOME爲你的solr主目錄,CORENAME爲你的core的名稱性能
可能的緣由是:雖然代碼中調用server.add(doc)了,可是沒有進行commit,因此solr不會當即更新索引lua
解決辦法:增長完索引以後,進行commit。不要add一個就commit一次,太耗性能了,最好是批量add完成以後一次性commit。
solrServer.commit();
這種提交叫硬提交(hard commit), 使用這種提交會把文檔當即持久化到磁盤,並可讓你能立馬查詢到它,由於它會開啓一個新的searcher,可是它缺點很明顯,就是很耗性能,並會阻塞到提交任務完成,使用它是很是昂貴的操做。 查看solrj的源碼發現commit()方法的實現是commit(true,true);及waitFlush=true 和 waitSearcher=true。
源碼以下:
/** * Performs an explicit commit, causing pending documents to be committed for indexing * <p> * waitFlush=true and waitSearcher=true to be inline with the defaults for plain HTTP access * @throws IOException If there is a low-level I/O error. */ public UpdateResponse commit( ) throws SolrServerException, IOException { return commit(true, true); }
上面手動commit太耗性能了,也能夠用solr的配置自動提交,自動提交程序只須要server.add(doc),無需commit()。
通常也是自動提交結合手動commit來實現,好比你想刪除索引批量重建就能夠刪除以後手動commit,而後批量創建索引以後再手動commit;若是是單個文檔添加索引就可使用solr的自動提交。
在collection/conf/solrconfig.xml配置文件的updateHandler節點,提供了autoCommit和autoSoftCommit兩種提交索引的方式。
<!-- AutoCommit Perform a hard commit automatically under certain conditions. Instead of enabling autoCommit, consider using "commitWithin" when adding documents. http://wiki.apache.org/solr/UpdateXmlMessages maxDocs - Maximum number of documents to add since the last commit before automatically triggering a new commit. maxTime - Maximum amount of time in ms that is allowed to pass since a document was added before automatically triggering a new commit. openSearcher - if false, the commit causes recent index changes to be flushed to stable storage, but does not cause a new searcher to be opened to make those changes visible. If the updateLog is enabled, then it's highly recommended to have some sort of hard autoCommit to limit the log size. --> <autoCommit> <maxTime>${solr.autoCommit.maxTime:15000}</maxTime> <openSearcher>false</openSearcher> </autoCommit> <!-- softAutoCommit is like autoCommit except it causes a 'soft' commit which only ensures that changes are visible but does not ensure that data is synced to disk. This is faster and more near-realtime friendly than a hard commit. --> <autoSoftCommit> <maxTime>${solr.autoSoftCommit.maxTime:-1}</maxTime> </autoSoftCommit>
解釋:
autoCommit 硬提交
maxDocs:add到solr緩衝區的文檔數量超過這個值時,自動執行commit把結果寫入到磁盤索引文件中
maxTime:最長多久執行一次commit,即若是文檔一直沒有經過commit沉澱到磁盤上,那麼持久性就可能出問題,因此要隔一段時間就執行一次commit
openSearcher:要不要新開一個searcher,若是要新開,那麼目前已有的cache就會失效,具體代碼能夠看SolrIndexSearcher,它裏面有幾個Cache成員變量,若是你新創建一個searcher那麼cache失效也是正常的了,除非你有autoWarming機制。在hard commit的時候設置openSearcher=false,那麼執行完hard commit以後,磁盤文件雖然改變了,可是searcher沒有新開,須要reload或者重啓,才能看到索引中的新文檔。
通常硬提交配置以下:
<autoCommit> <maxTime>${solr.autoCommit.maxTime:60000}</maxTime> <openSearcher>true</openSearcher> </autoCommit>
autoSoftCommit 軟提交
自動軟提交只確保改變的索引是可見的,但不保證數據會同步到磁盤。該提交方式比應提交來講更快,更接近實時,就是所謂的支持near real-time (NRT) searching近實時查詢。若是不想執行autoSoftCommit(autoSoftCommit的maxTime設置成-1)。
軟提交能夠根據需求決定是否開啓。