介绍如何使用Python SDK查看SLB实例的监控参数并配置告警。

前提条件

在华北3张家口地域已经有两台状态为运行中的ECS实例。
在开始运行示例脚本前,您还需确保已完成以下准备工作:
  1. 因为使用Python SDK创建SLB实例会产生实例费,所以确保您的阿里云账户金额不少于100元。
  2. 获取AccessKey。

    确保您已经有了用于身份验证的AccessKey ID和AccessKey Secret。如果尚未获取AK,参见查询获取获取AccessKey

  3. 下载阿里云负载均衡Python SDK场景示例的SLB Python Example库
  4. 进入setup.py所在的目录,执行如下命令,完成环境初始化配置。
    python setup.py install

背景信息

本示例将采用以下配置:
  • 在华北3张家口地域新建一个名为SLB1的按量付费实例,主可用区为cn-zhangjiakou-a,备可用区为cn-zhangjiakou-b。
  • 为新建SLB实例创建一个TCP监听,SLB实例前端使用的端口为80,后端服务器开放用来接收请求的端口为80,健康检查协议为TCP,将张家口地域的两台ECS实例添加到默认服务器组,用来分发流量,ECS实例的后端服务权重都为100。
  • 查询新建SLB实例QPS使用率。
  • 创建告警,当新建SLB实例QPS使用率平均值大于等于35时,发起告警。
  • 删除新建实例。

操作步骤

  1. 在下载的SDK目录中,打开$aliyun-openapi-python-sdk-examples\sdk_examples\examples\slb文件夹。
  2. 使用编辑器打开slb_monitor.py文件,您需要配置用户鉴权参数ACS_CLIENT,其他参数根据实际情况配置后,保存退出。
    说明 因为用户鉴权是每个SDK必须执行的操作,所以可以在常量文件中配置AcsClient参数的值,在场景代码中调用常量文件。
    # encoding=utf-8
    import sys
    import json
    import uuid
    
    # 调用AcsClient参数进行身份验证
    from aliyunsdkcore.client import AcsClient
    # 使用阿里云官方sdk的异常处理模块
    from aliyunsdkcore.acs_exception.exceptions import ServerException, ClientException
    # 异常处理逻辑
    from sdk_lib.exception import ExceptionHandler
    # 调用创建SLB实例API
    from aliyunsdkslb.request.v20140515 import CreateLoadBalancerRequest
    # 调用添加默认服务器组API
    from aliyunsdkslb.request.v20140515 import AddBackendServersRequest
    # 调用添加TCP监听API
    from aliyunsdkslb.request.v20140515 import CreateLoadBalancerTCPListenerRequest
    # 调用云监控的接口查看SLB的最新监控数据
    from aliyunsdkcms.request.v20190101 import DescribeMetricLastRequest
    # 调用云监控的接口为SLB实例创建报警规则
    from aliyunsdkcms.request.v20190101 import PutResourceMetricRuleRequest
    # 调用删除SLB实例API
    from aliyunsdkslb.request.v20140515 import DeleteLoadBalancerRequest
    # 命令行导入日志
    from sdk_lib.common_util import CommonUtil
    
    # 用户身份验证参数配置
    ACS_CLIENT = AcsClient(
        'your-access-key-id',  # your-access-key-id
        'your-access-key-secret',  # your-access-key-secret
        'cn-zhangjiakou',  # your-region-id
    )
    # 失败重试次数
    TRY_TIME = 3
    
    '''
    创建slb实例->创建tcp监听->创建后端服务器->
    查询slb实例端口当前并发连接数->创建告警规则
    '''
    
    
    def create_load_balancer(params):
        '''
        create_load_balancer:创建slb实例
        官网API参考链接:https://help.aliyun.com/document_detail/27577.html
        '''
        try:
            # 设置创建SLB实例的调用参数
            request = CreateLoadBalancerRequest.CreateLoadBalancerRequest()
            request.set_MasterZoneId(params["master_zone_id"])
            request.set_SlaveZoneId(params["slave_zone_id"])
            request.set_LoadBalancerName(params["load_balancer_name"])
            request.set_PayType(params["pay_balancer_type"])
            # 发送调用请求并接收返回数据
            response = ACS_CLIENT.do_action_with_exception(request)
            response_json = json.loads(response)
            # 返回结果
            return response_json
        except ServerException as e:
            ExceptionHandler.server_exception(e)
        except ClientException as e:
            ExceptionHandler.client_exception(e)
    
    
    def add_backend_servers(params):
        '''
        add_backend_servers:添加后端服务器
        官网API参考链接: https://help.aliyun.com/document_detail/27632.html
        '''
        counter = 0
        while counter < TRY_TIME:
            try:
                # 设置添加默认服务器组的调用参数
                request = AddBackendServersRequest.AddBackendServersRequest()
                # 负载均衡实例的ID
                request.set_LoadBalancerId(params["load_balancer_id"])
                # 要添加的后端服务器列表
                request.set_BackendServers(params["backend_servers"])
                # 发送调用请求并接收返回数据
                response = ACS_CLIENT.do_action_with_exception(request)
                response_json = json.loads(response)
                # 返回结果
                return response_json
            except ServerException as e:
                if ExceptionHandler.server_exception(e):
                    return e
            except ClientException as e:
                if ExceptionHandler.client_exception(e):
                    return e
            finally:
                counter += 1
    
    
    def create_tcp_listener(params):
        '''
        create_tcp_listener:创建tcp监听
        官网API参考链接: https://help.aliyun.com/document_detail/27594.html
        '''
        counter = 0
        while counter < TRY_TIME:
            try:
                # 设置创建TCP监听的调用参数
                request = CreateLoadBalancerTCPListenerRequest.CreateLoadBalancerTCPListenerRequest()
                # 负载均衡实例的ID
                request.set_LoadBalancerId(params["load_balancer_id"])
                # 负载均衡实例前端使用的端口
                request.set_ListenerPort(params["listener_port"])
                # 负载均衡实例后端使用的端口
                request.set_BackendServerPort(params["backend_server_port"])
                # 监听的健康检查协议
                request.set_HealthCheckType(params["listener_health_check"])
                # 设置监听的带宽峰值
                request.set_Bandwidth(params["listener_bandwidth"])
                # 发送调用请求并接收返回数据
                response = ACS_CLIENT.do_action_with_exception(request)
                response_json = json.loads(response)
                # 返回结果
                return response_json
            except ServerException as e:
                if ExceptionHandler.server_exception(e):
                    return e
            except ClientException as e:
                if ExceptionHandler.client_exception(e):
                    return e
            finally:
                counter += 1
    
    
    def describe_metric_last(params):
        '''
        describe_metric_last:查询指定监控对象的最新监控数据
        官网API参考链接: https://help.aliyun.com/document_detail/51939.html
        '''
        counter = 0
        while counter < TRY_TIME:
            try:
                request = DescribeMetricLastRequest.DescribeMetricLastRequest()
                # 名字空间,表明监控数据所属产品
                request.set_Namespace(params["project"])
                # 监控项名称
                request.set_MetricName(params["metric_name"])
                # 过滤项
                request.set_Dimensions(params['dimensions'])
                response = ACS_CLIENT.do_action_with_exception(request)
                response_json = json.loads(response)
                return response_json
            except ServerException as e:
                ExceptionHandler.server_exception(e)
            except ClientException as e:
                ExceptionHandler.client_exception(e)
            finally:
                counter += 1
    
    
    def put_resource_metric_rule(params):
        '''
        put_resource_metric_rule:创建报警规则,可以为某一个实例创建报警规则,也可以为多个实例同时创建报警规则
        官网API参考链接: https://help.aliyun.com/document_detail/114934.html
        '''
        counter = 0
        while counter < TRY_TIME:
            try:
                request = PutResourceMetricRuleRequest.PutResourceMetricRuleRequest()
                # 报警规则ID,调用者统一生成,保证唯一性,已经存在的ID则修改,不存在则创建
                request.set_RuleId(uuid.UUID)
                # 产品名称,参考各产品对应的project
                request.set_Namespace(params["name_space"])
                # 报警联系人组,多个联系组之间用英文逗号分隔
                request.set_ContactGroups(params["ContactGroups"])
                # 报警规则名称
                request.set_RuleName(params["name"])
                # 相应产品对应的监控项名称,参考各产品metric定义
                request.set_MetricName(params["metric_name"])
                # 报警规则对应实例列表
                request.set_Resources(params["dimensions"])
                # Critical级别报警统计方法
                request.set_EscalationsCriticalStatistics(params["statistics"])
                # Critical级别阈值比较符
                request.set_EscalationsCriticalComparisonOperator(params["comparison_operator"])
                # Critical级别报警阈值
                request.set_EscalationsCriticalThreshold(params["threshold"])
                # Critical级别报警重试次数
                request.set_EscalationsCriticalTimes(3)
                response = ACS_CLIENT.do_action_with_exception(request)
                response_json = json.loads(response)
                return response_json
            except ServerException as e:
                ExceptionHandler.server_exception(e)
            except ClientException as e:
                ExceptionHandler.client_exception(e)
            finally:
                counter += 1
    
    
    def delete_load_balancer(load_balancer_id):
        '''
        delete_load_balancer:删除slb实例
        官网API参考链接:https://help.aliyun.com/document_detail/27579.html
        '''
        try:
            # 设置删除SLB实例的调用参数
            request = DeleteLoadBalancerRequest.DeleteLoadBalancerRequest()
            # 负载均衡实例的ID
            request.set_LoadBalancerId(load_balancer_id)
            # 发送调用请求并接收返回数据
            response = ACS_CLIENT.do_action_with_exception(request)
            response_json = json.loads(response)
            # 返回结果
            return response_json
        except ServerException as e:
            ExceptionHandler.server_exception(e)
        except ClientException as e:
            ExceptionHandler.client_exception(e)
    
    
    def main():
        params = {}
        # 设置创建SLB实例的参数
        # 设置新建SLB实例的主可用区为cn-zhangjiakou-a
        params["master_zone_id"] = "cn-zhangjiakou-a"
        # 设置新建SLB实例的主可用区为cn-zhangjiakou-b
        params["slave_zone_id"] = "cn-zhangjiakou-b"
        # 设置新建SLB实例的名称为SLB1
        params["load_balancer_name"] = "SLB1"
        # 设置新建SLB实例的计费类型为按量计费
        params["pay_balancer_type"] = "PayOnDemand"
    
        # 设置添加到默认服务器组的ECS的实例ID和权重
        params["backend_servers"] = [{"ServerId": "i-8vbfus6jnwjp1c2*****", "Weight": "100"},
                                     {"ServerId": "i-8vbfus6jnwjp1c2*****", "Weight": "100"}]
    
        # 设置添加TCP监听的参数
        # 前端使用的端口为80
        params["listener_port"] = 80
        # 后端服务器开放用来接收请求的端口为80
        params["backend_server_port"] = 80
        # 健康检查协议为TCP
        params["listener_health_check"] = "tcp"
        # TCP监听的带宽峰值为-1,即不限制带宽峰值
        params["listener_bandwidth"] = -1
    
        # 设置查询监控项的参数
        # 设置监控数据所属产品
        params["project"] = "acs_slb_dashboard"
        # 设置监控项名称
        params["traffic_tx_new"] = "InstanceQpsUtilization"
    
        # 设置创建告警的参数
        # 设置告警规则所属产品
        params["name_space"] = "acs_slb_dashboard"
        # 设置告警规则名称
        params["name"] = "slb_alarm"
        # 设置告警中SLB对应的监控项名称
        params["metric_name"] = "InstanceQpsUtilization"
        # 设置统计方法
        params["statistics"] = "Average"
        # 设置报警比较符,大于等于
        params["comparison_operator"] = "GreaterThanOrEqualToThreshold"
        # 设置报警阈值
        params["threshold"] = 35
    
        # 创建slb实例
        # 获取create_load_balancer函数返回值,load_balancer_json为结果的json串
        load_balancer_json = create_load_balancer(params)
        # 打印 load_balancer_json结果,其中"create_load_balancer"是对json串起的名字
        CommonUtil.log("create_load_balancer", load_balancer_json)
    
        # slb实例id
        params["load_balancer_id"] = load_balancer_json["LoadBalancerId"]
    
        # 创建tcp监听
        result_json = create_tcp_listener(params)
        CommonUtil.log("create_tcp_listener", result_json)
    
        # 创建后端服务器
        result_json = add_backend_servers(params)
        CommonUtil.log("add_backend_servers", result_json)
    
        # 查询slb实例QPS使用率
        params["dimensions"] = '[{"instanceId":"' + load_balancer_json["LoadBalancerId"] + '"}]'
        result_json = describe_metric_last(params)
        CommonUtil.log("describe_metric_last", result_json)
    
        # 创建告警规则
        params["metric_name"] = "InstanceQpsUtilization"
        # 报警联系人组
        params["ContactGroups"] = "test_contact_groups"
        result_json = put_resource_metric_rule(params)
        CommonUtil.log("put_resource_metric_rule", result_json)
    
        # 删除slb实例
        # 删除返回的LoadBalancerId对应的SLB实例
        load_balancer_json = delete_load_balancer(load_balancer_json["LoadBalancerId"])
        # 打印 load_balancer_json结果
        CommonUtil.log("delete_load_balancer", load_balancer_json)
    
    
    if __name__ == "__main__":
        sys.exit(main())
  3. 进入slb_monitor.py所在的目录,执行如下命令,运行查看监控示例。
    python slb_monitor.py
    系统显示类似如下:
    ---------------------------create_load_balancer---------------------------
    {
      "VpcId": "",
      "AddressIPVersion": "ipv4",
      "LoadBalancerName": "SLB1",
      "ResourceGroupId": "rg-axxxxxxxxxx",
      "VSwitchId": "",
      "RequestId": "661DDF49-FD2B-46C1-8E38-FDE5E62C8448",
      "Address": "39.xx.xx.xx4",
      "NetworkType": "classic",
      "LoadBalancerId": "lb-8vbtxxxxxxxxxxx1hn"
    }
    
    ---------------------------create_tcp_listener---------------------------
    {
      "RequestId": "7ED453FF-7DF6-4F4F-81A0-670EED9EB997"
    }
    
    ---------------------------add_backend_servers---------------------------
    {
      "RequestId": "4B730606-BD44-4A6B-BE9E-118E9606B064",
      "BackendServers": {
        "BackendServer": [
          {
            "ServerId": "i-8xxxxxxxxxxf4z",
            "Type": "ecs",
            "Weight": 100
          },
          {
            "ServerId": "i-8xxxxxxxxxxxxx",
            "Type": "ecs",
            "Weight": 100
          }
        ]
      },
      "LoadBalancerId": "lb-8xxxxxxxxxxxxxx"
    }
    
    ---------------------------describe_metric_last---------------------------
    {
      "Code": "200",
      "Period": "60",
      "RequestId": "15FD2461-FD94-451F-ABE3-D281DB453161",
      "Datapoints": "[]"
    }
    
    ---------------------------put_resource_metric_rule---------------------------
    {
      "Code": "200",
      "Data": "53547DF14168E368073BE8E34E1522DE25854224",
      "RequestId": "8652E53F-74AD-413B-B2D9-103BFE557FAC",
      "Success": true
    }
    
    ---------------------------delete_load_balancer---------------------------
    {
      "RequestId": "D6CCD259-41C2-4D5C-A644-19A0E96F1D4C"
    }