【新功能发布】事件监控升级-支持自动化处理云产品异常

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
云监控,每月短信1000条
应用型负载均衡 ALB,每月750个小时 15LCU
简介: 事件监控发布新版本,支持在云产品的系统事件发生时,分发给您的消息服务队列、函数计算,以便后续自动化处理这些异常。

背景

系统事件监控为用户提供各类云产品产生的系统事件的统一统计和查询入口,使得用户明确知晓云产品的使用状态,让云更透明。

本月的新版本,支持在这些产品的系统事件发生时,分发给您的消息服务队列、函数计算,以便后续自动化处理这些异常。

原理解读

事件发生时,云产品会将事件推送给云监控,云监控收到事件后,检查您是否配置了报警规则,如果有相关配置,会根据报警规则的配置将事件分发到相应渠道。
image

最佳实践分享

如何在ECS宕机时,通过函数计算将EIP迁移到另一台机器上。并且发送事件到消息服务的队列中。

创建函数计算

  1. 登录函数计算控制台:https://fc.console.aliyun.com/overview/cn-shanghai
  2. 新建服务
    image
  3. 新建函数
    image

选择空白函数,不创建触发器,以Java8运行环境为例
image
上传一段EIP从机器A解绑后,绑定到机器B的代码逻辑,jar包中的代码见文章结尾分享。
image

函数入口为com.aliyun.cms.fc.driver.FCDriver::handleRequest
image
无需其他权限设置,点击创建后保存函数

创建消息服务的队列

  1. 登录消息服务控制台:https://mns.console.aliyun.com/#/list/cn-hangzhou
  2. 创建队列
    image

创建云监控系统事件报警

  1. 登录云监控事件监控控制台:https://cloudmonitor.console.aliyun.com/#/eventmonitoring/alarmrules
  2. 创建事件报警规则
    19_24_30__08_06_2018

点击按钮进入创建报警规则页面
19_33_10__08_06_2018

首次使用先点击授权,允许云监控向您的队列和函数发送事件。
19_34_11__08_06_2018

授权后,选择上一步创建好的队列和函数,保存设置。
19_37_06__08_06_2018

调试事件

您可以使用系统事件的调试功能,模拟系统事件的发生,以便验证报警规则中设置的消息服务队列是否能正常接收时间、函数计算的函数是否能正常被触发。

  1. 点击报警规则列表的调试操作,进入调试页面
    22
  2. 选择需要调试的事件,内容中会显示相应的事件内容,可以根据实际情况修改内容中的实例id等字段。
    33
  3. 点击确定按钮,将根据内容发送一个事件,触发函数计算的逻辑、向消息服务队列中写一个事件。

查看结果

  1. 查看消息服务的队列信息
    消息服务队列的列表页点击接收消息,可以看到队列里收到了调试发出的事件。

19_43_57__08_06_2018

  1. 弹性公网IP控制台查看IP已经从一台实例解绑后,重新绑定到另一台实例。
  2. 在函数计算的代码执行模块,可以查询执行结果。
    20_34_49__08_06_2018

示例代码

  • maven依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.aliyun.cms</groupId>
    <artifactId>drive-fc</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>com.aliyun.fc.runtime</groupId>
            <artifactId>fc-java-core</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-ecs</artifactId>
            <version>4.9.4</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-slb</artifactId>
            <version>3.2.6</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.0.3</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.48</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.1.0</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <appendAssemblyId>false</appendAssemblyId> <!-- this is used for not append id to the jar name -->
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id> <!-- this is used for inheritance merges -->
                        <phase>package</phase> <!-- bind to the packaging phase -->
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
  • Java 代码

示例包含EIP的解绑、绑定,SLB后端ESC实例的绑定、解绑,磁盘的挂载。试用时请将实例id、AK、SK等信息替换成您的具体信息,示例仅供演示参考,具体事件发生时应做的处理,需要根据您的实际业务决定。

package com.aliyun.cms.fc.driver;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.FunctionComputeLogger;
import com.aliyun.fc.runtime.StreamRequestHandler;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.ecs.model.v20140526.*;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.slb.model.v20140515.AddBackendServersRequest;
import com.aliyuncs.slb.model.v20140515.AddBackendServersResponse;
import com.aliyuncs.slb.model.v20140515.RemoveBackendServersRequest;
import com.aliyuncs.slb.model.v20140515.RemoveBackendServersResponse;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
public class FCDriver implements StreamRequestHandler 
   private static final String ak = "*";
   private static final String aks = "*";

   /**
    *
    * @param inputStream
    * @param outputStream
    * @param context
    * @throws IOException
    */
   @Override
   public void handleRequest(
           InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
       String input = IOUtils.toString(inputStream, StandardCharsets.UTF_8.name());
       JSONObject event = JSON.parseObject(input, JSONObject.class);
       context.getLogger().info("receive event message: " + event);
       String product = event.getString("product");
       if ("ECS1".equalsIgnoreCase(product)) {
           handleECS(context.getLogger(), event);
       }
       outputStream.write("ok".getBytes());
   }

   public void handleECS(FunctionComputeLogger logger, JSONObject event) {
       JSONObject content = event.getJSONObject("content");
       String ecsInstanceId = content.getString("ecsInstanceId");
       String regionId = event.getString("regionId");
       String name = event.getString("name");
       String eipId = "eip-*";
       if ("Disk:Stalled:Executing".equalsIgnoreCase(name)){
           unassociateEipAddress(regionId, ecsInstanceId, eipId, logger);
           try {
               TimeUnit.SECONDS.sleep(30);
           } catch (InterruptedException e) {
           }
           associateEipAddress(regionId, "i-****", eipId, logger);
       }else if ("Disk:Stalled:Executed".equalsIgnoreCase(name)){
           unassociateEipAddress(regionId, "i-****", eipId, logger);
           try {
               TimeUnit.SECONDS.sleep(30);
           } catch (InterruptedException e) {
           }
           associateEipAddress(regionId, ecsInstanceId, eipId, logger);
       }else if ("Instance:SystemFailure.Reboot:Executing".equalsIgnoreCase(name)){
           unassociateEipAddress(regionId, ecsInstanceId, eipId, logger);
           try {
               TimeUnit.SECONDS.sleep(30);
           } catch (InterruptedException e) {
           }
           associateEipAddress(regionId, "i-****", eipId, logger);
       }else if ("Instance:SystemFailure.Reboot:Executed".equalsIgnoreCase(name)){
           unassociateEipAddress(regionId, "i-****", eipId, logger);
           try {
               TimeUnit.SECONDS.sleep(30);
           } catch (InterruptedException e) {
           }
           associateEipAddress(regionId, ecsInstanceId, eipId, logger);
       }
   }

   private void associateEipAddress(String regionId, String ecsInstanceId, String eipId, FunctionComputeLogger logger ) {
       DefaultProfile profile = DefaultProfile.getProfile(regionId, ak, aks);
       IAcsClient client = new DefaultAcsClient(profile);

       try {
           for (int count=0;count<5;count++) {
               DescribeEipAddressesRequest describeEipAddressesRequest = new DescribeEipAddressesRequest();
               describeEipAddressesRequest.setAllocationId(eipId);
               describeEipAddressesRequest.setRegionId(regionId);
               DescribeEipAddressesResponse describeEipAddressesResponse = client.getAcsResponse(describeEipAddressesRequest);
               if (describeEipAddressesResponse!=null&&describeEipAddressesResponse.getEipAddresses()!=null&&"vailable".equalsIgnoreCase(describeEipAddressesResponse.getEipAddresses().get(0).getStatus())){
                   AssociateEipAddressRequest request = new AssociateEipAddressRequest();
                   request.setInstanceId(ecsInstanceId);
                   request.setAllocationId(eipId);
                   try {
                       AssociateEipAddressResponse response = client.getAcsResponse(request);
                       logger.info(String.format("Associate eip %s to ecs %s, requestId:%s, ", eipId, ecsInstanceId, response.getRequestId()));
                   } catch (ClientException e) {
                       logger.info(String.format("Failure of associate eip %s to ecs %s, errorMsg:%s", eipId, ecsInstanceId, e.getLocalizedMessage()));
                   }
                   return;
               }
               TimeUnit.SECONDS.sleep(5);
           }
       } catch (InterruptedException | ClientException e) {
           logger.info(String.format("Failure of describe eip %s, errorMsg:%s", eipId, e.getLocalizedMessage()));
       }
   }

   private void unassociateEipAddress(String regionId, String ecsInstanceId, String eipId, FunctionComputeLogger logger) {
       DefaultProfile profile = DefaultProfile.getProfile(regionId, ak, aks);
       IAcsClient client = new DefaultAcsClient(profile);

       UnassociateEipAddressRequest request = new UnassociateEipAddressRequest();
       request.setInstanceId(ecsInstanceId);
       request.setAllocationId(eipId);
       try {
           UnassociateEipAddressResponse response = client.getAcsResponse(request);
           logger.info(String.format("Unassociate eip %s to ecs %s, requestId:%s, ", eipId, ecsInstanceId, response.getRequestId()));
       } catch (ClientException e) {
           logger.info(String.format("Failure of unassociate eip %s to ecs %s, errorMsg:%s", eipId, ecsInstanceId, e.getLocalizedMessage()));
       }
   }

   private void addBackendServer(String regionId, String ecsInstanceId, FunctionComputeLogger logger) {
       DefaultProfile profile = DefaultProfile.getProfile(regionId, ak, aks);
       IAcsClient client = new DefaultAcsClient(profile);
       String lb = "lb-****";
       AddBackendServersRequest request = new AddBackendServersRequest();
       request.setBackendServers(String.format("[{\"ServerId\":\"%s\",\"Weight\":50}]",ecsInstanceId));
       request.setLoadBalancerId(lb);
       try {
           AddBackendServersResponse response = client.getAcsResponse(request);
           logger.info(String.format("add backend server %s to lb %s, requestId:%s, ", ecsInstanceId, lb, response.getRequestId()));
       } catch (ClientException e) {
           logger.info(String.format("failure of add backend server %s to lb %s, errorMsg:%s", ecsInstanceId, lb, e.getLocalizedMessage()));
       }
   }

   private void removeBackendServer(String regionId, String ecsInstanceId, FunctionComputeLogger logger) {
       DefaultProfile profile = DefaultProfile.getProfile(regionId, ak, aks);
       IAcsClient client = new DefaultAcsClient(profile);
       String lb = "lb-****";
       RemoveBackendServersRequest request = new RemoveBackendServersRequest();
       request.setBackendServers(String.format("[\"%s\"]",ecsInstanceId));
       request.setLoadBalancerId(lb);
       try {
           RemoveBackendServersResponse response = client.getAcsResponse(request);
           logger.info(String.format("remove backend server %s to lb %s, requestId:%s, ", ecsInstanceId, lb, response.getRequestId()));
       } catch (ClientException e) {
           logger.info(String.format("failure of remove backend server %s to lb %s, errorMsg:%s", ecsInstanceId, lb, e.getLocalizedMessage()));
       }
   }

   private void mountDisk(String regionId, String ecsInstanceId, String diskId, FunctionComputeLogger logger) {
       logger.info("prepare mount diskId:"+diskId);
       AttachDiskRequest request = new AttachDiskRequest();
       request.setDiskId(diskId);
       request.setInstanceId(ecsInstanceId);
       IClientProfile profile = DefaultProfile.getProfile(regionId, ak, aks);
       IAcsClient client = new DefaultAcsClient(profile);
       try {
           AttachDiskResponse response = client.getAcsResponse(request);
           logger.info("mount disk result:" + JSON.toJSONString(response));
       } catch (ClientException e) {
           logger.error("mount failure, diskId:" + diskId + e.getMessage());
       }

   }

   private void unmountDisk(String regionId, String ecsInstanceId, String diskId, FunctionComputeLogger logger) {
       logger.info("prepare mount diskId:"+diskId);
       DetachDiskRequest request = new DetachDiskRequest();
       request.setDiskId(diskId);
       request.setInstanceId(ecsInstanceId);
       IClientProfile profile = DefaultProfile.getProfile(regionId, ak, aks);
       IAcsClient client = new DefaultAcsClient(profile);
       try {
           DetachDiskResponse response = client.getAcsResponse(request);
           logger.info("unmount disk result:" + JSON.toJSONString(response));
       } catch (ClientException e) {
           logger.error("unmount failure, diskId:" + diskId);
       }
   }
}

欢迎扫描下方二维码,加入云监控用户支持群。
image

相关实践学习
基于云监控实现的监控系统
通过阿里云云监控功能给非阿里云主机安装监控插件,从而实现对非阿里云主机的各项指标进行监控和管理,在配置报警规则和报警人的情况下,能对特定的场景做出报警反应通知到报警人的手机上。
目录
相关文章
|
9天前
|
存储 弹性计算 运维
自动化监控和响应ECS系统事件
阿里云提供的ECS系统事件用于记录云资源信息,如实例启停、到期通知等。为实现自动化运维,如故障处理与动态调度,可使用云助手插件`ecs-tool-event`。该插件定时获取并转化ECS事件为日志存储,便于监控与响应,无需额外开发,适用于大规模集群管理。详情及示例可见链接文档。
|
2天前
|
存储 运维 监控
构建高效运维体系:从监控到自动化的全方位实践指南
在当今数字化时代,企业对运维(Operations)的需求日益增长。运维不仅仅是保持系统运行那么简单,它涉及到监控、日志管理、故障排除、性能优化和自动化等多个层面。本文将从实际操作的角度出发,详细探讨如何构建一个高效的运维体系。通过具体案例,我们将了解不同运维工具和方法的应用,以及它们是如何帮助企业提高生产效率和降低运营风险的。无论你是刚接触运维的新手,还是经验丰富的专家,这篇文章都将为你提供宝贵的参考和启示。
|
3天前
|
存储 运维 监控
构建高效运维体系:从监控到自动化的全方位实践
在当今信息技术飞速发展的时代,运维作为保障信息系统稳定运行的关键环节,其重要性不言而喻。本文将围绕如何构建一个高效的运维体系进行深入探讨,内容涵盖从监控、日志分析到自动化运维工具的选择与应用,以及在实际工作中的经验和案例分享。通过本文的介绍,读者将能够了解到如何在复杂多变的技术环境中,确保系统的高可用性、高性能和安全性,为业务连续性提供坚实保障。
|
17天前
|
数据采集 运维 监控
自动化运维:用Python打造简易监控系统
【8月更文挑战第31天】在追求高效的IT世界里,自动化运维不再是奢侈品而是必需品。本文将通过一个Python示例,展示如何构建一个简单的系统监控工具。从数据采集到警报触发,我们将一步步解锁自动化的秘密,让你的服务器管理变得轻松而高效。
|
17天前
|
运维 监控 jenkins
打造高效运维:自动化部署与监控实践
【8月更文挑战第31天】 在数字化浪潮中,运维工作如同航船的舵手,决定着企业信息系统的稳定性和效率。本文将通过浅显易懂的语言,带你了解如何利用自动化工具简化日常运维任务,提升工作效率,并确保系统健康运行。从代码示例到操作流程,我们将一步步构建起你的自动化运维体系。
|
17天前
|
监控 jenkins 测试技术
自动化测试中的“守护神”: 持续集成与代码质量监控
【8月更文挑战第31天】在软件开发的海洋里,自动化测试犹如一座灯塔,指引着项目向着高质量和高效率的方向前进。本文将深入探讨如何通过持续集成(CI)和代码质量监控相结合的方式,构建起一道坚固的防线,保障软件项目在快速迭代中不失方向。我们将一起探索这一过程中的关键实践,以及它们是如何相互作用,共同提升软件项目的可靠性和稳定性。
|
1月前
|
运维 监控 大数据
深入探讨网络自动化的魅力所在,以及如何利用Python这一强大工具,实现网络设备的批量配置与监控
在信息洪流的浪潮中,网络自动化如同一盏明灯,引领着我们穿越复杂网络管理的迷雾。它不仅简化了网络运维人员的工作,更是在大数据、云计算等技术飞速发展的背景下,成为了构建高效、稳定网络环境的关键。本文将深入探讨网络自动化的魅力所在,以及如何利用Python这一强大工具,实现网络设备的批量配置与监控,以此展现网络自动化在简化复杂网络管理中的重要作用。
40 0
|
1月前
|
XML JSON 监控
淘宝商品数据接口实战:自动化监控与竞品分析
淘宝开放平台提供的商品列表数据接口是一种API,使开发者能编程获取淘宝商品数据。主要功能包括按关键词、分类等获取商品列表及其详情,并支持分页、排序及多维度筛选。常见参数有关键词、页码、排序方式等。使用需注册账号获取API密钥,构建并发送HTTP请求,解析JSON/XML响应数据进行业务处理。此接口适用于商品监控、市场分析等多种场景。[体验API](http://u6v.cn/5W41Dx)
|
2月前
|
监控 网络安全 数据库
员工上网行为监控中的VBA自动化任务
使用VBA进行员工上网行为监控,包括记录网页访问(如`监控网页访问`子程序,抓取`A1`单元格的链接),截取屏幕(`截取屏幕并保存`子程序,保存为JPEG),以及自动将数据提交到网站(`数据提交到网站`子程序,构建HTTP请求)。这些自动化任务有助于提升网络安全和工作效率。
59 3
|
11天前
|
运维 Ubuntu Devops
自动化运维工具的魅力:Ansible入门
【9月更文挑战第5天】在快速变化的IT世界里,自动化运维不再是可选项,而是必需品。Ansible,一款简单却强大的自动化工具,正成为众多DevOps工程师的首选。本文将带你了解Ansible的基本概念、安装步骤以及如何编写简单的Playbook,从而开启你的自动化之旅。
58 35

热门文章

最新文章