1、设计数据库:
- 尽可能提前确定字段,避免在开发接口时修改过多。
- 尽可能选择占用存储空间小的字段类型,在满足正常业务需求的情况下,从小到大,往上选。
- 如果字符串长度固定,或者差别不大,可以选择char类型。(例如学号、身份证号)如果字符串长度差别较大,可以选择varchar类型。
- 数字枚举字段,可以选择tinyint类型。
- 主键字段,可以选择bigint、int、CHAR(16)、VARCHAR(36)类型。
- 金额字段,可以选择decimal类型。
- 时间字段,可以选择timestamp或datetime类型。
- 知道某些字段将频繁用于查询或连接操作时,可以在创建表的语句中添加相应的索引。
2、多用explain查看执行计划
写完查询SQL语句之后,用explain关键字查看一下该SQL语句有没有走索引。
3、避免一次性查询太多数据
问题:一次性查询太多的数据,可能会导致查询耗时很长,更加严重的情况会导致系统出现OOM的问题。
解决:
- 优化查询和索引:通过使用适当的【索引】、【减少返回结果的数量】、适当地【分页】等方式来优化查询。这将减少查询的内存消耗,并提高查询性能。
- 分批处理数据:将大型数据集或复杂查询拆分成较小的批次进行处理。这样可以减少每个查询或操作涉及的数据量,从而降低内存消耗。
如果调用第三方批量查询接口,对性能有一定的要求,我们可以分批之后,用多线程调用接口,最后汇总返回数据。
- 避免返回过多的冗余数据或不必要的字段。
4、优先使用批量操作
能批量操作的不要循环操作
例如:
for(User user : userList) {
userMapper.update(user);
}
userMapper.updateForBatch(userList);
5、耗时操作异步处理
一些复杂的逻辑,非核心逻辑可以异步处理,例如:大文件上传、调用第三方接口、消息推送。
实现:job、mq、CompletableFuture、多线程、回调函数。
6、注意事务问题
多表操作时要保证数据一致性,简单的场景可以使用@Transactional注解解决,复杂的场景可以使用TransactionTemplate的编程式事务,多数据源场景可以使用@DsTransactional,分布式场景可以使用@GlobalTransactional。
注意事务失效问题,大事务问题,数据库死锁问题。
7、注意线程安全问题
- 单机环境可以使用synchronized 关键字、Lock 接口实现加锁。
- 尽量使用局部变量,使用全局变量要用线程安全的类型,例如:AtomicInteger、AtomicLong、AtomicBoolean、StringBuffer、ConcurrentHashMap、CopyOnWriteArrayList。
- 分布式环境可以使用分布式锁,例如:
使用基于数据库的分布式锁:可以通过在数据库中创建一张表作为锁的标识,利用数据库的事务和唯一性约束来实现分布式锁。具体步骤如下:
创建一张专门用于存放锁的表,例如命名为 distributed_lock。
当需要获取锁时,通过执行 SQL 语句向 distributed_lock 表中插入一条唯一的记录,如果插入成功,则表示获取到了锁。
如果获取锁失败,则等待一段时间后重试或返回获取锁失败的信息。
在任务完成后,释放锁时,删除相应的记录。
使用分布式缓存中间件实现分布式锁:可以利用分布式缓存中间件的原子性操作和超时机制来实现分布式锁。常用的分布式缓存中间件有 Redis 和 ZooKeeper。以下是一个使用 Redis 实现分布式锁的示例:
当需要获取锁时,通过向 Redis 中设置一个特定的键值对(例如,键为锁的名称、值为唯一标识符)来尝试获取锁。
如果设置成功,则表示获取到了锁;如果设置失败,则表示锁已经被其他线程占用,可以选择等待一段时间后重试或返回获取锁失败的信息。
在任务完成后,通过删除相应的键来释放锁。
8、接口要做幂等性设计
比如:用户在前端页面,非常快的点击了两次保存按钮,这样就会在极短的时间内调用你两次接口。
实现:
- 前端请求接口携带一个标识(例如:UUID、版本号),处理前先校验一下是否重复。
- 数据库唯一索引约束
- 数据库锁(悲观锁、乐观锁)
- token令牌
9、调用第三方接口注意
- 处理接口调用失败、超时、返回错误码等情况,处理接口调用失败、超时、返回错误码等情况
- 并发和性能问题:当需要大量并发调用第三方接口时,要注意接口的并发限制和性能问题。尽量避免过多的并发请求,合理控制调用频率,以免对第三方系统造成压力或触发限流机制。
- 异步和批量处理:如果允许的话,可以尝试将接口调用设计为异步或批量处理,以提高效率和性能。合理利用队列、消息中间件等技术,将接口请求进行批量发送或异步处理,减少对第三方接口的频繁调用。
- 监控和日志记录:在调用第三方接口时,建议记录相应的监控指标和日志信息。例如接口调用时间、成功率、错误信息等,这有助于排查问题、分析性能和追踪调用链路,保证系统的稳定和可追溯性。
10、设计接口参数
- 校验数据格式、长度,是否必填。
- 文档和注释,对于每个参数都要提供清晰的文档说明和注释。描述参数的作用、取值范围、限制条件。
- 尽量避免删除参数和修改参数名。