外层接口从 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 当作可忽略告警。