ELK日志收集系统调研(五) -- ElasticSearch Java接口

本文介绍了一个基于Elasticsearch Java API的文件信息索引案例,包括构造文件信息类、实现JSON映射及使用ESHandle接口进行索引、检索等操作。

在研究ELK日志收集系统时,顺便对于ElasticSearch的javaapi了解了下。
于是将自己写的测试代码上传做个备注。

Fileinfo.java
构造数据类,模拟的是文件的具体信息。

package com.elastic;

import java.io.File;
import java.io.IOException;
import java.util.Date;

import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;

public class FileInfo 
{
    // 文件名称
    private String filename;

    // 文件路径
    private String filepath;

    // 文件大小
    private Long filesize;

    // 作者
    private String fileauthor;

    // 最后更新日期
    private Date filedate;

    public FileInfo()
    {
        super();
    }

    public FileInfo(String filename, String filepath, Long filesize, String fileauthor)
    {
        super();
        this.filename = filename;
        this.filepath = filepath;
        this.filesize = filesize;
        this.fileauthor = fileauthor;
    }

    /**
     * @return filename
     */
    public String getFilename() 
    {
        return filename;
    }

    /**
     * @param filename 要设置的 filename
     */
    public void setFilename(String filename) 
    {
        this.filename = filename;
    }

    /**
     * @return filepath
     */
    public String getFilepath() 
    {
        return filepath;
    }

    /**
     * @param filepath 要设置的 filepath
     */
    public void setFilepath(String filepath) 
    {
        this.filepath = filepath;
    }

    /**
     * @return filesize
     */
    public Long getFilesize() 
    {
        return filesize;
    }

    /**
     * @param filesize 要设置的 filesize
     */
    public void setFilesize(Long filesize) 
    {
        this.filesize = filesize;
    }

    /**
     * @return fileauthor
     */
    public String getFileauthor() 
    {
        return fileauthor;
    }

    /**
     * @param fileauthor 要设置的 fileauthor
     */
    public void setFileauthor(String fileauthor) 
    {
        this.fileauthor = fileauthor;
    }

    /**
     * @return filedate
     */
    public Date getFiledate() 
    {
        return filedate;
    }

    /**
     * @param filedate 要设置的 filedate
     */
    public void setFiledate(Date filedate) 
    {
        this.filedate = filedate;
    }

    /**
     * 
     * @return json对象(mapping)
     */
    public String toJsonStr()
    {
        String jsonData = null;

        try 
        {
            XContentBuilder jsonBuild = XContentFactory.jsonBuilder()
                .startObject()
                    .field("filename", filename)
                    .field("filepath", filepath)
                    .field("filesize", filesize)
                    .field("fileauthor", fileauthor)
                    .field("filedate", new Date(new File(filepath).lastModified()))
                .endObject();

            jsonData = jsonBuild.string();
        } 
        catch (IOException e)
        {
            System.out.println("build Json String failed!");
        }
        return jsonData;
    }
}

ESHandle.java
ES相关的方法接口

package com.elastic;

import java.util.List;

import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.deletebyquery.DeleteByQueryResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.node.Node;
import org.elasticsearch.node.NodeBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;

public class ESHandler 
{   
    public Client client;

    // TransportClient方式
    public ESHandler(String clusterName, String ip)
    {
        if (null == client)
        {
            client = new TransportClient(ImmutableSettings.settingsBuilder()
                    .put("client.transport.sniff", true)
                    .put("cluster.name", clusterName)
                    .build())
                    .addTransportAddress(new InetSocketTransportAddress(ip, 9300));
        }
    }

    // Node方式,指定clusterName
    public ESHandler(String clusterName)
    {
        if (null == client)
        {
            Node node = NodeBuilder.nodeBuilder().clusterName(clusterName).client(true).node();

            client = node.client();
        }
    }

    // 单条数据索引
    public IndexResponse IndexSingleDoc(String indexName, String type, String id, String jsondata)
    {
        IndexRequestBuilder requestBuilder = null;

        // 指定id,或者由ES随即生成ID
        if (isStringEmptyOrNull(id))
        {
            requestBuilder = client.prepareIndex(indexName, type);
        }
        else
        {
            requestBuilder = client.prepareIndex(indexName, type, id);
        }

        return requestBuilder.setSource(jsondata).execute().actionGet();
    }

    // 单条数据获取
    public GetResponse getSingleDoc(String indexName, String type, String id)
    {
        return client.prepareGet(indexName, type, id)
                     .execute()
                     .actionGet();
    }

    // 单条数据删除
    public DeleteResponse deleteSingleDoc(String indexName, String type, String id)
    {
        return client.prepareDelete(indexName, type, id)
                     .setOperationThreaded(false)
                     .execute().actionGet();
    }

    // 通过Query删除数据
    public DeleteByQueryResponse deleteByQuery(String indexName, QueryBuilder querybuilder)
    {
        return client.prepareDeleteByQuery(indexName)
                     .setQuery(querybuilder)
                     .execute()
                     .actionGet();
    }

    // 批量数据索引
    public BulkResponse bulkIndex(String indexName, String type, List<String> jsondata)
    {
        BulkRequestBuilder bulkRequest = client.prepareBulk();

        for(int i = 0; i < jsondata.size(); i++)
        {
            IndexRequestBuilder requestBuilder = client.prepareIndex(indexName, type).setRefresh(true);
            bulkRequest.add(requestBuilder.setSource(jsondata.get(i)));
        }

        BulkResponse response = bulkRequest.execute().actionGet();

        if (response.hasFailures())
        {
            System.out.println("Buld Index failed!Msg: " + response.buildFailureMessage());
        }

        return response;
    }

    // 处理搜索结果
    public void dealWithResponse(SearchHits hits)
    {
        SearchHit[] searchHits = hits.getHits();

        System.out.println(searchHits.length);

        for(SearchHit hit:searchHits)
        {   
            System.out.println((String)hit.getSource().get("type") 
                    + "|"
                    + (String)hit.getSource().get("message"));
        }
    }

    public void close()
    {
        client.close();
    }

    public static boolean isStringEmptyOrNull(String str)
    {
        if (null == str || "".equals(str))
        {
            return true;
        }

        return false;
    }
}
服务健康监测系统用于实时监控服务的运行状态、性能指标和可用性,通常包含数据采集、存储、分析和告警等功能模块。以下是其核心方案、实现原理与技术选型的详细说明: ### **一、常见方案** 1. **集中式监控方案** - **架构**:通过Agent采集数据,发送至中央服务器(如Prometheus、Zabbix),由统一平台处理和展示。 - **适用场景**:大规模分布式系统,需集中管理多个服务的健康状态。 - **优势**:统一视图、支持历史数据分析;**劣势**:单点故障风险、扩展性依赖中央组件。 2. **分布式监控方案** - **架构**:每个服务节点独立运行监控组件(如Spring Boot Actuator),通过消息队列或API聚合数据。 - **适用场景**:微服务架构,需低延迟、高可用的监控。 - **优势**:去中心化、容错性强;**劣势**:数据一致性维护成本高。 3. **云原生监控方案** - **工具**:基于Kubernetes的Prometheus+Grafana、AWS CloudWatch、阿里云ARMS等。 - **适用场景**:云环境或容器化部署,需与编排系统深度集成。 ### **二、实现原理** 1. **数据采集** - **主动轮询**:监控系统定期请求服务接口(如HTTP健康检查)。 - **被动上报**:服务通过Agent主动推送指标(如Telegraf、Prometheus Pushgateway)。 - **指标类型**: - **基础指标**:CPU、内存、磁盘I/O(通过JMX、/proc文件系统等获取)。 - **业务指标**:接口响应时间、错误率、订单量等(通过埋点或AOP实现)。 2. **数据存储** - **时序数据库**:Prometheus的TSDB、InfluxDB,适合存储高频指标。 - **日志存储**:ELKElasticsearch+Logstash+Kibana)或Loki,用于分析异常日志。 3. **告警与通知** - **规则引擎**:Prometheus的Alertmanager、ELK的Watcher,基于阈值或异常检测触发告警。 - **通知渠道**:邮件、短信、Webhook(如钉钉、企业微信)、PagerDuty等。 4. **可视化** - **仪表盘**:Grafana、Kibana,支持自定义图表和告警规则。 - **拓扑图**:通过服务依赖关系(如Spring Cloud Sleuth+Zipkin)展示调用链。 ### **三、技术选型** | **模块** | **推荐技术** | **适用场景** | |----------------|---------------------------------------|----------------------------------| | **数据采集** | Prometheus Exporter、Spring Boot Actuator、Micrometer | Java/微服务监控 | | **数据存储** | Prometheus TSDB、InfluxDB、TimescaleDB | 时序数据存储 | | **日志分析** | ELK Stack、Loki+Grafana | 结构化/非结构化日志检索 | | **告警管理** | Alertmanager、ELK Watcher、Zabbix | 规则引擎与通知集成 | | **可视化** | Grafana、Kibana、SkyWalking UI | 实时监控与历史分析 | | **分布式追踪** | SkyWalking、Zipkin、Jaeger | 微服务调用链分析 | ### **四、关键技术点** 1. **健康检查接口** - 实现 `/health` 端点(如Spring Boot Actuator),返回JSON格式的状态(UP/DOWN)及详细信息(如数据库连接状态)。 - 示例: ```java @Endpoint(id = "customhealth") @Component public class CustomHealthIndicator implements HealthIndicator { @Override public Health health() { boolean isDbOk = checkDatabase(); // 自定义检查逻辑 return isDbOk ? Health.up().build() : Health.down().build(); } } ``` 2. **指标暴露** - 使用Micrometer注册自定义指标(如请求成功率): ```java @Bean public MeterRegistry meterRegistry() { return new SimpleMeterRegistry(); } @RestController public class ApiController { @Autowired private MeterRegistry registry; @GetMapping("/api") public String api() { registry.counter("api.requests").increment(); return "OK"; } } ``` 3. **容器化监控** - 通过Prometheus的cAdvisor采集容器指标(CPU、内存、网络),结合Kubernetes的ServiceMonitor实现自动发现。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值