Java 使用 HttpClient 调用 es restful api 操作es

前言

今天交付 ES 管理平台,因为 ES 有两套集群,分别是5.x 和 6.x 为了代码的通用性,需要把 Transport Client 的相关操作全部废弃,改为直接调用 rest api

准备工作

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.3</version>
        </dependency>

        <dependency>
            <groupId>com.arronlong</groupId>
            <artifactId>httpclientutil</artifactId>
            <version>1.0.4</version>
        </dependency>
<!--        工具集-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.3.8</version>
        </dependency>

相关操作

1.根据ip地址获取所有索引

/**
     * 获取所有索引index
     * @param ip
     * @return
     */
    public static List<IndexInfo> getAllIndex(String ip) {
        HttpConfig config = HttpConfig.custom().url("http://"+ip+":9200/_cat/indices?format=json&pretty");
        String jsonStr = null;
        try {
            jsonStr = HttpClientUtil.get(config);
        } catch (HttpProcessException e) {
            e.printStackTrace();
            return null;
        }
        JSONArray jsonArray = JSONUtil.parseArray(jsonStr);

        List<IndexInfo> list = new ArrayList<>();
        List<Map> maps = jsonArray.toList(Map.class);
        for(Map map : maps) {
            IndexInfo index = new IndexInfo();
            index.setHealth ((String)map.get("health"));
            index.setStatus ((String)map.get("status"));
            index.setIndex ((String)map.get("index"));
            index.setUuid ((String)map.get("uuid"));
            index.setPri ((String)map.get("pri"));
            index.setRep ((String)map.get("rep"));
            index.setDocs ((String)map.get("docs.count"));
            index.setDeleted ((String)map.get("docs.deleted"));
            index.setStoreSize ((String)map.get("store.size"));
            index.setPriStoreSize ((String)map.get("pri.store.size"));
            list.add(index);
        }
        return list;
    }

  查询结果解释

  • 索引健康(health),green为正常,yellow表示索引不可靠(单节点),red索引不可用。与集群健康状态一致。
  • 状态(status),表明索引是否打开。
  • 索引名称(index),这里有.kibana和school。
  • uuid,索引内部随机分配的名称,表示唯一标识这个索引。
  • 主分片(pri),这个就是集群的主分片数。
  • 文档数(docs.count)。
  • 已删除文档数(docs.deleted),这里统计了被删除文档的数量。
  • 索引存储的总容量(store.size),索引的总容量,是主分片总容量的两倍,因为存在一个副本。
  • 主分片的总容量(pri.store.size),主分片容量,是索引总容量的一半。

2.查看集群的健康状态

/**
     * 查看集群的健康状态
     *
     * @param ip
     * @return
     */
    public static List<Cluster> heathInfo(String ip) {
        HttpConfig config = HttpConfig.custom().url("http://" + ip + ":9200/_cat/health?format=json&pretty");
        String jsonStr = null;
        try {
            jsonStr = HttpClientUtil.get(config);
        } catch (HttpProcessException e) {
            e.printStackTrace();
            return null;
        }
        JSONArray jsonArray = JSONUtil.parseArray(jsonStr);

        List<Cluster> list = new ArrayList<>();
        List<Map> maps = jsonArray.toList(Map.class);
        for (Map map : maps) {
            Cluster cluster = new Cluster();
            cluster.setCluster((String) map.get("cluster"));
            cluster.setStatus((String) map.get("status"));
            cluster.setNodeTotal((String) map.get("node.total"));
            cluster.setNodeData((String) map.get("node.data"));
            cluster.setShards((String) map.get("shards"));
            cluster.setPri((String) map.get("pri"));
            cluster.setRelo((String) map.get("relo"));
            cluster.setInit((String) map.get("init"));
            cluster.setUnassign((String) map.get("unassign"));
            cluster.setPendingTasks((String) map.get("pending_tasks"));
            cluster.setMaxTaskWaitTime((String) map.get("max_task_wait_time"));
            cluster.setActiveShardsPercent((String) map.get("active_shards_percent"));
            list.add(cluster);
        }
        return list;
    }
  • cluster ,集群名称
  • status,集群状态 green代表健康;yellow代表分配了所有主分片,但至少缺少一个副本,此时集群数据仍旧完整;red代表部分主分片不可用,可能已经丢失数据。
  • node.total,代表在线的节点总数量
  • node.data,代表在线的数据节点的数量
  • shards, active_shards 存活的分片数量
  • pri,active_primary_shards 存活的主分片数量 正常情况下 shards的数量是pri的两倍。
  • relo, relocating_shards 迁移中的分片数量,正常情况为 0
  • init, initializing_shards 初始化中的分片数量 正常情况为 0
  • unassign, unassigned_shards 未分配的分片 正常情况为 0
  • pending_tasks,准备中的任务,任务指迁移分片等 正常情况为 0
  • max_task_wait_time,任务最长等待时间
  • active_shards_percent,正常分片百分比 正常情况为 100%

3.获取索引的基本信息(大小,文档数,字段。。)

/**
     * 获取索引基本信息
     */
    public static JSONObject getIndexInfo(String ip, String index) {
        // 获取索引的别名,字段,创建时间
        HttpConfig config = HttpConfig.custom().url("http://" + ip + ":9200/" + index);
        String jsonStr = null;
        try {
            jsonStr = HttpClientUtil.get(config);
        } catch (HttpProcessException e) {
            e.printStackTrace();
            return null;
        }
        JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
        JSONObject fields = jsonObject.getJSONObject(index).getJSONObject("mappings").getJSONObject("CrmLog").getJSONObject("properties");
        JSONObject aliases = jsonObject.getJSONObject(index).getJSONObject("aliases");
        JSONObject jsonIndex = jsonObject.getJSONObject(index).getJSONObject("settings").getJSONObject("index");
        // 时间戳
        String dateStr = jsonIndex.getStr("creation_date");
        Date date = new Date(Long.parseLong(dateStr));
        // 分片数
        String shards = (String) jsonIndex.get("number_of_shards");
        // 主分片数
        String pri = (String) jsonIndex.get("number_of_replicas");

        // 获取索引所占内存大小
        config = HttpConfig.custom().url("http://" + ip + ":9200/" + index + "/_stats");
        try {
            jsonStr = HttpClientUtil.get(config);
        } catch (HttpProcessException e) {
            e.printStackTrace();
            return null;
        }
        jsonObject = JSONUtil.parseObj(jsonStr);
        Integer byteNum = (Integer) jsonObject.getJSONObject("indices").getJSONObject(index).getJSONObject("primaries").getJSONObject("store").get("size_in_bytes");
        Integer docs = (Integer) jsonObject.getJSONObject("indices").getJSONObject(index).getJSONObject("primaries").getJSONObject("docs").get("count");

        // 整合输出结果
        String size;
        BigDecimal bigDecimal = new BigDecimal(byteNum);
        BigDecimal mb = bigDecimal.divide(BigDecimal.valueOf(1024 * 1024));
        BigDecimal gb = mb.divide(BigDecimal.valueOf(1024));
        if (gb.intValue() / 10 > 0) {
            size = gb.setScale(2, RoundingMode.HALF_UP) + " gb";
        } else {
            size = mb.setScale(2, RoundingMode.HALF_UP) + " mb";
        }

        JSONObject result = new JSONObject();
        list = getFields(fields);
        String[] aliaseArr = getAliases(aliases);
        result.putOpt("alise", aliaseArr);
        result.putOpt("date", DateUtil.format(date, "yyyy-MM-dd HH:mm:ss"));
        result.putOpt("shards", shards);
        result.putOpt("pri", pri);
        result.putOpt("size", size);
        result.putOpt("docs", docs);
        return result;
    }

    /**
     * 解析别名
     * @param aliases
     * @return
     */
    private static String[] getAliases(JSONObject aliases) {
        String[] aliaseArr = {};
        if(aliases.size() > 0) {
            aliaseArr = aliases.toString()
                    .replace("{", "")
                    .replace("}", "")
                    .replace(",", "")
                    .replace("\"", "")
                    .split(":");
        }
        return aliaseArr;
    }
/**
     * 解析出字段list
     * @param jsonObject
     * @return
     */
    private static List<ColumnModel> getFields(JSONObject jsonObject) {
        Map map = JSONUtil.toBean(jsonObject, Map.class);
        Set set = map.keySet();
        List<ColumnModel> list = new ArrayList<>();
        for(Object field : set) {
            String fname = (String) field;
            String type = jsonObject.getJSONObject(fname).getStr("type");
            ColumnModel columnModel = new ColumnModel();
            columnModel.setColumnName(fname);
            columnModel.setTypeName(type);
            list.add(columnModel);
        }
        return list;
    }

其他操作同理,只需要调用对应的 restful api 即可,拼接字符串过程比较冗长,在此不做展示了。有疑问可以留言

posted @ 2020-08-13 17:01  正在路上的兔子  阅读(2733)  评论(0编辑  收藏  举报