云监控发布事件监控功能,助力开发者快速提升业务稳定性

简介: 服务在运行过程中,难免出现异常情况,严重异常甚至会中断您的业务。传统方法是通过开源的ELK(ElasticSearch, Logstash, Kibana)等收集和查询异常,并对接消息网关发送报警。但这些开源系统往往是由多个复杂的分布式系统组成,自行搭建和维护面临着技术门槛高、时间和人力成本高的问题。

应用场景

服务在运行过程中,难免出现异常情况,有些异常通过重试等手段可以自动恢复,有些则不能,严重异常甚至会中断客户业务。所以我们需要一个系统来记录这些异常,并且在满足特定的条件时触发报警。传统方法是打印文件日志,通过收集日志到特定的系统,例如开源的ELK(ElasticSearch, Logstash, Kibana)中。 这些开源的系统往往是由多个复杂的分布式系统组成,自行维护面临着技术门槛高、时间和人力成本高的问题。

云监控提供了一个开箱即用的事件监控功能,能很好解决这些问题。 下面通过几个例子简单说明下如何使用事件监控功能。

实战案例

第一步:上报异常

事件监控提供了JAVA SDK和Open API两种上报数据的方式,这里介绍通过JAVA SDK 上报数据。

Step1 添加 Maven 依赖

<dependency>
    <groupId>com.aliyun.openservices</groupId>
    <artifactId>aliyun-cms</artifactId>
    <version>0.1.2</version>
</dependency>

Step2 初始化SDK

// 这里的118代表云监控的应用分组ID,可以以应用的角度来对事件归类, 可以到云监控应用分组列表中查看分组的ID。
CMSClientInit.groupId = 118L;

// 这里的地址是事件系统上报的入口,目前是公网地址。accesskey和secretkey用于身份识别。
CMSClient c = new CMSClient("https://metrichub-cms-cn-hangzhou.aliyuncs.com", accesskey, secretkey);

Step3 考虑是否异步上报数据

云监控事件默认提供了同步的上报策略。 好处是编写代码简单、 保证每次上报事件的可靠,不丢失数据。

但是同步策略也带来一些问题。因为要在业务代码中嵌入事件上报代码,如果网络出现波动,可能会出现阻塞代码执行,影响正常的业务。
有很多业务场景并不需要100%要求事件可靠不丢,所以我们需要一个简单的异步上报封装。将事件写到一个LinkedBlockingQueue中,然后通过ScheduledExecutorService异步在后台批量上报。

//初始化queue与Executors:
private LinkedBlockingQueue<EventEntry> eventQueue = new LinkedBlockingQueue<EventEntry>(10000);
private ScheduledExecutorService schedule = Executors.newSingleThreadScheduledExecutor();

//上报事件:
//每一个事件都包含事件的名称与事件的内容,名称用于识别事件,内容是事件的详细信息,支持全文搜索。
public void put(String name, String content) {
    EventEntry event = new EventEntry(name, content);

    // 这里事件队列满后将直接丢弃,可以根据自己的情况调整这个策略。
    boolean b = eventQueue.offer(event);
    if (!b) {
        logger.warn("事件队列已满,丢弃事件:{}", event);
    }
}

//异步提交事件,初始化定时任务,每秒执行run方法批量上报事件。可以根据自己的情况调整上报间隔。
schedule.scheduleAtFixedRate(this, 1, 1, TimeUnit.SECONDS);

public void run() {
    do {
        batchPut();
    } while (this.eventQueue.size() > 500);
}

private void batchPut() {
    // 从队列中取出99条事件,用于批量上报
    List<CustomEvent> events = new ArrayList<CustomEvent>();
    for (int i = 0; i < 99; i++) {
        EventEntry e = this.eventQueue.poll();
        if (e == null) {
            break;
        }
        events.add(CustomEvent.builder().setContent(e.getContent()).setName(e.getName()).build());
    }
    if (events.isEmpty()) {
        return;
    }


    // 批量上报事件到云监控, 这里并未重试, SDK也没有重试, 如果对事件可靠度要求高需要自己加重试策略。
    try {
        CustomEventUploadRequestBuilder builder = CustomEventUploadRequest.builder();
        builder.setEventList(events);
        CustomEventUploadResponse response = cmsClient.putCustomEvent(builder.build());
        if (!"200".equals(response.getErrorCode())) {
            logger.warn("上报事件错误:msg: {}, rid: {}", response.getErrorMsg(), response.getRequestId());
        }
    } catch (Exception e1) {
        logger.error("上报事件异常", e1);
    }
}

Step4 事件上报Demo

Demo1:http controller的异常监控

主要目的是监控http请求是否有大量异常,如果每分钟异常次数超过一定数量就报警。

实现原理是通过spring的拦截器或者servlet filter等技术对HTTP请求拦截,如果出现异常就记录日志,最后通过配置报警规则来达到报警的目的。

上报事件的demo如下:

// 每个事件应该有丰富的信息来帮助我们搜索和定位问题,这里使用的map来组织事件, 最后转成Json格式作为事件的content。 
Map<String, String> eventContent = new HashMap<String, String>();
eventContent.put("method", "GET");  // http 请求方法
eventContent.put("path", "/users"); // http path
eventContent.put("exception", e.getClass().getName()); //异常类名,方便搜索
eventContent.put("error", e.getMessage()); // 异常报错信息
eventContent.put("stack_trace", ExceptionUtils.getStackTrace(e)); // 异常堆栈,方便定位问题

// 最后使用前面封装好的异步上报方法提交事件,这里是异步上报,并且没有重试,可能会小概率丢事件,但是已经能很好的满足http未知异常报警这个场景了。
put("http_error", JsonUtils.toJson(eventContent));

image.png

Demo2:后台定时任务执行情况的监控与消息消费情况的监控

同上面的http事件,有很多类似的业务场景需要报警,例如后台任务与消息队列消费等,都可以通过类似的方式上报事件达到监控的目的。当异常发生时,第一时间收到报警。


//消息队列的事件组织:

Map<String, String> eventContent = new HashMap<String, String>();
eventContent.put("cid", consumerId);  // 代表消费者的身份
eventContent.put("mid", msg.getMsgId()); // 消息的id
eventContent.put("topic", msg.getTopic()); // 消息的主题,
eventContent.put("body", body); // 消息的主体
eventContent.put("reconsume_times", String.valueOf(msg.getReconsumeTimes())); // 消息失败重试的次数
eventContent.put("exception", e.getClass().getName()); // 发生异常时的异常类名
eventContent.put("error", e.getMessage()); // 异常信息
eventContent.put("stack_trace", ExceptionUtils.getStackTrace(e)); // 异常堆栈

// 最后上报事件
put("metaq_error", JsonUtils.toJson(eventContent)); 

上报后查看事件
message

对队列消息消费异常设置报警:
alert

Demo 3:记录重要事件

事件还有一种使用场景是用来记录一些重要的业务发生,但是不需要报警,方便日后翻看。 例如重要业务的操作日志,改密码,修改订单,异地登录等。

查询事件

相关实践学习
RocketMQ监控/告警一站式搭建应用
RocketMQ监控/告警一站式搭建演示
目录
相关文章
|
SQL 消息中间件 分布式计算
基于阿里云 CloudMonitor云监控自定义监控大盘对 EMR 自定义监控实践
本文旨在分享 EMR 平台大数据服务基于阿里云 CloudMonitor 的监控实践,给客户提供除了 EMR 平台默认监控以外,自建监控方式,适用于统一多个阿里云服务的监控监控场景。
667 1
基于阿里云 CloudMonitor云监控自定义监控大盘对 EMR 自定义监控实践
|
弹性计算 监控 应用服务中间件
云监控之自定义监控
云监控之自定义监控
|
监控 负载均衡 网络协议
云监控-主机监控功能介绍|学习笔记
快速学习云监控-主机监控功能介绍
177 0
云监控-主机监控功能介绍|学习笔记
|
弹性计算 监控 开发者
云监控-创建 Dashboard 监控大盘|学习笔记
快速学习云监控-创建 Dashboard 监控大盘
135 0
云监控-创建 Dashboard 监控大盘|学习笔记
|
弹性计算 监控 开发者
云监控-创建Dashboard监控大盘|学习笔记
快速学习云监控-创建Dashboard监控大盘
191 0
云监控-创建Dashboard监控大盘|学习笔记
|
监控 算法
云监控中通过HTTP上报事件监控数据
云监控中通过HTTP上报事件监控数据
188 0
云监控中通过HTTP上报事件监控数据
|
Prometheus 监控 Cloud Native
使用云监控进行跨账号监控
前言云监控的跨账号监控依赖资源目录RD(Resource Directory),RD的具体操作见其官方文档。需要前当前登录的账号是RD的主账号MA(Master Account)或者是云监控的委派管理员DA(DelegatedAdminAccount)才能进行跨账号监控数据管理。主账号MA无需进行任何设置,只需登陆云监控的控制台正常操作就行。但如果需要某个成员账号也能在云监控上管理其他账号的数据,
3117 0
使用云监控进行跨账号监控
|
监控 网络协议
云监控 -- 站点监控
站点监控是一款定位于互联网网络探测的监控产品,主要用于通过遍布全国的互联网终端节点,发送模拟真实用户访问的探测请求,监控全国各省市运营商网络终端用户到您服务站点的访问情况
479 0
云监控 -- 站点监控
|
监控
云监控 --- 自定义监控
自定义监控为您提供了自定义监控项和报警规则的功能,您可以通过上报监控数据接口,将自己关心的业务指标上报至云监控,并在云监控上添加监控图标和设置报警规则,对于故障指标发送报警通知,便于您及时处理故障,保障业务的正常运行。
427 0
云监控 --- 自定义监控
|
数据采集 Prometheus 监控
使用云监控来监控线下IDC(及其它云)的Mongodb,Redis,Mysql等中间件
背景当前很多用户的服务部署在混合环境中,比如同时使用多个云厂商,或者云加线下IDC等。而对于线下IDC的监控主要是使用开源的系统来自建。带来的问题就是需要花费较大精力来维护自建监控系统并且和云上的监控数据也无法打通。针对这种混合云环境,云监控推出了企业版监控服务,可以实现在阿里云上对下线IDC或其它云服务上部署的中间件进行监控。线下IDC中间件监控实现在云监控上对下线IDC的中间件进行监控,主要实
519 0
使用云监控来监控线下IDC(及其它云)的Mongodb,Redis,Mysql等中间件