基于Serverless云函数站点监控的方法

背景

      现代化企业与互联网软件IT运维监控领域,传统的方法是手动编写监控脚本,手动编写监控代码。现代化系统基于B/S架构设计,网站运维过程需要基于HTTP端点进行应用层监控。传统运维监控需要搭建运维监控软件平台,有的使用Zabbix,有的使用其他厂商运维监控工具,这种方法效率低下,还需要自己部署服务器与操作系统,数据库等基础设施,消耗时间成本较大。

解决方案

     核心技术是 云函数(Serverless Cloud Function,SCF)是云为企业和开发者们提供的无服务器执行环境,帮助您在无需购买和管理服务器的情况下运行代码。您只需使用平台支持的语言编写核心代码并设置代码运行的条件,即可在云基础设施上弹性、安全地运行代码。云函数可以执行任何类型的计算任务,从服务网页和处理数据流到调用API和与其他云服务集成。

Serverless 计算的概念是指不需要维护自己的服务器来运行这些功能。云函数 SCF 是一个可完全托管的服务,为你处理所有的基础设施。因此,serverless 并不意味着不涉及任何服务器:它只是意味着服务器、操作系统、网络层和其他基础设施已经被处理好了,所以您可以专注于编写应用代码。

  • 按量付费。在云 SCF 中,只需为功能所使用的计算量,以及产生的相关网络流量付费。对于那些在一天中的不同时间段进行大幅伸缩扩展的请求负载来说,这种类型的计费方式可以更好的节省成本。
  • 完全托管的基础设施。现在,代码运行在受管理的云基础设施上,不需要考虑底层服务器的问题──云为您解决了这些问题。这可以大大节省维护工作,如升级操作系统或管理网络层设施。
  • 自动伸缩。云函数 SCF 在代码被请求时创建实例。无需预设扩展池,无需担心扩展级别,无需进行设置──同时,不管请求增加或减少,你的服务都可用。您只需为每个函数的运行时间付费。
  • 与其他云产品紧密集成。云函数 SCF 与 API 网关、云存储和云数据库等。
  • 服务集成,使您能够在 SCF 函数中构建功能完整的应用程序。

高弹性

根据请求的并发数量自动调度资源运行函数,实现透明、准确和实时的伸缩,应付业务峰值的访问。用户无需关心峰值和空闲时段的资源需要申请多少资源,系统根据请求的数量自动扩容/缩容。自动负载均衡将请求分发到函数运行实例。同时系统会根据流量负载的模式来智能预热实例,以缓解冷启动对业务的影响。

事件触发

通过事件触发机制,集成多种云服务,满足不同场景需求,获得高效的开发体验。与云日志服务、云监控服务对接,无需任何配置,即可查询函数日志和监控告警信息,快速排查故障。

高可用

函数运行实例出现异常,系统会启动新的实例处理后续的请求,故障函数实例占用资源将会回收使用。

按量计费

根据代码的调用次数和运行时长计费,代码未运行时不产生费用。

a. 解决基于HTTP接口快速运维监控,过程如下:

1、编写简单脚本片段代码

2、部署脚本到serverless无服务器环境

3、配置云函数

4、配置定时器

5、配置消息通知渠道


基于Serverless实现自动化监控的优点

1、无需部署运维监控软件与独立服务器资源,直接使用公有云
2、监控程序与应用系统是分离的
3、可灵活配置多渠道通知
4、支持以下多种语言,编写即可使用, 如
Node.js, Python

概要示例:

(1) 最原始的技术方案:

A、服务端编写监控HTTP接口:根据监控需求编写与设计HTTP协议的REST服务接口,如JAVA应用中在SpringBoot项目中Actuator模块提供了众多HTTP接口端点(Endpoint),来提供应用程序运行时的内部状态信息。;

B、部署服务器搭建监控软件:安装服务器操作系统如Liunx,进行相关防火墙配置,

操作系统配置,基础设施软件安装与部署。部署监控应用软件, 如Zabbix。

C、配置监控HTTP端口:为了确保系统应用运维监控流程,需要测试监控HTTP接口功能,编写脚本代码,然后在运维监控软件Zabbix配置HTTP端点的监控。创建新的Web场景,添加一个场景来监控Zabbix的Web界面。该场景将执行多个步骤。点击配置->主机->选择主机->单击Web监测->创建Web监测。场景第2步,定义场景的步骤,定义场景的步骤->点击步骤->点击添加按钮。

D、持续运维监控:基于运维监控软件配置定时监控目标网站的URL是否触达

(2)进一步的技术方案:替换步骤B:直接采用无服务器架构下云函数功能,省去部署服务器操作系统,部署运维监控软件过程。

A、服务端HTTP接口:根据业务逻辑编写与设计HTTP协议的REST服务;

B、基于无服务器云函数配置:为了便于运维监控,基于无服务器的云函数,我们可以快速配置监控脚本,实现接口监控。

C、配置监控HTTP端口:函数工作流(FunctionGraph)是一项基于事件驱动的函数托管计算服务。通过函数工作流,只需编写业务函数代码并设置运行的条件,无需配置和管理服务器等基础设施,函数以弹性、免运维、高可靠的方式运行

D、持续运维监控:基于运维监控软件配置定时监控目标网站的URL是否触达

(3)进一步的技术方案:如果步骤B是核心创新点,则针对步骤 C、自动生成接口测试代码进一步细化描述,

具体实施例1:基于无服务器架构,快速构建一个一键自动部署的无服务器告警推送解决方案,实现将华为云的资源告警信息推送到客户指定的通知平台(如企业微信)。

详细的子流程步骤如下:

该解决方案部署如下资源:

1. 监控HTTP端点,当网站监控HTTP接口状态变化触发告警规则设置的阈值时,您将收到告警通知。
2. 编写监控脚本代码片段,包含需要拨测目标网站HTTP端点。(可选)消息通知服务 SMN,用于接受来自云监控服务 CES的告警数据,并触发函数工作流 FunctionGraph进行告警推送。
3. 函数工作流 FunctionGraph,该方案利用函数工作流 FunctionGraph调用第三方接口推送告警信息,以消息通知服务 SMN主题作为触发器。

查看已创建函数的“调用次数”、“成功率”和“平均时延”指标的统计数据,并可点击“查看详情”进入函数详情页查询具体的函数类和实例类指标监控数据,比如“服务端错误”、“函数错误”、“触发器请求入队”、“触发器请求积压数”、“超时次数”、“平均CPU使用情况”等。

实践

基于企业微信群机器人webhook集成

     在终端某个群组添加机器人之后,创建者可以在机器人详情页看的该机器人特有的webhookurl。开发者可以按以下说明a向这个地址发起HTTP POST 请求,即可实现给该群组发送消息。下面举个简单的例子.

假设webhook是:https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa

特别特别要注意:一定要保护好机器人的webhook地址,避免泄漏!不要分享到github、博客等可被公开查阅的地方,否则坏人就可以用你的机器人来发垃圾消息了。

以下是用curl工具往群组推送文本消息的示例(注意要将url替换成你的机器人webhook地址,content必须是utf8编码):

1. curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=693axxx6-7aoc-4bc4-97a0-0ec2sifa5aaa' \

2. -H 'Content-Type: application/json' \

3. -d '

4. {

5. "msgtype": "text",

6. "text": {

7. "content": "hello world"

8. }

9. }'


函数工作流(FunctionGraph)是一项基于事件驱动的函数托管计算服务。通过函数工作流,只需编写业务函数代码并设置运行的条件,无需配置和管理服务器等基础设施,函数以弹性、免运维、高可靠的方式运行。此外,按函数实际执行资源计费,不执行不产生费用

https://www.huaweicloud.com/product/functiongraph.html


以下是基于拨测模板 ,修改编写的本地函数python脚本:

# -*- coding:utf-8 -*-

import time

import json

import requests

def handler (event, context):

    logger = context.getLogger()

# Replace the URL and latency threshold to be tested.

    url_latency_threshold_dict = {

'http://ip/xzspnet/commonOrgManage/getOrgs/children?id=530000001&isAcceptOrg=1&order=xzqm':300,

'http://ip/xzspnet/commonOrgManage/getOrgs/children?id=530000001&isAcceptOrg=1&order=xzqm':500

    }

    alarm_info = []

    headers = {

"Accept": 'application/json'

    }

for url,latency_threshold in url_latency_threshold_dict.items():

        start_time = time.time()

        resp = None

try:

            resp = requests.get(url, headers=headers,timeout=3)

except (

        requests.exceptions.Timeout, requests.exceptions.ConnectionError, requests.exceptions.ConnectTimeout) as e:

            logger.error("Access '" + url + "' failed,err=" + str(e))

            alarm_info.append("Access '" + url + "' timeout")

else:

            latency = (time.time() - start_time) * 1000

if resp.status_code >= 400:

                alarm_info.append("Access '" + url + "' failed,status code=" + str(resp.status_code))

elif latency > latency_threshold:

                alarm_info.append("Access '" + url + "' latency=" + str(format(latency, '.1f')))

if len(alarm_info) != 0:

        logger.info("Send msg=" + json.dumps(alarm_info))

        msg =    {

"msgtype": "text",

"text": {

"content": json.dumps(alarm_info)

        }

   }

        send_to_smn(msg, context)

return {

"statusCode": 200,

"isBase64Encoded": False,

"body": "",

"headers": {

"Content-Type": "application/json"

        }

    }

def send_to_smn(msg, context):

    endpoint = context.getUserData('smn_endpoint')

if not endpoint:

        context.getLogger().error("Environment variable 'smn_endpoint' must be configured")

return False

    topic_urn = context.getUserData('smn_topic_urn')

if not topic_urn:

        context.getLogger().error("Environment variable 'smn_topic_urn' must be configured")

return False

    project_id = context.getUserData('smn_project_id')

if not project_id:

        context.getLogger().error("Environment variable 'smn_project_id' must be configured")

return False

    url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=%s' % (topic_urn)

    headers = {

"x-auth-token": context.getToken(),

"content-type": 'application/json;charset=UTF-8'

    }

    resp = requests.post(url, json=msg, headers=headers)

if resp.status_code >= 400:

        context.getLogger().error("Send msg failed,status code=" + str(resp.status_code) + ",body=" + str(resp.content))

return False

return True

函数概述
  • 目的:监控URL的响应时间和状态码,并在超过阈值或状态码错误时记录告警信息,并尝试通过某个消息通知服务(SMN或类似)发送告警。
  • 输入:event(未在此代码中使用),context(用于获取日志记录器、用户数据等)。
  • 输出:一个字典,包含HTTP状态码、响应是否Base64编码、响应体、和响应头。
主要步骤
  1. 初始化:设置URL和对应的延迟阈值字典,初始化告警信息列表,设置HTTP请求头。

  2. 遍历URL:对字典中的每个URL进行遍历。

  3. 请求URL:

    • 记录开始时间。
    • 尝试发送GET请求到URL,设置超时时间为3秒。
    • 捕获并处理可能发生的超时、连接错误等异常。
  4. 检查响应:

    • 如果响应状态码大于等于400,记录告警信息。
    • 计算请求响应时间(毫秒),如果超出设定的阈值,记录告警信息。
  5. 发送告警:如果存在告警信息,通过send_to_smn函数尝试发送告警。

  6. 结束:返回标准HTTP响应格式的字典。


在企业微信群告警通知效果


函数监控数据


配置定时器

环境变量

目前通过 smn_topic_urn 参数配置企业微信群机器人Webhook-KEY


参考函数调用

https://support.huaweicloud.com/api-functiongraph/functiongraph_06_0125.html


结论

      通过这个方案极大节约资源成本,时间成本,效率高,可靠性高实现网站HTTP端口监控。该方案集成第三方平台,实现低成本、及时完成告警推送,进一步解锁“端·云一体化”的企业化运维场景。采用无服务器架构,无需运维底层计算资源,无需考虑服务可用性、可扩展性等技术问题。Serverless架构在运维层面有着得天独厚的优势,不仅仅因为其事件触发可以有针对性的获取、响应一些事件,也因为其轻量化、低运维的特性让很多运维开发者甚是喜爱。在实际生产中,如果可以将线上环境的变动以事件的形式触发函数,由函数进行系列的运维行为操作,那么Serverless将会在自动化运维的过程中发挥出更重要的作用和更大的价值,也会让传统服务的自动化运维变得更加简单,轻便。



今天先到这儿,希望对云原生,技术领导力, 企业管理,系统架构设计与评估,团队管理, 项目管理, 产品管理,信息安全,团队建设 有参考作用 , 您可能感兴趣的文章:
构建创业公司突击小团队
国际化环境下系统架构演化
微服务架构设计
视频直播平台的系统架构演化
微服务与Docker介绍
Docker与CI持续集成/CD
互联网电商购物车架构演变案例
互联网业务场景下消息队列架构
互联网高效研发团队管理演进之一
消息系统架构设计演进
互联网电商搜索架构演化之一
企业信息化与软件工程的迷思
企业项目化管理介绍
软件项目成功之要素
人际沟通风格介绍一
精益IT组织与分享式领导
学习型组织与企业
企业创新文化与等级观念
组织目标与个人目标
初创公司人才招聘与管理
人才公司环境与企业文化
企业文化、团队文化与知识共享
高效能的团队建设
项目管理沟通计划
构建高效的研发与自动化运维
某大型电商云平台实践
互联网数据库架构设计思路
IT基础架构规划方案一(网络系统规划)
餐饮行业解决方案之客户分析流程
餐饮行业解决方案之采购战略制定与实施流程
餐饮行业解决方案之业务设计流程
供应链需求调研CheckList
企业应用之性能实时度量系统演变

如有想了解更多软件设计与架构, 系统IT,企业信息化, 团队管理 资讯,请关注我的微信订阅号:

作者:Petter Liu
出处:http://www.cnblogs.com/wintersun/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 该文章也同时发布在我的独立博客中-Petter Liu Blog。

热门相关:呆萌配腹黑:欢喜小冤家   黄金渔场   以权谋妻   兵王无双   佣兵的战争