限流一般的处理手段:
<1>丢弃:
超过限制流量的时候,最直接的方法是根据响应时间直接拒绝,这个比较武断;
<2> 降级
超过限定流量的时候,在保证核心服务的时候,将非核心的服务去掉;
<3>队列以后处理(业务对数据不敏感,可以在峰值过了后进行处理)
超过限定流量,如果业务流程走完,但是就是落地持久化的时候有问题,在不影响业务的情况下,可以先用队列进行持久化,然后再更新到相关的数据库中。
限流的处理策略:
限流有分为自动降级和手动降级,自动降级可以根据业务的反应速度来进行降级,手动降级通知手动开关来进行。
限流包括读服务降级、写服务降级。
限流包括从接入层到后端层等多级多个级别的限流措施。
调用第三方服务策略(第三方服务有限流):
实际上在调用第三方服务的时候,如何在接入层进行限流,又保证不被第三方拒绝,那么在业务层需要根据详细的访问策略来进行流量限制,在调用第三方的时候要进行限制,主要作用:
1>调用第三方服务要保证不能超过第三方服务的qps
2>在接入层限流的情况下,因为后端要涉及到多个第三方,包括可能采取二个同样服务的能力的第三方作为备份,在接入层的限流可能没那么精细
3>第三方流量的实际情况,比如:单位流量超限制要反馈到接入层和处理层,在接入层直接进行丢弃,在处理层可以进行降级处理,这需要在调用第三方的时候针对调用的失败进行统计
redis相关的支持:
redis中可以使用expire命令设置一个键的生存时间,到时间后redis会自动删除它
expire 设置生存时间(单位/秒)
pexpire 设置生存时间(单位/毫秒)
ttl/pttl 查看键的剩余生存时间
persist 取消生存时间
expireat [key] unix时间戳1351858600
pexpireat [key] unix时间戳(毫秒)1351858700000
使用redis进行限制的lua脚本:
local key = "rate.limit:" .. KEYS[1]
local limit = tonumber(ARGV[1])
local expire_time = ARGV[2]
local is_exists = redis.call("EXISTS", key)
if is_exists == 1 then
if redis.call("INCR", key) > limit then
return 0
else
return 1
end
else
redis.call("SET", key, 1)
redis.call("EXPIRE", key, expire_time)
return 1
end
如果觉得秒级的限制不可以的话,可以使用
redis.call("PEXPIRE", key, expire_time)