优化请求
和风天气会根据你的请求,通过API或SDK的方式向你提供天气服务,在这一过程中,需要尽量优化你的请求,以便更高效的使用我们的服务,这篇文档将介绍几种常见的优化方式。
为了更有效的使用和风天气开发服务,你需要尽量优化你的请求。这篇文档将介绍几种常见的优化方式。
构建合法的URL
当你使用API获取数据的时候,会通过URL向我们发起请求,例如:
https://abcxyz.qweatherapi.com/v7/weather/3d?parameters
一般来说,这段请求URL不会出现错误,但是在传递一些特殊的参数和值的时候需要特别注意:
特殊字符
根据 RFC 3986 URI 标准,URL 中除英文字母、数字和部分非预留字符(- _ . ~)外,其他字符在请求参数值中都必须进行 URL 编码(URL encoding)或称之为百分号编码(Percent-encoding),以确保请求能被正确解析和传输。
请求参数中无需编码的字符:
- 英文字母:
A-Z
,a-z
- 数字:
0-9
- 非预留字符:
-
_
.
~
请求参数必须编码的字符:
- 空格,请编码为
%20
,不建议使用+
,例如new york
➡️new%20york
- 中文或其他非 ASCII 字符,例如
北京
➡️%E5%8C%97%E4%BA%AC
- 英文逗号
,
作为保留字符通常无需编码,但为了确保兼容所有服务器和客户端的解析行为,强烈建议也将其进行 URL编码,避免歧义:color=blue,red
➡️color=blue%2Cred
- 上述无需编码字符列表以外的字符
无效的空格
请求URL中还需要注意那些无效的空格,这种情况常见于复制粘贴操作。例如,当复制一段 Token 时,可能会在其前后不小心夹带空格。粘贴后应仔细检查并手动删除这些空格,否则可能导致请求 URL 格式错误,或传递的参数不正确,进而影响接口的正常访问。
中文符号混用
在使用允许的特殊字符时,请注意不要与对应的中文符号混淆。例如,查询参数的起始符应使用英文问号?
,而不是中文问号?
。符号混用可能导致请求解析失败或行为异常。
安全的请求
请不要共享完整的请求URL,这有可能泄露你的敏感信息,使用HTTPS、JWT身份认证等方式发送安全的API请求。关于如果保护API安全,请参考安全指南。
处理错误
当你的请求返回错误码时,你需要暂停请求并妥善的处理这些错误,否则这些错误可能看起来像DDoS攻击,我们的安全策略将冻结你的帐号。
例如: 当你传入了错误的参数或KEY,将返回
400
或403
,此时你应该暂停这一次的请求,排除故障后再继续。否则当程序不断重试而产生大量失败的请求时,这违反了我们的许可协议且被视为一种攻击,我们将中止你的服务并冻结你的帐号。
了解状态码
请参考错误码。
使用指数退避算法处理错误
当出现错误的时候,请停止请求并进行检查,待故障排除后再恢复请求。然而一些错误并非由于请求不符合规范而导致的,例如超过每分钟请求限制,没有足够的余额等等,这时你应该使用指数退避算法优化请求。
例如,当你的请求收到429
状态码时,代表你超过了每分钟请求次数,此时你应该在下次请求开始前添加x秒的等待期。如果下次请求仍然返回429
,则将等待期延长一倍,再发送另一次请求,以此类推,继续延长等待期,直至不再返回错误状态码。
简单的公式可以参考:
t = bc
其中t
代表下次请求的间隔时间,或称之为等待期,b
代表基数,c
是发生错误的次数。如果按照上述的例子来讲,假设b = 2
,那么在出现第一次错误时,下一次请求应该等待21 = 2秒,再下一次请求应等待22 = 4秒,第三次请求等待23 = 8秒,如果第四次请求响应正常,则恢复之前的请求频率并重置c = 1
。
避免冲突
如果你有大量独立设备发送请求,为了避免这些设备产生了相同的等待期而产生冲突(比如都在等待2秒后重新发送,这并不能恢复QPM),你可以在等待期中设置一个随机数,或称之为插槽,这个随机数的取值范围可以是0~2c-1。在上述例子中,前三次的等待期的随机数分别是:
- 第一次:0, 1
- 第二次:0, 1, 2, 3
- 第三次:0, 1, 2, 3, 4, 5, 6, 7
这样你的多个独立设备每次都有不同的等待期而避免了冲突。
截断
等待期不应是无限的,如果连续出现20次错误,那么此时的等待期就已经长达291个小时,这显然是不现实的。因此你需要为等待期设置一个最大值,当达到这个值时,则不再增加c的取值。我们的建议是c = 10
。
按需请求
仅在需要天气数据的时候再进行请求。
例如:在APP中,天气内容的位置较为靠下,你可以让程序在用户滑动到天气内容部分再进行请求。
如果已经加载了天气内容,你也可以为这个内容设置缓存时间,或者增加一个刷新按钮,让用户手动去刷新数据。关于设置缓存,请参考缓存你的数据。