You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用SolrJ检查Solr服务器各索引分片的IP运行状态

使用SolrJ获取Solr分片IP并检测故障服务器

核心思路

其实Solr集群的所有节点、分片信息都可以通过它的Admin API获取,而SolrJ已经封装了这些API的调用逻辑。我们只需要:

  1. 通过Solr的HTTP URL初始化Solr客户端
  2. 调用集群状态查询接口,拿到所有分片和对应节点的详细信息
  3. 解析出每个节点的IP和端口
  4. 对每个节点进行连通性检测,筛选出故障下线的服务器

第一步:引入SolrJ依赖

如果是用Maven管理项目,在pom.xml里添加以下依赖(版本要和你的Solr集群版本一致,避免兼容性问题):

<dependency>
    <groupId>org.apache.solr</groupId>
    <artifactId>solr-solrj</artifactId>
    <version>8.11.2</version> <!-- 替换成你的Solr版本 -->
</dependency>

如果是手动导入jar包,直接去Solr官网下载对应版本的solr-solrj-xxx.jar及其依赖包即可。

第二步:完整Java代码实现

下面是可以直接在Eclipse中运行的代码,包含了获取分片IP/端口、故障检测的完整逻辑:

import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.request.admin.AdminRequest;
import org.apache.solr.client.solrj.response.ClusterStatusResponse;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.ZkCoreNodeProps;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;

public class SolrShardMonitor {
    // Solr集群的HTTP入口地址(比如你的SolrCloud的任意一个节点地址)
    private static final String SOLR_BASE_URL = "http://your-solr-host:8983/solr";
    // 节点连通性检测的超时时间(毫秒)
    private static final int CONNECTION_TIMEOUT = 5000;

    public static void main(String[] args) {
        // 1. 初始化Solr客户端
        try (SolrClient solrClient = new HttpSolrClient.Builder(SOLR_BASE_URL).build()) {
            // 2. 获取集群状态信息
            AdminRequest.ClusterStatus clusterStatusReq = new AdminRequest.ClusterStatus();
            ClusterStatusResponse clusterStatusResp = clusterStatusReq.process(solrClient);
            ClusterState clusterState = clusterStatusResp.getClusterState();

            // 3. 收集所有分片对应的节点IP和端口(去重,因为一个节点可能属于多个分片)
            Set<String> uniqueNodes = new HashSet<>();
            // 遍历集群中的所有集合(如果只需要特定集合,替换成集合名称即可)
            for (String collectionName : clusterState.getCollections()) {
                // 获取集合的所有分片
                Map<String, Slice> slices = clusterState.getSlicesMap(collectionName);
                for (Slice slice : slices.values()) {
                    // 获取分片的所有副本
                    for (Replica replica : slice.getReplicas()) {
                        // 从副本的属性中提取节点的基础URL
                        String nodeBaseUrl = replica.getStr(ZkCoreNodeProps.BASE_URL_PROP);
                        // 解析URL,提取IP和端口
                        URL url = new URL(nodeBaseUrl);
                        String nodeInfo = url.getHost() + ":" + url.getPort();
                        uniqueNodes.add(nodeInfo);
                    }
                }
            }

            // 4. 检测每个节点的状态,筛选故障节点
            List<String> downNodes = new ArrayList<>();
            for (String node : uniqueNodes) {
                if (!isNodeAlive(node)) {
                    downNodes.add(node);
                }
            }

            // 输出结果
            System.out.println("所有集群节点(IP:端口):");
            uniqueNodes.forEach(System.out::println);
            System.out.println("\n故障下线的节点:");
            if (downNodes.isEmpty()) {
                System.out.println("无故障节点");
            } else {
                downNodes.forEach(System.out::println);
            }

        } catch (SolrServerException | IOException e) {
            e.printStackTrace();
            System.err.println("获取集群状态或检测节点时发生错误:" + e.getMessage());
        }
    }

    /**
     * 检测Solr节点是否存活
     * @param nodeInfo 节点的IP:端口,比如192.168.1.100:8983
     * @return true表示存活,false表示故障
     */
    private static boolean isNodeAlive(String nodeInfo) {
        try {
            // 构造节点的健康检查URL(Solr的系统信息接口)
            URL healthCheckUrl = new URL("http://" + nodeInfo + "/solr/admin/info/system");
            HttpURLConnection connection = (HttpURLConnection) healthCheckUrl.openConnection();
            connection.setConnectTimeout(CONNECTION_TIMEOUT);
            connection.setReadTimeout(CONNECTION_TIMEOUT);
            connection.setRequestMethod("GET");

            // 如果响应码在200-399之间,认为节点存活
            int responseCode = connection.getResponseCode();
            connection.disconnect();
            return responseCode >= 200 && responseCode < 400;
        } catch (IOException e) {
            // 发生IO异常(无法连接、超时等),认为节点故障
            return false;
        }
    }
}

关键代码说明

  • 获取集群状态:通过AdminRequest.ClusterStatus来调用Solr的集群状态API,不需要知道ZooKeeper地址,只需要任意一个Solr节点的HTTP URL即可。
  • 解析节点信息:从副本的BASE_URL_PROP属性中拿到节点的完整URL,再通过URL类解析出IP和端口,用HashSet去重避免重复检测同一个节点。
  • 故障检测:通过访问节点的/solr/admin/info/system接口来判断节点是否存活,设置超时时间避免长时间等待。

注意事项

  1. 确保SolrJ的版本和你的Solr集群版本完全一致,否则可能出现兼容性问题(比如不同版本的集群状态返回格式不同)。
  2. 如果你的Solr集群开启了身份验证,需要在初始化HttpSolrClient时添加认证信息,比如:
    new HttpSolrClient.Builder(SOLR_BASE_URL)
        .withBasicAuth("username", "password")
        .build();
    
  3. 可以根据需求修改代码,比如只检测特定集合的分片,或者调整超时时间。

内容的提问来源于stack exchange,提问作者Anonymous Ninja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:20:37