• 探索Windows Azure 监控和自动伸缩系列2


    上一篇博文介绍了如何连接Windows Azure: http://www.cnblogs.com/teld/p/5113063.html

    本篇我们继续上次的示例代码,获取虚拟机的监控定义和监控数据。

    有人会问,Azure Portal上已经有了监控数据,通过代码获取有意思吗?我们计划基于性能计数器的监控数据来实现应用的自动伸缩,因此可以获取到监控指标定义和监控数据应该是第一步。

    在Azure的管理Portal中我们可以看到虚拟机的监控数据,目前,提供的主要有以下监控指标:

    CPU Percentage;Disk Read; Disk Write; Network in;NetWork Out。

    Azure中监控的Nuget主要是这个:Microsoft Azure Management Libraries

    核心的几个namespace有:

    我们本篇用的是Metric这个命名空间,核心类MetricClient:

     1 namespace AzureTest
     2 {
     3     using Microsoft.WindowsAzure;
     4     using Microsoft.WindowsAzure.Management.Monitoring.Metrics;
     5     using Microsoft.WindowsAzure.Management.Monitoring.Metrics.Models;
     6     using Microsoft.WindowsAzure.Management.Monitoring.Utilities;
     7 
     8     /// <summary>
     9     /// 监控客户端
    10     /// </summary>
    11     class MonitorClient
    12     {
    13         private SubscriptionCloudCredentials credentials;
    14 
    15         public MonitorClient(SubscriptionCloudCredentials credentials)
    16         {
    17             this.credentials = credentials;
    18         }
    19 
    20         /// <summary>
    21         /// 获取所有的监控指标
    22         /// </summary>
    23         public void GetMetricDefinitions()
    24         {
    25             var metricsClient = new MetricsClient(credentials);
    26             // Build the resource ID string.
    27             var resourceId = ResourceIdBuilder.BuildVirtualMachineResourceId("cloudServiceName", "deploymentName");
    28             Console.WriteLine("Resource Id: {0}", resourceId);
    29 
    30             //Get the metric definitions.
    31             var metricListResponse=
    32                 metricsClient.MetricDefinitions.List(resourceId, null, null);34 
    35             MetricDefinitionCollection metricDefinitions = metricListResponse.MetricDefinitionCollection;           
    36             // Display the metric definitions.
    37             int count = 0;
    38             foreach (MetricDefinition metricDefinition in metricDefinitions.Value)
    39             {
    40                 Console.WriteLine("MetricDefinitio: " + count++);
    41                 Console.WriteLine("Display Name: " + metricDefinition.DisplayName);
    42                 Console.WriteLine("Metric Name: " + metricDefinition.Name);                
    43                 Console.WriteLine("Metric Namespace: " + metricDefinition.Namespace);                
    44                 Console.WriteLine("Is Altertable: " + metricDefinition.IsAlertable);
    45                 Console.WriteLine("Min. Altertable Time Window: " + metricDefinition.MinimumAlertableTimeWindow);
    46                 Console.WriteLine();
    47             }
    48         }
    49 }
    50 }


    使用上一篇我们的Azure 凭据验证器,获取一个令牌凭据TokenCloudCredentials,然后构造一个MonitorClient,获取指定虚拟机的监控数据。

    static void Main(string[] args)
    {            
          var credential = Authorizator.GetCredentials();
          var client = new MonitorClient(credential);
          client.GetMetricDefinitions();
          Console.ReadLine();
    }


    第一块代码中:

    var resourceId = ResourceIdBuilder.BuildVirtualMachineResourceId("cloudServiceName", "deploymentName");

    这个地方通ResourceIDBuilder获取虚拟机的资源ID,对应的参数分别为:cloudServiceName和deploymentName,第一个是虚拟机使用的云服务名称,第二个是虚拟机名称即可。

    Run...

    出错了:

    {"ForbiddenError: The server failed to authenticate the request. Verify that the certificate is valid and is associated with this subscription."}

    一番Google后未果,咋整,再分析下错误信息:

    可以看到,请求的Uri:

    {https://management.core.windows.net/37*****-5107-*****-*******6/services/monitoring/metricdefinitions/query?&resourceId=%2Fhostedservices%2Fteldptapp%2Fdeployments%2Fteldptapp}

    请求又跑到Azure Global那去了。

    这个错误困扰了好久,还在StackOverflow上发了英文咨询贴,不知道洋人们如何回答了。在此多谢鞠强老大的指导,想办法将请求的Uri定位到中国区的Azure。

    重新分析了代码,找到了Monitor的构造函数中,可以指定Uri,将中国区Azure的Uri指定一下:https://management.core.chinacloudapi.cn

    MetricsClient metricsClient = new MetricsClient(credentials, new Uri("https://management.core.chinacloudapi.cn/"));

    测试通过,ok。

    获取到了监控指标定义,接下来我们获取监控数据:

    namespace AzureTest
    {
        using Microsoft.WindowsAzure;
        using Microsoft.WindowsAzure.Management.Monitoring.Metrics;
        using Microsoft.WindowsAzure.Management.Monitoring.Metrics.Models;
        using Microsoft.WindowsAzure.Management.Monitoring.Utilities;
        /// <summary>
        /// 监控客户端
        /// </summary>
        class MonitorClient
        {
            private SubscriptionCloudCredentials credentials;
    
            public MonitorClient(SubscriptionCloudCredentials credentials)
            {
                this.credentials = credentials;
            }
    
            /// <summary>
            /// 获取所有的监控指标数据
            /// </summary>
            public void GetMetricData()
            {
                var metricsClient = new MetricsClient(credentials, new Uri("https://management.core.chinacloudapi.cn/"));
                
                // Build the resource ID string.
                var resourceId = ResourceIdBuilder.BuildVirtualMachineResourceId("cloudServiceName", "deploymentName");
                Console.WriteLine("Resource Id: {0}", resourceId);
    
                //Get the metric definitions.
                var metricListResponse = metricsClient.MetricDefinitions.List(resourceId, null, null);
                MetricDefinitionCollection metricDefinitions = metricListResponse.MetricDefinitionCollection;
                
                var metricNamespace = "";
                var metricNames = new List<string>();
                // Display the metric definitions.
                int count = 0;
                foreach (MetricDefinition metricDefinition in metricDefinitions.Value)
                {
                    Console.WriteLine("MetricDefinitio: " + count++);
                    Console.WriteLine("Display Name: " + metricDefinition.DisplayName);
                    Console.WriteLine("Metric Name: " + metricDefinition.Name);
                    if (!metricNames.Contains(metricDefinition.Name))
                        metricNames.Add(metricDefinition.Name);
                    Console.WriteLine("Metric Namespace: " + metricDefinition.Namespace);
                    metricNamespace = metricDefinition.Namespace;
                    Console.WriteLine("Is Altertable: " + metricDefinition.IsAlertable);
                    Console.WriteLine("Min. Altertable Time Window: " + metricDefinition.MinimumAlertableTimeWindow);
                    Console.WriteLine();
                }
    
                // timeGrain must be 5, 60 or 720 minutes.
                TimeSpan timeGrain = TimeSpan.FromMinutes(5);
                DateTime startTime = DateTime.UtcNow.AddHours(-1);
                DateTime endTime = DateTime.UtcNow;
    
                MetricValueListResponse response = metricsClient.MetricValues.List(resourceId, metricNames, metricNamespace, timeGrain, startTime, endTime);
    
                foreach (MetricValueSet value in response.MetricValueSetCollection.Value)
                {
                    String valueName = value.Name;
                    Console.WriteLine("MetricValue:{0}", valueName);
                    foreach (MetricValue metricValue in value.MetricValues)
                    {
                        Console.WriteLine("Maximum:{0}{1}", metricValue.Maximum, value.Unit);
                        Console.WriteLine("Average:{0}{1}", metricValue.Average, value.Unit);
                        Console.WriteLine("Minimum:{0}{1}", metricValue.Minimum, value.Unit);
                    }
                }
            }
        }
    }

    Run...

    程序在metricsClient.MetricValues.List(resourceId, metricNames, metricNamespace, timeGrain, startTime, endTime);

    出错了:
    Additional information: <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">{"Code":"InvalidRequest","Message":"Could not retrieve metrics."}</string>

    为啥不能获取监控指标呢?

    这个错误,Google一番依旧未果,咨询了微软的技术工程师,给了如下指导,resouceID必须执行RoleName:

    var resourceId = ResourceIdBuilder.BuildVirtualMachineResourceId("cloudService", "deploymentName", "roleName");

    修改之后,问题解决。

    至此,我们已经可以获取到监控指标和监控数据,下一步我们要获取自定义的性能计数器,基于自定义的性能计数器来实现自动伸缩。

    周国庆

  • 相关阅读:
    android 自定义日历控件
    android 常用类
    真假空格风波
    设计模式的初衷---“委托”有感
    pymysql.err.InterfaceError: (0, '')
    微信文章收藏到有道云笔记PC版只保留了标题
    SQL Server数据库字典生成SQL
    nhibernate常见错误
    NUnit
    使用ffmpeg截取视频
  • 原文地址:https://www.cnblogs.com/teld/p/5113376.html
Copyright © 2020-2023  润新知