大促场景下电商、支付等核心业务会产生数倍于日常的SQL请求,数据库很容易因为承载过高出现慢查询、连接池耗尽等问题,合理的限流与降级策略是应对这类场景的核心手段。

SQL限流的核心策略
SQL限流的目的是在请求到达数据库之前控制流量规模,避免数据库被过量请求击垮,常见的限流维度有以下几种:
1. 基于SQL并发数限流
对同一类型的高频SQL设置最大并发执行数,超过阈值的请求会被直接拒绝或者进入等待队列。比如针对商品详情页的库存查询SQL,限制同时最多有100个请求执行该语句。
以Java应用为例,我们可以通过自定义拦截器实现简单的SQL并发限流:
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Semaphore;
public class SqlConcurrencyLimiter {
// 存储SQL模板对应的信号量,key为SQL模板的哈希值
private static final ConcurrentHashMap<String, Semaphore> SQL_SEMAPHORE_MAP = new ConcurrentHashMap<>();
// 初始化限流规则,sqlTemplate为SQL模板,maxConcurrency为最大并发数
public static void initLimitRule(String sqlTemplate, int maxConcurrency) {
String key = String.valueOf(sqlTemplate.hashCode());
SQL_SEMAPHORE_MAP.put(key, new Semaphore(maxConcurrency));
}
// 尝试获取执行权限,获取成功返回true,失败返回false
public static boolean tryAcquire(String sqlTemplate) {
String key = String.valueOf(sqlTemplate.hashCode());
Semaphore semaphore = SQL_SEMAPHORE_MAP.get(key);
if (semaphore == null) {
return true;
}
return semaphore.tryAcquire();
}
// 释放执行权限
public static void release(String sqlTemplate) {
String key = String.valueOf(sqlTemplate.hashCode());
Semaphore semaphore = SQL_SEMAPHORE_MAP.get(key);
if (semaphore != null) {
semaphore.release();
}
}
}
2. 基于SQL执行时长限流
对执行时长超过阈值的慢SQL进行限制,避免慢查询占用过多数据库资源。可以在数据库中间件层配置规则,自动终止执行时长超过2秒的查询类SQL。
3. 基于请求来源限流
对核心业务和非核心业务的SQL请求做区分,优先保障核心业务的SQL资源,限制非核心业务的SQL并发量。比如大促期间限制运营后台的批量查询SQL并发数不超过20。
SQL降级的核心策略
当数据库负载达到阈值时,通过降级非核心功能来减少SQL请求量,保障核心业务的正常运行,常见的降级策略如下:
1. 查询降级
对非实时的查询请求返回缓存数据,或者返回简化版的结果。比如商品评论列表在大促期间默认只返回前10条最新评论,不再支持分页查询,减少关联查询的SQL执行。
2. 功能降级
临时关闭非核心功能,减少对应的SQL请求。比如大促期间关闭用户的浏览历史记录功能,不再执行插入浏览记录的SQL,同时关闭商品推荐模块的关联查询。
3. 写操作降级
对非核心的写操作进行合并或者延迟处理。比如用户的积分变更操作,先暂存到消息队列中,等大促峰值过后再批量执行SQL写入数据库,避免大量写请求占用数据库资源。
策略落地的注意事项
在实际落地过程中需要注意以下几点:
- 限流和降级规则需要根据历史大促的流量数据进行提前配置,避免阈值设置不合理导致误限或者防护失效。
- 降级策略需要提前做好开关配置,支持动态开启和关闭,不需要重启服务即可调整策略。
- 需要对限流和降级的触发情况做好监控和告警,及时感知策略生效情况,方便后续优化规则。
以下是简单的降级开关配置示例:
import java.util.concurrent.ConcurrentHashMap;
public class SqlDegradeSwitch {
// 存储降级开关状态,key为功能标识,value为是否开启降级
private static final ConcurrentHashMap<String, Boolean> DEGRADE_SWITCH_MAP = new ConcurrentHashMap<>();
// 开启指定功能的降级
public static void openDegrade(String functionKey) {
DEGRADE_SWITCH_MAP.put(functionKey, true);
}
// 关闭指定功能的降级
public static void closeDegrade(String functionKey) {
DEGRADE_SWITCH_MAP.put(functionKey, false);
}
// 判断指定功能是否开启降级
public static boolean isDegradeOpen(String functionKey) {
return DEGRADE_SWITCH_MAP.getOrDefault(functionKey, false);
}
}
通过合理的限流与降级策略组合,可以有效提升SQL在大促场景下的抗压能力,保障核心业务的稳定运行。开发者需要根据自身业务的特点,灵活调整策略规则,同时做好全链路的监控,确保策略生效。