外层接口从 GET 改成 POST,大参数请求仍然失败,可能是改错了通信层级。Spring Boot 接收请求,与它通过 SolrJ 调用 Solr,是两次独立的 HTTP 请求。
原来的连接错误和后续空指针
2019 年项目通过 Solr 获取分词结果。数据小时正常,数据增大后日志出现:
I/O exception (java.net.SocketException)
Connection reset by peer: socket write error
随后业务代码又报 NullPointerException。后一个异常不应盖住前面的通信失败:请求没成功取得 response,代码却继续读取分析结果。
我先把 Postman 到 Spring Boot 的调用改成 POST,又调整应用层请求头限制,仍然无效。
真正需要调整的是下游请求
Postman → Spring Boot 接口
Spring Boot 中的 SolrJ → Solr
第一跳的方法不会自动传递到第二跳。后来对 SolrJ 的 FieldAnalysisRequest 显式设置 POST,当时的大参数请求恢复。
把设置放进实际请求对象
以下使用 SolrJ 8.0 API,客户端由调用方创建、复用并关闭,core 必须已有指定字段和分析处理器:
public static org.apache.solr.client.solrj.response.FieldAnalysisResponse
analyze(org.apache.solr.client.solrj.SolrClient client,
String field, String text)
throws java.io.IOException,
org.apache.solr.client.solrj.SolrServerException {
org.apache.solr.client.solrj.request.FieldAnalysisRequest request =
new org.apache.solr.client.solrj.request.FieldAnalysisRequest(
"/analysis/field");
request.addFieldName(field);
request.setFieldValue("");
request.setQuery(text);
request.setMethod(org.apache.solr.client.solrj.SolrRequest.METHOD.POST);
return request.process(client);
}
异常向调用方传播,由统一边界记录和处理,不打印后继续使用 null。具体 token 解析可参考 查询分析阶段的读取。SolrJ 8.0 请求源码
POST 不是无限容量,也不是唯一根因证明
这次结果与大查询参数的传输方式有关,但仅凭连接重置,不能确定是代理、容器、Solr 还是网络设备主动断开。应比较下游实际方法、参数字节数、状态、服务端日志及限制,而不是只提高 Spring Boot 的配置。
POST 也可能受到请求体、超时和内存限制。大型分析任务还需合理分批;在确认失败阶段前,不应盲目自动重试或把所有 IOException 当作可忽略告警。