个人练手项目(Java)-API开放平台(一)——项目背景与技术选型
前言
为了巩固一些学到的java开发技术,于是我将它们综合之后创建了这个练手项目——API开放平台。本项目皆在提供一个类似阿里云API市场的开发者平台,不仅包含完整的前后端交互,更重点攻克网关限流、异步解耦与海量日志检索等后端核心痛点
项目背景与业务痛点分析
1.核心业务:管理员在后台发布各类 API 接口,开发者注册后申请调用密钥(AK/SK),并在自己的代码中集成调用。
2.技术痛点:
- 瞬间高并发:如何防止恶意用户利用脚本疯狂刷接口,导致底层数据库宕机?
- 同步阻塞问题:每次 API 调用都会产生计费和日志,如果同步写入数据库,接口响应会极度缓慢。
- 海量数据检索:平台每天可能产生百万级以上的调用日志,如何在 C 端控制台让用户秒级查出带有特定条件的报错日志?
技术栈选型与破局思路
为了解决上述痛点,本项目引入了多项中间件:
底层基石:Spring Boot + MyBatis + MySQL
负责核心元数据(用户信息、接口配置、密钥状态)的持久化与状态机流转。
极速缓存与限流防刷:Redis
不直接查库,将用户的权限数据预热至 Redis。在 API 网关层结合 Lua 脚本实现高性能的“令牌桶算法”,对接口调用进行毫秒级限流。
异步解耦与削峰填谷:RocketMQ / Kafka 网关处理完核心逻辑后,将“调用日志”打包发送至消息队列,立刻响应用户。后台消费者平滑拉取日志,彻底剥离耗时操作,保障 API 接口的高吞吐量。
海量文本秒级检索:ElasticSearch 面对庞大且复杂的调用日志,放弃 MySQL 的低效模糊查询。将 MQ 消费出的日志批量存入 ES,利用倒排索引实现控制台的多维度、秒级报表查询。
并行处理优化:Java 多线程 (JUC) 在后台生成用户调用统计报表时,使用自定义线程池与
CompletableFuture实现多任务并行处理,大幅缩短定时任务的执行时间。规范与工程化:Maven + Apifox + Swagger 使用 Maven 进行标准的多模块划分;后端接口接入 Swagger 自动生成文档,并导入 Apifox 进行标准化的前后端接口联调。
前端展示:Vue3 复用前端优势,搭建高颜值的数据可视化开发者控制台。
系统架构与多模块划分
项目采用 Maven 多模块(Multi-Module)架构:
api-platform-common: 公共组件、全局异常、工具类。api-platform-model: 统一的数据模型(Entity, DTO, VO)。api-platform-backend: 核心管控后台,提供给前端的 RESTful 接口。api-platform-gateway: 高并发核心,基于 Spring Cloud Gateway,负责鉴权、路由、Redis 限流与 MQ 消息投递。api-platform-interface: 模拟底层真实 API 接口服务。api-platform-client-sdk: 为开发者封装的专属 Java 客户端 SDK,实现开箱即用的签名与调用。
阶段规划
阶段一:系统架构设计、数据库表结构构建。
阶段二:核心管控后台开发与 Swagger/Apifox 联调。
阶段三:API 网关搭建、客户端 SDK 开发与签名认证(核心难点)。
阶段四:引入 Redis 限流、MQ 异步日志与 ES 报表检索。
数据库设计
用户表 (user)
对于 API 开放平台,用户除了账号密码,最重要的是分配给他用来调用 API 的**“通行证”**(AccessKey 和 SecretKey)。
| 字段名 | 类型 | **说明 ** |
|---|---|---|
id |
BIGINT | 主键。 |
user_account |
VARCHAR | 登录账号。 |
user_password |
VARCHAR | 登录密码(用 MD5+Salt 加密)。 |
phone |
VARCHAR | 手机号,用于短信登录和找回密码。 |
access_key |
VARCHAR | 核心,API 调用的公钥(账号)。 |
secret_key |
VARCHAR | 核心,API 调用的私钥(密码,用于签名防篡改)。 |
user_role |
VARCHAR | 权限隔离:区分 admin(管理员,能发接口)和 user(普通开发者)。 |
create_time |
DATETIME | 创建时间。 |
update_time |
DATETIME | 更新时间。 |
is_delete |
TINYINT | 逻辑删除标志(0表示正常,1表示已删除)。 |
接口信息表 (interface_info)
这个表是提供给开发者调用的“商品货架”。不仅需要名字,还需要告诉网关怎么去请求这个接口。
| 字段名 | 类型 | **说明 ** |
|---|---|---|
id |
BIGINT | 主键。 |
name |
VARCHAR | 接口名称 |
description |
VARCHAR | 接口描述。 |
url |
VARCHAR | 核心 ,接口的真实调用地址。 |
method |
VARCHAR | 请求类型(GET / POST 等),网关路由必须用到。 |
request_params |
TEXT | 请求参数说明(存 JSON 格式,方便前端渲染接口文档)。 |
request_header |
TEXT | 请求头说明。 |
response_header |
TEXT | 响应头说明。 |
status |
TINYINT | 接口状态(0-关闭下线,1-正常上线),方便管理员随时停用出 Bug 的接口。 |
user_id |
BIGINT | 创建人 ID(记录是哪个管理员发布的)。 |
create_time |
DATETIME | 创建时间。 |
update_time |
DATETIME | 更新时间。 |
is_delete |
TINYINT | 逻辑删除标志。 |
用户调用接口关系表 (user_interface_info)
在关系型数据库中,永远不要在关系表里存“账户名”和“接口名”这类会变动的文本,而是应该存它们的 id(外键思想)。从而消除数据冗余。
这个表主要用于记录配额(剩余调用次数)。
| 字段名 | 类型 | 说明 |
|---|---|---|
id |
BIGINT | 主键。 |
user_id |
BIGINT | 调用者的用户 ID。 |
interface_info_id |
BIGINT | 被调用的接口 ID。 |
total_num |
INT | 总调用次数(历史一共调了多少次,用于统计)。 |
left_num |
INT | 核心,剩余可调用次数(每次调用扣减 1,为 0 时 Redis/网关直接拦截)。 |
status |
TINYINT | 状态(0-正常,1-封号禁用)。比如发现某人恶意刷接口,单独封禁他调这个接口的权限。 |
create_time |
DATETIME | 创建时间。 |
update_time |
DATETIME | 更新时间。 |
is_delete |
TINYINT | 逻辑删除标志。 |
API签名机制
很多人可能经常听到“调用API”,但是不知道API签名的运作原理,现在就让我们了解一下
API 调用通常是机器对机器(代码对代码),且需要极高的防伪造能力。
- AccessKey (AK): 相当于用户名(公开的)。告诉网关“我是谁”。
- SecretKey (SK): 相当于密码(绝对不能在网络上传输!)。
签名(Signature)的运作原理(就像对暗号):
- 客户端(开发者)端: 开发者把请求参数(比如想查哪个城市的天气)、加上随机数、加上当前时间戳,最后跟自己的 SecretKey (SK) 混在一起,用一种不可逆的加密算法(如 HMAC-SHA256),算出一个乱码字符串,这个乱码就是**“签名 (Sign)”**。
- 发送请求: 开发者把请求参数、AK、随机数、时间戳、以及算好的签名(Sign) 发给网关。(注意:这里面绝对不包含 SK)。
- 服务端(网关)校验: 网关拿到请求后,看到 AK,去数据库里查出这个 AK 对应的 SK 是什么。 然后,网关用收到的请求参数、随机数、时间戳,结合查出来的 SK,用同样的加密算法,自己也算出一个“签名”。
- 比对结果: 如果算出来的签名,和开发者发过来的签名一模一样,说明两件事:第一,他确实知道正确的 SK;第二,这个请求在半路上没有被黑客篡改过(如果参数被改了,算出来的签名一定不一样)。
(注:加上随机数和时间戳,是为了防止黑客把正常的请求录下来,隔五分钟后再疯狂重发,这叫防重放攻击。)
核心数据库SQL建表脚本
创建数据库
1 | -- 创建数据库 |
用户表
1 | -- 1. 用户表 (开发者与管理员) |
接口信息表
1 | -- 2. 接口信息表 (API 商品货架) |
用户调用接口关系表
1 | -- 3. 用户调用接口关系表 (剩余调用次数与配额) |
准备工作
搭建Maven微服务多模块骨架

连接数据库

以及配置模块之间的关系、引入一些组件,到此为止本项目的环境搭建已经准备完毕,后续文章将会更新开发过程
我会将此项目上传到我的GitHub,如果喜欢可以点个⭐!







