Solr 7.1高并发查询遇“无法分配请求地址/连接被拒”问题求助
解决高并发Solr查询中的连接错误问题
看起来你在高并发查询Solr时遇到了典型的客户端端口耗尽和服务端过载问题,这两个错误分别对应不同层面的瓶颈,我来给你逐个拆解解决方案:
一、解决"Cannot assign requested address (connect failed)"错误
这个错误本质是客户端本地TCP端口耗尽:Java默认每次查询新建HTTP短连接,每秒1万次查询会快速用完Ubuntu系统的可用临时端口,而且处于TIME_WAIT状态的端口还没来得及回收,导致无法新建连接。
解决方案:
启用SolrJ连接池
不要每次查询都新建HttpSolrClient实例,改用连接池复用连接,大幅减少端口占用。示例代码:// 初始化带连接池的Solr客户端 HttpSolrClient.Builder solrBuilder = new HttpSolrClient.Builder("http://10.*.*.*:8983/solr"); solrBuilder.withConnectionTimeout(5000); solrBuilder.withSocketTimeout(10000); // 配置连接池参数 PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); connManager.setMaxTotal(2000); // 全局最大连接数,根据服务器资源调整 connManager.setDefaultMaxPerRoute(500); // 每个Solr节点的最大连接数 // 绑定连接池到客户端 solrBuilder.setHttpClient(HttpClients.custom().setConnectionManager(connManager).build()); HttpSolrClient solrClient = solrBuilder.build();调整Ubuntu系统内核参数
修改系统端口配置,增加可用端口范围并加速TIME_WAIT端口回收:- 编辑
/etc/sysctl.conf,添加或修改以下内容:net.ipv4.ip_local_port_range = 1024 65535 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_fin_timeout = 30 - 执行
sudo sysctl -p让配置立即生效。
- 编辑
二、解决org.apache.solr.client.solrj.SolrServerException: Server refused connection错误
这个错误说明Solr服务端无法处理这么高的并发连接,可能是Jetty容器连接数限制、Solr资源不足或者查询效率太低导致的。
解决方案:
优化Solr Jetty容器配置
Solr7.1默认使用Jetty作为Web容器,需要调整其连接处理能力:- 编辑
solr-7.1.0/server/etc/jetty.xml:- 调高 acceptor和selector线程数(对应CPU核心数,一般设为核心数的1-2倍):
<Set name="acceptors">8</Set> <Set name="selectors">16</Set> - 增加最大连接数限制:在Connector节点添加
maxConnections配置:<Set name="maxConnections">10000</Set>
- 调高 acceptor和selector线程数(对应CPU核心数,一般设为核心数的1-2倍):
- 编辑
提升Solr资源配置
- 调整JVM堆内存:编辑
solr-7.1.0/bin/solr.in.sh,修改SOLR_HEAP参数(建议设置为服务器物理内存的50%,比如32G内存设为16G):SOLR_HEAP="16g" SOLR_JAVA_MEM="-Xms16g -Xmx16g -XX:+UseG1GC" - 优化查询缓存:编辑每个core的
solrconfig.xml,调整queryResultCache、filterCache的大小,比如:<cache name="queryResultCache" class="solr.LRUCache" size="10000" initialSize="5000" autowarmCount="5000"/>
- 调整JVM堆内存:编辑
优化查询语句
- 避免全表扫描,确保查询字段都有合适的索引;
- 使用
fq(过滤查询)提前过滤无关数据,减少结果集大小; - 使用
fl指定仅返回需要的字段,避免返回大字段或不必要的字段。
三、额外建议
- 逐步压测验证:不要直接上每秒1万次查询,从低并发(比如每秒1000次)开始逐步提升,观察系统的CPU、内存、端口占用和Solr的请求队列状态,找到系统的最优承载能力;
- 监控关键指标:用
netstat -an | grep TIME_WAIT查看客户端端口状态,通过Solr Admin UI(http://localhost:8983/solr)监控请求延迟、线程数、缓存命中率等指标,用top/htop监控服务器资源使用情况。
内容的提问来源于stack exchange,提问作者Susmita Sadhu
相关产品推荐
相关产品推荐

