# 资源与应用服务层监控
[Amazon CloudWatch](https://aws.amazon.com/cn/cloudwatch/?trk=cndc-detail) 监控和预警平台可以帮助客户统一管理和运维亚马逊云科技云端和本地资源、服务和业务系统;使用 [Amazon CloudWatch](https://aws.amazon.com/cn/cloudwatch/?trk=cndc-detail) 可以收集和跟踪指标,收集和监控日志文件,设置警报。您可通过使用 [Amazon CloudWatch](https://aws.amazon.com/cn/cloudwatch/?trk=cndc-detail) 全面地了解资源使用率、应用程序性能和运行状况。使用这些分析结果,您可以及时做出反应,保证应用程序顺畅运行。
# Amazon CloudWatch 的基本概念
请参考[亚马逊云科技官方文档](https://docs.aws.amazon.com/zh_cn/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html?trk=cndc-detail)了解 [Amazon CloudWatch](https://aws.amazon.com/cn/cloudwatch/?trk=cndc-detail) 的核心概念和术语,比如指标、命名空间、维度、时间戳、单位、统计数据、时间段、聚合、警报等。
# 基于 CloudWatch 的监控预警平台架构
![1.png](https://dev-media.amazoncloud.cn/7d5b5bd1db564fefae7ef07e692f3268_1.png "1.png")
CloudWatch 提供了一套标准的 API 接口,用户可以利用该平台发布自定义应用、业务或者更加详细的系统指标。用户发布到 [Amazon CloudWatch](https://aws.amazon.com/cn/cloudwatch/?trk=cndc-detail) 的指标是按时间排序的数据点集合,数据点本身可以来自于任何应用程序或者业务活动;指标通过名称、命名空间和维度进行唯一定义;维度可以帮助你设计数据点的分组特征或者类别,发布指标数据点时必须必须指定维度,比如虚机的 CPU 使用率,用户可以查看单独某个虚机的监控指标也可以按 AutoScaling 组来查看,这里的单个虚机或者 AutoScaling 组就是同一数据点的不同的维度。用户可以使用秒级甚至千分之一秒的频率发布自定义指标,但是 [Amazon CloudWatch](https://aws.amazon.com/cn/cloudwatch/?trk=cndc-detail) 还是会将数据聚合到 1 分钟为最小粒度。
基于指标数据,用户可以翻译业务的波动异常到相应的指标,从而创建警报来和相应的操作来自动化应对各种异常情况,操作包括弹性伸缩(Auto Scaling)机制来应对访问流量变化或者 [Amazon SNS](https://aws.amazon.com/cn/sns/?trk=cndc-detail) 主题订阅绑定的邮件通知、HTTP 请求的调用和消息队列异步处理。
指标数据用户可以直接通过亚马逊云科技控制台进行的图形化按时间筛选、查看和分享;同时,用户也可以通过 API 接口获取指标数据进行第三方的处理和展示。CloudWatch 默认保存两周的指标数据(海外区域部分可以支持免费存储最多 15 个月的统计数据,[详情请查看 Amazon CloudWatch 文档](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_GetMetricStatistics.html?trk=cndc-detail))。
本文的架构中,自定义指标收集不需要自己编程而是利用 collectd 守护进程进行监控和获取,同时利用 CloudWatch Plugin for collectd 直接将自定义指标发布和存储到 CloudWatch 中,用户随后可以基于自定义指标的进行自动化警报处理从而实现无人值守的统一监控平台。
# 什么是 CloudWatch Plugin for collectd
CloudWatch 一直支持用户发布自定义指标来存储、监控自己关心的业务、应用和系统健康状况;亚马逊云科技最新发布了 CloudWatch Plugin for collectd 开源项目,该插件整合了 collectd 强大的收集各种类型统计数据的能力,帮助客户简化了开发收集自定义指标的相关工作,开箱即用地支持发布 Apache、Nginx Web 服务器应用指标,内存监控指标等监控数据到 CloudWatch 进行统一存储、展示和预警。
## 什么是 collectd?
collectd 是一个基于 C 语言的守护进程,主要任务就是用来收集统计信息,它提供各种了存储方式来存储不同值的机制。它支持超过 100 种各类插件,下面大概列出一些比较常见的插件类型,具体的请参考[collectd官方网站](https://collectd.org/?trk=cndc-detail)。
- Web 应用:Apache、nginx
- 数据库:MySQL、Oracle、PostgreSQL、memcached
- 网络:OpenVPN、Ping、TCPConns、
- 系统:Memory、Disk、FileCount、vmem、uptime、df
# 安装配置 CloudWatch Plugin for collectd
下面的步骤以 BJS 区域的 EC2 为例来说明如何安装配置和使用 CloudWatch Plugin for collectd:
#### 用户授权
该插件支持 IAM Role 或者 IAM User 两种方式的授权,按照亚马逊云科技最佳实践,我们推荐使用 IAM Role 的方式进行授权。所以,开始之前,我们先创建一个 IAM Role 并赋予相应的权限。
创一个角色名字为 role4collectd。
![2.png](https://dev-media.amazoncloud.cn/c86e373199be4fcb8921fcf41ac5ce0c_2.png "2.png")
然后在该角色的权限页面,创建角色策略,赋予该角色拥有发布指标的权限。
![3.png](https://dev-media.amazoncloud.cn/4aab20f3be1344279c23df97767a528a_3.png "3.png")
#### 启动实例并绑定角色
如果你想在已经启动的 EC2 或者你自己的机器上启用该插件,可以忽略该步骤并创建一个具备 CloudWatch 发布指标权限的 IAM User。
本文启动一个新的 EC2 实例并绑定上一步创建好的角色:
![4.png](https://dev-media.amazoncloud.cn/26fa8422c23d45a398b0ae7dc3521318_4.png "4.png")
#### 安装插件
登陆到 EC2 并更新系统。
> [ec2-user@ip-10-0-0-6 ~]$ sudo yum -y install collectd
>
> 已加载插件:priorities, update-motd, upgrade-helper
>
> 正在解决依赖关系
>
> --> 正在检查事务
>
> ---> 软件包 collectd.x86_64.0.5.4.1-1.11.amzn1 将被 安装
>
> --> 解决依赖关系完成
下载 CloudWatch Plugin for collectd 安装文件并执行,安装脚本会自动读取 EC2 的 Meta Data,因此选项都可以默认选择,比如区域,EC2 绑定的 IAM Role 等等。
> [ec2-user@ip-10-0-0-6 ~]$ sudo -s
>
> [root@ip-10-0-0-6 ec2-user]# wget https://raw.githubusercontent.com/awslabs/collectd-cloudwatch/master/src/setup.py
>
> [root@ip-10-0-0-6 ec2-user]# chmod +x setup.py
>
> [root@ip-10-0-0-6 ec2-user]# ./setup.py
>
> [root@ip-10-0-0-6 ec2-user]# ./setup.py
>
> Installing dependencies ... OK
>
> Installing python dependencies ... OK
>
> Downloading plugin ... OK
>
> Extracting plugin ... OK
>
> Moving to collectd plugins directory ... OK
>
> Copying CloudWatch plugin include file ... OK
>
> Choose Amazon region for published metrics:
>
> 1. Automatic [cn-north-1]
>
> 2. Custom
>
> Enter choice [1]:
>
> Choose hostname for published metrics:
>
> 1. EC2 instance id [i-cc97bc74]
>
> 2. Custom
>
> Enter choice [1]:
>
> Choose authentication method:
>
> 1. IAM Role [role4collectd]
>
> 2. IAM User
>
> Enter choice [1]:
>
> Choose how to install CloudWatch plugin in collectd:
>
> 1. Do not modify existing collectd configuration
>
> 2. Add plugin to the existing configuration
>
> Enter choice [2]:
>
> Plugin configuration written successfully.
>
> Stopping collectd process ... NOT OK
>
> Starting collectd process ... OK
collectd 和 CloudWatch plugin for collectd 到此就已经安装完成了。
#### 定义发布到 CloudWatch 的指标
要在 CloudWatch 中存储和查看 collectd 收集的指标数据,需要完成两件事情(1)安装相应的 collectd 插件(2)在 CloudWatch plugin 配置文件中添加指标白名单。
查看 CloudWatch plugin 的指标白名单,版本 collectd 5.5 以下默认 CloudWatch 白名单指标是空的,也就是默认不会发布任何 collectd 的指标到 CloudWatch:
> [ec2-user@ip-10-0-0-6 ~]$ sudo cat /opt/collectd-plugins/cloudwatch/config/whitelist.conf
对于可用的 collectd 的指标数据类型,我们可以查看以下文件来确认,该文件包含没有发布到 CloudWatch 的指标类型,该文件是系统自动维护,不要人为进行修改:
blocked_metrics plugin.conf whitelist.conf
> [ec2-user@ip-10-0-0-6 ~]$ sudo cat /opt/collectd-plugins/cloudwatch/config/blocked_metrics
> #This file is automatically generated - do not modify this file.
>
> #Use this file to find metrics to be added to the whitelist file instead.
>
> cpu-0-cpu-user
>
> cpu-0-cpu-nice
>
> cpu-0-cpu-system
>
> cpu-0-cpu-idle
>
> cpu-0-cpu-wait
>
> cpu-0-cpu-interrupt
>
> cpu-0-cpu-softirq
>
> cpu-0-cpu-steal
>
> interface-lo-if_octets-
>
> interface-lo-if_packets-
>
> interface-lo-if_errors-
>
> interface-eth0-if_octets-
>
> interface-eth0-if_packets-
>
> interface-eth0-if_errors-
>
> load--load-
>
> memory--memory-used
>
> memory--memory-buffered
>
> memory--memory-cached
>
> memory--memory-free
假定我们对于内存相关指标比较感兴趣,可以将 memory 开头的指标类型添加到 CloudWatch 白名单:
> [ec2-user@ip-10-0-0-6 ~]$ sudo vim /opt/collectd-plugins/cloudwatch/config/whitelist.conf
输入如下信息:
> memory--memory-.*
重启 collectd 服务:
![5.png](https://dev-media.amazoncloud.cn/4b1758f636994f8d9b92cdf0633e6862_5.png "5.png")
注:在 BJS 区域的 EC2 上默认安装和配置后,我们从日志会发现报错,主要原因是默认安装后的脚本不支持 BJS 区域,详细的错误识别请参考以下步骤。
打开 debug 模式:
![6.png](https://dev-media.amazoncloud.cn/71de0be9d1494243aedfe33ee5d44829_6.png "6.png")
![7.png](https://dev-media.amazoncloud.cn/a9f3469ec32241e3ae9e90be510e5244_7.png "7.png")
重启 collectd 服务:
![8.png](https://dev-media.amazoncloud.cn/7413cb592fe04d6bad0b119a0f1c5447_8.png "8.png")
查看日志:
![9.png](https://dev-media.amazoncloud.cn/e5e23e9aaf8441a68240035ed1c45939_9.png "9.png")
从下面的错误信息可以看到,脚本默认发布指标到如下的 endpoint:https://monitoring.cn-north-1.amazonaws.com/, 但 BJS 区域的 CloudWatch endpoint 和海外区域的命名规则有差异,详细的 Amazon BJS 区域服务的终端节点可以参考:[中国(北京)区域](https://docs.amazonaws.cn/aws/latest/userguide/endpoints-arns.html#cnnorth_region?trk=cndc-detail);
为了解决 BJS 区域终端节点的支持问题,我们需要更新插件的 Python 脚本文件使其支持 BJS 区域:
1.[confighelper.py文件](https://github.com/awslabs/collectd-cloudwatch/blob/master/src/cloudwatch/modules/configuration/confighelper.py?trk=cndc-detail):该文件默认安装后的目录是 /opt/collectd-plugins/cloudwatch/modules/configuration
![10.png](https://dev-media.amazoncloud.cn/7e08e5c9a9024efab9ce96641c925480_10.png "10.png")
更新如下函数:
![11.png](https://dev-media.amazoncloud.cn/f936a24d02d34a5eaa0f39c147fff4ee_11.png "11.png")
参考修改后的代码如下:
![12.png](https://dev-media.amazoncloud.cn/5789cae27e544d2c9d9dcd341262dfbe_12.png "12.png")
1. [requestbuilder.py 文件](https://github.com/awslabs/collectd-cloudwatch/blob/master/src/cloudwatch/modules/client/requestbuilder.py?trk=cndc-detail):该文件默认安装后的目录为/opt/collectd-plugins/cloudwatch/modules/client
该类的主要功能是构建签名版本 4 的 PutMetricData API 请求,因此会使用到 endpoint 信息,具体请参考[在线文档](https://docs.aws.amazon.com/zh_cn/general/latest/gr/create-signed-request.html#create-canonical-request?trk=cndc-detail):
![13.png](https://dev-media.amazoncloud.cn/cf684428993241908aa5bd80e03530c4_13.png "13.png")
更新如下函数:
![14.png](https://dev-media.amazoncloud.cn/691811ab65164d389f25923858ce94b9_14.png "14.png")
参考修改后的代码如下:
![15.png](https://dev-media.amazoncloud.cn/c46f0e86c1ce4284b53f8d934c04c29e_15.png "15.png")
重启 collectd 服务:
![16.png](https://dev-media.amazoncloud.cn/6d387a95de76470c9ee963e203dcfaad_16.png "16.png")
查看以 [AmazonCloudWatchPlugin] 开头的日志内容,从日志可以看出,我们添加到白名单的 memory 相关的日志包含四个不同的指标,每分钟发布一次:
![17.png](https://dev-media.amazoncloud.cn/fc50a7d10cd540c5ae3fa6573be8e01b_17.png "17.png")
![18.png](https://dev-media.amazoncloud.cn/b9e48cd6a4fc47fba578a6db15fff26d_18.png "18.png")
登录亚马逊云科技控制台,打开到 CloudWatch 页面,左侧导航最底端有个自定义指标的选择框,下拉就可以选择 collectd 来查看刚刚发布的指标内容:
![19.png](https://dev-media.amazoncloud.cn/333e7b00b79e4ab7b37f191cc98277ac_19.png "19.png")
#### 安装启用收集 Apache 监控数据插件
如果未安装配置好 Apache Web 服务器,可以参考 [教程:在 Amazon Linux 上安装 LAMP Web 服务器](https://docs.aws.amazon.com/zh_cn/AWSEC2/latest/UserGuide/install-LAMP.html?trk=cndc-detail) 来搭建好该 Web 服务器环境。
通过以下命令可以查询 Amazon Linux AMI 带有的 collectd 的插件列表:
![20.png](https://dev-media.amazoncloud.cn/0b2d6d7e99434f4182258e16cfa583c7_20.png "20.png")
apache 的状态信息来自于自身的 mod_status 模块,collectd 解析出例如传输的 bytes 大小,接受到的请求数量等指标;详情请参考该[插件介绍页面](https://collectd.org/wiki/index.php/Plugin:Apache?trk=cndc-detail);安装 collectd apache 监控插件:
![21.png](https://dev-media.amazoncloud.cn/440bb665ec0742d9ac167cd859c139ff_21.png "21.png")
修改 collectd 的配置,默认安装的文件位置 /etc/collectd.conf:
![1678862167529.jpg](https://dev-media.amazoncloud.cn/0112a6c58d434c6089a57d87554475ec_1678862167529.jpg "1678862167529.jpg")
以下是针对 httpd-2.2 版本的参考配置,默认的配置文件位于/etc/httpd/conf/httpd.conf:
![22.png](https://dev-media.amazoncloud.cn/7cab3d88220a407c96d08e87546a1927_22.png "22.png")
将 apache 相关状态指标加入到 CloudWatch collectd 插件配置的白名单列表,更新文件 /opt/collectd-plugins/cloudwatch/config/whitelist.conf :
![23.png](https://dev-media.amazoncloud.cn/af85a2fb86f045cc9ea7647206a5f1ce_23.png "23.png")
重新启动相关服务:
![24.png](https://dev-media.amazoncloud.cn/29e311ae92d74406a03d7fe38fb4766a_24.png "24.png")
这样我们就完成了安装配置新的 collectd 的 apache 插件,同时将 apache 的相关监控指标添加到 CloudWatch 的白名单,这样我们就可以无缝整合 collectd 的收集数据能力和 CloudWatch 统一存储、展示和预警能力,下图就是 apache web 应用相关的指标在 CloudWatch 中展示的结果:
![25.png](https://dev-media.amazoncloud.cn/f72be57aa2bf4acf9f291a7b8ee37fbf_25.png "25.png")
#### 基于 CloudWatch 指标创建警报
既然我们通过插件收集了很多系统和应用的指标,那如果发生一些异常或者超过预先定义的阈值的时候,我们如何去应对和处理呢?理想情况我们能够尽可能自动化来应对这些警报,即搭建“无人”值守的监控预警平台。下图是基于某一个采集指标定义警报及处理警报的操作的截图。当一个警报发生时,你可以定义一个或多个操作来应对和处理。你可以采取的操作类型有,发送邮件通知,发布消息到 SNS 服务,添加 Auto Scaling 操作,以及 EC2 实际操作。这里的 EC2 实例操作包含停止、终止、重启或恢复,任何 EC2 实例指标(在 Amazon/EC2 命名空间中)或者包含“InstanceId=”维度的任何自定义指标都可以在警报中触发 EC2 实例操作。
![26.png](https://dev-media.amazoncloud.cn/9c03c0c2b45d4f6b86b8482852f5d547_26.png "26.png")
#### 一些限制
很多用户在开始接触 CloudWatch 的时候就非常关心性能问题,目前发布指标 API [PutMetricData](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_PutMetricData.html?trk=cndc-detail) 每秒可处理 150 个事务 (TPS),这是您每秒可以发出而不会受到限制的操作请求的最大数量,但可以在线请求提高限制;[PutMetricData](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_PutMetricData.html?trk=cndc-detail) 同时支持 GET 和 POST 操作,请求最大大小分别为 8KB 和 40KB。每个指标最多可以有 10 个维度。
# 总结
本文和大家一起学习了如何基于 CloudWatch 及 collectd 相关插件构建无人值守的监控预警平台。CloudWatch 默认提供了亚马逊云科技资源的基本监控数据,同时提供了 CLI 和 REST API 的方式供用户自行扩展自定义业务和系统指标数据; [CloudWatch plugin for collectd](https://github.com/awslabs/collectd-cloudwatch?trk=cndc-detail) 是亚马逊云科技最新发布的一个开源插件,大家可以进一步通过学习该项目的源代码掌握如何基于 Python 扩展和集成亚马逊云科技的服务。
文章审核:tsaoyang