这个让我疯了。
问题出现在双服务器系统中,其中服务器A运行Magento EE 1.11,服务器B运行Solr 3.4.0。两个服务器都位于同一网络(192.168.x.x)中,A上的Magento后端配置为使用B上的Solr守护程序进行目录搜索。
Imo,Magento后端配置正确,因为Magentos Test Connection
功能总是返回Successful! Test again?
,我可以找到Solr日志中测试引起的ping。
但是在尝试
时System -> Index Management -> Catalog Search Index -> Reindex data
Magento总是以“重建索引过程出现问题”而失败。
检查Solr日志会提供缺少内容流并返回HTTP 400(错误请求):
Nov 10, 2011 3:50:16 PM org.apache.solr.core.SolrCore execute
INFO: [] webapp=/solr path=/admin/ping params={} hits=0 status=0 QTime=1
Nov 10, 2011 3:50:16 PM org.apache.solr.core.SolrCore execute
INFO: [] webapp=/solr path=/admin/ping params={} status=0 QTime=2
Nov 10, 2011 3:50:16 PM org.apache.solr.core.SolrCore execute
INFO: [] webapp=/solr path=/admin/ping params={} hits=0 status=0 QTime=1
Nov 10, 2011 3:50:16 PM org.apache.solr.core.SolrCore execute
INFO: [] webapp=/solr path=/admin/ping params={} status=0 QTime=2
Nov 10, 2011 3:50:16 PM org.apache.solr.update.processor.LogUpdateProcessor finish
INFO: {} 0 0
Nov 10, 2011 3:50:16 PM org.apache.solr.common.SolrException log
SEVERE: org.apache.solr.common.SolrException: missing content stream
at org.apache.solr.handler.ContentStreamHandlerBase.handleRequestBody(ContentStreamHandlerBase.java:62)
at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:129)
at org.apache.solr.core.SolrCore.execute(SolrCore.java:1368)
at org.apache.solr.servlet.SolrDispatchFilter.execute(SolrDispatchFilter.java:356)
at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:252)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1212)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:399)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:766)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:450)
at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:945)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Nov 10, 2011 3:50:16 PM org.apache.solr.core.SolrCore execute
INFO: [] webapp=/solr path=/update params={wt=json&<delete fromPending="true"+fromCommitted%3D"true"><query>store_id:2</query></delete>} status=400 QTime=0
Nov 10, 2011 3:50:16 PM org.apache.solr.update.processor.LogUpdateProcessor finish
INFO: {} 0 0
Nov 10, 2011 3:50:16 PM org.apache.solr.common.SolrException log
SEVERE: org.apache.solr.common.SolrException: missing content stream
at org.apache.solr.handler.ContentStreamHandlerBase.handleRequestBody(ContentStreamHandlerBase.java:62)
at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:129)
at org.apache.solr.core.SolrCore.execute(SolrCore.java:1368)
at org.apache.solr.servlet.SolrDispatchFilter.execute(SolrDispatchFilter.java:356)
at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:252)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1212)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:399)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:766)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:450)
at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:945)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Nov 10, 2011 3:50:16 PM org.apache.solr.core.SolrCore execute
INFO: [] webapp=/solr path=/update params={<rollback/>=&wt=json} status=400 QTime=0
在这个错误跟踪中,我唯一看起来很奇怪的是,在/update
命令的参数中只有=
的一个是url编码的至%3D
,但所有其他人不。
<delete fromPending="true"+fromCommitted%3D"true"><query>store_id:2</query></delete>
Otoh我对Solr很陌生,并且不知道这可能只是Java记录器本身的错误。
我还检查了Apache_Solr_Service::deleteByQuery()
,这是一种生成失败的Solr查询的PHP方法,但到目前为止还没有找到任何错误。
在这种情况下,生产环境不幸地绑定到PHP 5.2.16,因此我想到的另一件事是PHP 5.2下htmlspecialchars
,stream_context_set_option
或file_get_contents
可能出现的问题。 16,但是IIRC没有这样的。
所以我的问题是:导致“缺少内容流”错误的原因和/或如何解决此问题?
答案 0 :(得分:2)
我们重写了enterprise / search / client / solr.php以使用curl。
你必须改变_sendRawGet和_sendRawPost方法:
protected function _sendRawGet($url, $timeout = FALSE)
{
$curl = curl_init();
curl_setopt ($curl, CURLOPT_URL,$url);
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
if($timeout && is_numeric($timeout))
{
curl_setopt ($curl, CURLOPT_CONNECTTIMEOUT, floatval($timeout));
}else{
curl_setopt ($curl, CURLOPT_CONNECTTIMEOUT, floatval(5));
}
curl_setopt ($curl, CURLOPT_HEADER, 1);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Authorization: Basic " . base64_encode($this->getUserLogin() . ':' . $this->getPassword())));
$ret = curl_exec($curl);
$info = curl_getinfo($curl);
if(curl_errno($curl))
{
throw new Exception('"' . curl_errno($curl) . '" Info: ' . print_r($info,true));
}
$header = substr($ret, 0, $info['header_size']);
$body = substr($ret, -$info['download_content_length']);
$response = new Apache_Solr_Response($body, explode("\r\n",$header), $this->_createDocuments, $this->_collapseSingleValueArrays);
if ($response->getHttpStatus() != 200 && $response->getHttpStatus() != 100)
{
throw new Exception('"' . $response->getHttpStatus() . '" Status: ' . $response->getHttpStatusMessage(), $response->getHttpStatus());
}
curl_close($curl);
return $response;
}
protected function _sendRawPost($url, $rawPost, $timeout = FALSE, $contentType = 'text/xml; charset=UTF-8')
{
$curl = curl_init();
curl_setopt ($curl, CURLOPT_URL,$url);
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
if($timeout && is_numeric($timeout))
{
curl_setopt ($curl, CURLOPT_CONNECTTIMEOUT, floatval($timeout));
}else{
curl_setopt ($curl, CURLOPT_CONNECTTIMEOUT, floatval(5));
}
curl_setopt ($curl, CURLOPT_HEADER, 1);
$sendHeader = array(
"Authorization: Basic " . base64_encode($this->getUserLogin() . ':' . $this->getPassword()),
"Content-Type: ".$contentType
);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $rawPost);
curl_setopt($curl, CURLOPT_HTTPHEADER, $sendHeader);
$ret = curl_exec($curl);
$info = curl_getinfo($curl);
if(curl_errno($curl))
{
throw new Exception('"' . curl_errno($curl) . '" Info: ' . print_r($info,true));
}
$header = substr($ret, 0, $info['header_size']);
$body = substr($ret, -$info['download_content_length']);
$response = new Apache_Solr_Response($body, explode("\r\n",$header), $this->_createDocuments, $this->_collapseSingleValueArrays);
if ($response->getHttpStatus() != 200 && $response->getHttpStatus() != 100)
{
throw new Exception('"' . $response->getHttpStatus() . '" Status: ' . $response->getHttpStatusMessage(), $response->getHttpStatus());
}
curl_close($curl);
return $response;
}
也许这样可行,我们使用这种方法没有任何问题
答案 1 :(得分:2)
早期的PHP版本中存在一个已知错误,其中的版本使用“--with-curl-wrappers”构建。
你是否有机会使用curl包装器进行编译?尝试重新编译,看看你的情况。
答案 2 :(得分:0)
Magento EE 1.11.0.0使用stream_content_set_option()
和file_get_contents()
调用的组合来构建和执行Solr请求,因此问题似乎与流处理有关PHP 5.2.16 * 。
由于时间不多,我刚刚覆盖了Apache_Solr_Service
类并修改了方法_sendRawGet()
和_sendRawPost()
以使用cURL请求而不是PHP流
到目前为止,这种解决方法完全正常(顺便说一句:感谢@zuloo。我有同样的想法使用cURL来解决方法,但只想将它作为最后的手段使用它。)
我仍然想知道在使用PHP流时导致此错误的原因(同时我的主要怀疑是分块传输编码)。也许其他人会匆匆离去并且能够解决问题,所以我现在要让这个问题保持不变。
*这有点奇怪,因为根据Magento EE specs,只需要PHP 5.2.13+。