本文共 5421 字,大约阅读时间需要 18 分钟。
在调用阿里云 CDN openAPI,经常会出现各种各样的问题排查起来没有好的思路不好分析,今天说下基本的排查思路。
不管调什么 CDN openAPI,无论是控制台还是 SDK 或者用户的脚本,出现问题都可以按照如下思路排查。
1) 调用 CDN openAPI 一定会返回一个阿里云的 requestID ,这个值是用来排查用户完整的请求参数和返回结果的凭证,如果客户端调用 API 返回结果不是预期或者请求失败,都会返回,务必保留。
2)如果没有 requestID 返回的情况下,需要用户提供
获取 requestID 的情况。
1)先查 云台,requestID 的请求过程记录;
一站式查询-》 ECS 全链路日志 -〉 输入 requestID -》调整日志 查询。关注下列的信息,查看详细的返回错误内容,以及错误信息、API 名称;2)搜索 API.文档
对应的 API ,然后查看 API 请求是否有特殊说明,举例说明类似如下是 API 调用文档,我们先要明白 API 是做什么的?然后了解使用上的限制?以及调用传参的限制?对比用户的参数使用是否都是正确的,如果确保都是正确再向下排查。
3)调用测试
当文档和 requestID 都查不出来后,我们只能调用 openAPI 亲自测试一遍,这里提供了下载的测试脚本,可以参考。测试是请使用客户端的 AccesskeyID 和 SecretKey 测试,这样贴近用户环境测试结果更有效。
aliyun.ini 脚本
[Credentials]accesskeyid =accesskeysecret =
can.py 生成鉴权 URL 脚本
#!/usr/bin/python# -*- coding:utf-8 -*-import sys,osimport urllib, urllib2import base64import hmacimport hashlibfrom hashlib import sha1import timeimport uuidimport jsonfrom optparse import OptionParserimport ConfigParserimport tracebackaccess_key_id = '';access_key_secret = '';cdn_server_address = 'https://cdn.aliyuncs.com'CONFIGFILE = os.getcwd() + '/aliyun.ini'CONFIGSECTION = 'Credentials'cmdlist = '''接口说明请参照pdf文档'''def percent_encode(str): res = urllib.quote(str.decode(sys.stdin.encoding).encode('utf8'), '') res = res.replace('+', '%20') res = res.replace('*', '%2A') res = res.replace('%7E', '~') return resdef compute_signature(parameters, access_key_secret): sortedParameters = sorted(parameters.items(), key=lambda parameters: parameters[0]) canonicalizedQueryString = '' for (k,v) in sortedParameters: canonicalizedQueryString += '&' + percent_encode(k) + '=' + percent_encode(v) stringToSign = 'GET&%2F&' + percent_encode(canonicalizedQueryString[1:]) h = hmac.new(access_key_secret + "&", stringToSign, sha1) signature = base64.encodestring(h.digest()).strip() return signaturedef compose_url(user_params): timestamp = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()) parameters = { \ 'Format' : 'JSON', \ 'Version' : '2014-11-11', \ 'AccessKeyId' : access_key_id, \ 'SignatureVersion' : '1.0', \ 'SignatureMethod' : 'HMAC-SHA1', \ 'SignatureNonce' : str(uuid.uuid1()), \ 'TimeStamp' : timestamp, \ } for key in user_params.keys(): parameters[key] = user_params[key] signature = compute_signature(parameters, access_key_secret) parameters['Signature'] = signature url = cdn_server_address + "/?" + urllib.urlencode(parameters) return urldef make_request(user_params, quiet=False): url = compose_url(user_params) print urldef configure_accesskeypair(args, options): if options.accesskeyid is None or options.accesskeysecret is None: print("config miss parameters, use --id=[accesskeyid] --secret=[accesskeysecret]") sys.exit(1) config = ConfigParser.RawConfigParser() config.add_section(CONFIGSECTION) config.set(CONFIGSECTION, 'accesskeyid', options.accesskeyid) config.set(CONFIGSECTION, 'accesskeysecret', options.accesskeysecret) cfgfile = open(CONFIGFILE, 'w+') config.write(cfgfile) cfgfile.close()def setup_credentials(): config = ConfigParser.ConfigParser() try: config.read(CONFIGFILE) global access_key_id global access_key_secret access_key_id = config.get(CONFIGSECTION, 'accesskeyid') access_key_secret = config.get(CONFIGSECTION, 'accesskeysecret') except Exception, e: print traceback.format_exc() print("can't get access key pair, use config --id=[accesskeyid] --secret=[accesskeysecret] to setup") sys.exit(1)if __name__ == '__main__': parser = OptionParser("%s Action=action Param1=Value1 Param2=Value2\n" % sys.argv[0]) parser.add_option("-i", "--id", dest="accesskeyid", help="specify access key id") parser.add_option("-s", "--secret", dest="accesskeysecret", help="specify access key secret") (options, args) = parser.parse_args() if len(args) < 1: parser.print_help() sys.exit(0) if args[0] == 'help': print cmdlist sys.exit(0) if args[0] != 'config': setup_credentials() else: #it's a configure id/secret command configure_accesskeypair(args, options) sys.exit(0) user_params = {} idx = 1 if not sys.argv[1].lower().startswith('action='): user_params['action'] = sys.argv[1] idx = 2 for arg in sys.argv[idx:]: try: key, value = arg.split('=') user_params[key.strip()] = value except ValueError, e: print(e.read().strip()) raise SystemExit(e) make_request(user_params)
4) 测试分析
如果发现按照 API 文档,生成的 API 调用 URL 没有问题,说明用户使用的 API 代码可能存在问题,或者传的参数和我们不一样。可以用生成的正常 URL 和异常的 URL 进行比对。有用户问控制台的各项指标什么含义,峰值 QPS 是哪个,总的 QPS 是哪个? HTTPS 的带宽和 HTTP 带宽怎么区分,等等。
或者控制体台报错的问题,访问控制异常问题,所有此类问题都可以按照如下排查;1) 首先浏览器打开 F12。开发者模式。
2) 找到你要浏览的页面或者你点击的功能模块,触发调用。
3)然后分析你触发调用请求的 URL 是什么,大致都可看出来的,并不复杂。比如我是查域名的流量,那就是 DescribeDomainBpsData.json 接口,也就是 CDN 的 openAPI ,因为即便是控制台也是调用后端 API 操作的。
4)然后看浏览器对应的响应头信息,将这些头和 API 对应的文档 返回参数说明对比就知道什么含义了。
某用户反馈调用直播导播台的 DescribeCasters 功能,并没有返回 CasterTemplate 字段。
首先找到这个 API 的解释说明
通过这个 API 告诉了用户两个条件:
1)导播台分辨率配置,付费类型为预付费时必输。那也就是非预付费的不一定会输出。
2)用户是否在直播的播流域名上配置了,转码如果没有配置转码的话,一样不会输出 CasterTemplate 字段;
转载地址:http://jrxal.baihongyu.com/