当前位置: 首页 > news >正文

我做的基础服务项目,是如何实现 API 安全与限流的(短信、邮件、文件上传、钉钉通知)


我做的基础服务项目,是如何实现 API 安全与限流的(短信、邮件、文件上传、钉钉通知)


一、背景

最近我做了一个基础服务项目,主要对外提供短信、邮件、文件上传和钉钉通知等基础功能。这些接口是多个业务系统都要调用的,所以安全性、稳定性、限流控制必须得做好。

这篇文章就记录一下,我是怎么一步步设计这个系统,让它既能安全对接多个项目,又能抗住高并发调用的。


二、我遇到了什么问题?

这个系统上线初期,其实就碰到了几个问题:

  1. 接口被非法调用:没有权限的系统也能调用我们的短信接口,导致误发短信。
  2. 被刷接口:有个业务系统调用频繁,导致我们服务被打崩,日志里全是超时。
  3. 多项目对接混乱:不同项目调用同一接口,但权限、限流、日志都不一样,不好管理。

这些问题让我意识到,必须从架构层面统一解决 API 安全、限流、多项目对接等问题。


三、我是怎么做的?

我最终设计了一套统一的安全和限流机制,结合 Redis、拦截器、Lua 脚本等技术,解决了这些问题。

1. API 接口安全设计:API Key + Redis 校验

我给每个接入的项目分配一个唯一的 API Key,所有请求都必须在 Header 中带上 X-API-Key

Key 信息存在 Redis 中,包括:

  • 租户 ID(tenantId)
  • 是否启用
  • 过期时间

每次请求进来,拦截器会先校验 Key 是否有效。无效的直接返回 401。

实现亮点:
  • 使用 Redis 存储 Key,读取快,不影响性能
  • 拦截器统一处理,逻辑清晰
  • 可结合租户 ID 做日志追踪、限流隔离等
示例拦截器代码:
@Component
public class ApiKeyInterceptor implements HandlerInterceptor {@Autowiredprivate RedisTemplate<String, String> redisTemplate;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String apiKey = request.getHeader("X-API-Key");if (StringUtils.isBlank(apiKey)) {response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Missing API Key");return false;}String value = redisTemplate.opsForValue().get("api_key:" + apiKey);if (value == null) {response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid API Key");return false;}JSONObject json = JSON.parseObject(value);boolean enabled = json.getBoolean("enabled");long expireTime = json.getLong("expireTime");if (!enabled || System.currentTimeMillis() > expireTime) {response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "API Key expired or disabled");return false;}return true;}
}

2. 限流设计:Redis + Lua 实现滑动窗口限流

一开始我用的是 Guava 的限流组件,但发现它只适用于单机。后来我换成了 Redis + Lua 脚本,实现了分布式的滑动窗口限流。

Lua 脚本:
local key = KEYS[1]
local limit = tonumber(ARGV[1])
local windowSize = tonumber(ARGV[2])
local now = tonumber(ARGV[3])redis.call('ZREMRANGEBYSCORE', key, 0, now - windowSize * 1000)
local count = redis.call('ZCARD', key)if count >= limit thenreturn false
elseredis.call('ZADD', key, now, now)return true
end
Java 调用逻辑:
@Service
public class RateLimitService {@Autowiredprivate RedisTemplate<String, String> redisTemplate;private static final Long LIMIT = 100L; // 每分钟最多100次private static final Long WINDOW_SIZE = 60L; // 时间窗口60秒public boolean isAllowed(String apiKey) {String key = "rate_limit:" + apiKey;long now = System.currentTimeMillis();DefaultRedisScript<Boolean> script = new DefaultRedisScript<>(luaScript, Boolean.class);return redisTemplate.execute(script,Arrays.asList(key),LIMIT.toString(), WINDOW_SIZE.toString(), String.valueOf(now));}
}

然后我在拦截器中调用限流逻辑,拒绝超过限制的请求。

实现亮点:
  • 支持分布式限流,适合多节点部署
  • 滑动窗口比固定窗口更精准
  • Lua 脚本保证原子性,避免并发问题

3. 多项目对接策略

为了支持多个项目接入,我做了以下几点:

  • 所有 API Key 绑定租户 ID,便于日志追踪、限流隔离
  • 统一网关(Nginx + Spring Cloud Gateway)做路由、鉴权、限流
  • 用 Nacos 管理 API Key、限流规则等配置,支持运行时热更新

四、难点与亮点总结

难点:

  1. 如何在分布式环境下实现限流?
    答案是 Redis + Lua 脚本,保证原子性,避免并发问题。

  2. 如何防止非法调用?
    API Key + Redis 校验机制,拦截器统一处理,简单有效。

  3. 如何支持多项目对接?
    给每个项目分配独立的 API Key,绑定租户信息,限流、日志、权限都按租户隔离。

亮点:

  1. 模块清晰,易于扩展:短信、邮件、文件上传等功能模块化,方便维护。
  2. 统一安全机制:API Key + 限流,保障系统安全。
  3. 支持高并发:Redis + Lua 脚本应对分布式限流,性能稳定。
  4. 可扩展性强:后续可接入 Nacos、Prometheus、日志系统等,形成完整生态。

五、效果如何?

这套方案在我们公司已经上线使用几个月了,日均调用量几万次,没出过安全问题,也没被刷崩过,效果还不错。

  • 接口安全性大幅提升
  • 限流机制有效防止了刷接口
  • 多项目接入统一管理,效率提高

如果你也在做类似的平台,或者想搭建一个对外的基础服务系统,可以参考这套架构,亲测可用。


http://www.xdnf.cn/news/1149211.html

相关文章:

  • Jenkins 实现项目的构建和发布
  • 企业运维实战:Jenkins 依赖 JDK21 与应用需 JDK1.8 共存方案(含流水线配置)
  • 【ExtendScript Toolkit CC】【PR插件开发】获取当前序列的所有剪辑片段名
  • Java 性能调优实战:JVM 参数配置与 GC 日志分析
  • 深度学习-线性神经网络
  • QCC系列显示交互层的自研技术突破与实践
  • 本地大模型部署工具全解析:LM Studio vs. Ollama 及最佳实践指南
  • 81、【OS】【Nuttx】【启动】caller-saved 和 callee-saved 示例:压栈内容
  • Mybatis学习之简介(一)
  • Django接口自动化平台实现(三)
  • 多式联运物流管理系统的设计与实现(原创)
  • picoCTF 2024: [[NoSQL]] Injection - Writeup
  • 【MATLAB例程】Taylor算法用于TOA(到达时间)的三维标签位置解算,可自适应基站数量。附下载链接
  • 一个基于阿里云的C端Java服务的整体项目架构
  • 后缀树:字符串处理的利器
  • 模型轻量化全指南:从剪枝量化到低配置设备部署实战
  • 【Linux】基本指令详解(三) 指令本质、三个查找指令、打包压缩、重要热键、linux体系结构、命令行解释器
  • Go-Redis × 向量检索实战用 HNSW 在 Redis 中索引与查询文本 Embedding(Hash JSON 双版本)
  • 智能光电检测:YOLO+OpenCV联合算法工程实践
  • 【运维】flash attention安装出现错误及编译慢
  • 思维链(CoT)技术全景:原理、实现与前沿应用深度解析
  • windows wsl2-06-docker hello world
  • 1.初始化
  • Windows原生环境配置Claude Code MCP(通过JSON)
  • 【MySQL笔记】视图
  • Spring AI 项目实战(十九):Spring Boot + AI + Vue3 + OSS + DashScope 构建多模态视觉理解平台(附完整源码)
  • mac 配置svn
  • 医疗AI与融合数据库的整合:挑战、架构与未来展望(上)
  • xss-labs1-8题
  • 浏览器渲染原理——计算属性和布局过程常考内容