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

【整理】后端接口设计和优化相关思路汇总

文章目录

    • 明确的接口定义和文档化
    • 使用RESTful设计规范
    • 分页和过滤
    • 合理使用缓存
    • 限流与熔断机制
    • 安全性设计
    • 异步处理与后台任务
    • 接口参数校验(入参和出参)
    • 接口扩展性考虑
    • 核心接口,线程池隔离
    • 关键接口,日志打印
    • 接口功能单一性原则
    • 接口查询优化,串行改为并行
    • 确保接口兼容性的策略
    • 调用第三方接口要考虑异常和超时处理
    • 接口实现过程中,注意大文件、大事务、大对象
    • 仔细检查代码避免出现粗心的空指针异常
    • 考虑是否存在事务失效的问题场景

明确的接口定义和文档化

接口的明确定义和完善的文档能够减少沟通成本,避免误用。文档化还可以方便后续维护和扩展。

使用RESTful设计规范

遵循RESTful设计风格,使得接口更具一致性和可读性,并便于理解和使用。

分页和过滤

对于返回大量数据的接口,使用分页和过滤以减少数据传输量和提高响应速度。

合理使用缓存

在高并发的后端系统中,合理使用缓存可以显著提升性能,减轻数据库的压力,并缩短接口的响应时间。缓存的核心思想是将一些计算量大、访问频繁的数据暂时存储在内存中(如Redis、Memcached等),当下次请求相同数据时,可以直接从缓存中获取,而不需要再次访问数据库或执行复杂的计算。

限流与熔断机制

限流与熔断机制旨在防止系统过载,保护服务稳定性。限流控制请求频率,避免瞬间高并发冲击;熔断则在服务不稳定时主动停止请求,防止连锁故障,并在服务恢复后逐步恢复正常请求。

安全性设计

确保接口的安全性,如身份认证、权限校验和数据加密,避免数据泄露和未授权访问。

异步处理与后台任务

对于需要耗时较长的操作,可以通过异步处理或后台任务方式提高接口的响应速度。

接口参数校验(入参和出参)

接口入参和出参都需要进行校验, ① 例如入参是否不能为空,入参数据长度,入参是否符合预期规则,很多bug由于未做参数校验导致,对于可能改变的参数建议设计为对象类型;② 对于返回值,当返回值为空时是否返回为空串、空对象、空数组,需要与前端约定好。

接口扩展性考虑

在后端接口设计中,扩展性是非常重要的考虑因素。设计良好的接口应该能够适应业务需求的变化,易于扩展而不需要对现有系统做出大规模修改。

核心接口,线程池隔离

登录接口、首页数据接口、转账提现接口等,都可能使用到线程池,某些普通接口也会使用线程池,如果不做线程池隔离,普通接口出bug线程池打满,会导致登录等主要业务受到影响。

关键接口,日志打印

关键业务代码,需要打印日志进行保驾护航,在入参和出参位置或者其他关键位置,良好的日志打印具有如下好处:① 方便排查定位线上问题,划清问题责任;② 生产环境不能直接debug,必须依靠日志查问题和具体异常。

接口功能单一性原则

单一性是指接口做的事情比较单一、专一。比如一个登陆接口,它做的事情就只是校验账户名密码,然后返回登陆成功以及userId即可。但是如果你为了减少接口交互,把一些注册、一些配置查询等全放到登陆接口,就不太妥。其实这也是微服务一些思想,接口的功能单一、明确。比如订单服务、积分、商品信息相关的接口都是划分开的。将来拆分微服务的话,是不是就比较简便啦。

接口查询优化,串行改为并行

在设计一个APP首页接口时,如果它需要从多个不同的数据源获取信息(如用户信息、banner信息、弹窗信息等),通常有两种常见的调用方式:串行调用和并行调用。为了提高接口的响应速度,优化用户体验,采用并行调用是更优的选择,尤其是在这些调用之间没有依赖关系时。
并行调用允许多个请求同时执行,不必等待彼此完成。Java中的CompletableFuture可以很方便地实现这一点。

确保接口兼容性的策略

在修改老接口时,接口的兼容性是一个非常重要的考虑因素,特别是在系统已经上线并且被多个客户端使用的情况下。以下是一些确保接口兼容性的策略和最佳实践。

  1. 向后兼容性
    定义:向后兼容性指的是旧版本的客户端仍然可以正常使用新版本的接口,而不需要任何修改。
    策略:
    保持现有字段不变:不要随意修改或删除现有的字段或参数,这样可以保证旧客户端仍然能按预期工作。
    新增字段:如果需要扩展数据模型,可以新增字段或参数,但这些新增内容应该是可选的。旧客户端可以忽略这些新字段,而新客户端则可以利用它们。
    保持返回类型不变:尽量保持返回的JSON或XML结构不变,尤其是数据类型、字段名等。如果必须改变,确保新老结构兼容,或提供降级逻辑。
  2. 版本管理
    定义:当新功能或重大修改不可避免地会破坏现有客户端时,应该采用接口版本管理策略。
    策略:
    路径版本化:在URL路径中添加版本号,例如/api/v1/user和/api/v2/user。这种方式直观,客户端明确知道调用的是哪个版本的接口。
    请求头版本化:通过HTTP请求头指定版本号,例如Accept: application/vnd.company.v1+json。这种方式不会影响URL的结构。
    API网关:使用API网关进行版本管理和路由,能够更灵活地处理不同版本的接口。

调用第三方接口要考虑异常和超时处理

在调用第三方接口时,异常和超时处理是至关重要的。这些问题如果处理不当,会导致应用程序的不稳定,甚至崩溃。为了确保系统的健壮性和用户体验的稳定性,以下是一些关键的考虑和处理策略。

重试机制:在遇到网络异常时,可以尝试进行重试,通常是几次有限次数的重试。例如,可以使用指数退避算法来增加重试间隔时间,避免因频繁重试造成更多的问题。
兜底方案:如果多次重试后仍然失败,返回默认值或使用缓存中的数据,确保系统能够继续工作。

降级处理:当第三方服务异常时,提供降级服务。例如,返回一个友好的错误信息或使用本地的备用数据。
告警通知:当出现服务异常时,触发告警通知运维团队,以便快速响应。

调用第三方接口时,必须设定合理的超时时间,以避免长时间等待。
超时重试:在设定的超时时间内如果请求未完成,可以尝试重试,通常可以设置有限次重试,避免无限循环。

当某个第三方接口频繁出现异常或超时时,可以采用熔断机制,暂时停止对该接口的调用,避免对系统产生更大的影响。

日志记录:详细记录每次第三方接口调用的请求和响应信息,特别是在出现异常和超时时,确保可以进行后续的排查。
监控与报警:设置接口调用的监控指标,如成功率、平均响应时间等,当某些指标超过阈值时,立即报警通知相关人员。

接口实现过程中,注意大文件、大事务、大对象

• 读取大文件时,不要Files.readAllBytes直接读取到内存,这样会OOM的,建议使用BufferedReader一行一行来。
• 大事务可能导致死锁、回滚时间长、主从延迟等问题,开发中尽量避免大事务。
• 注意一些大对象的使用,因为大对象是直接进入老年代的,可能会触发fullGC

仔细检查代码避免出现粗心的空指针异常

空指针异常(NullPointerException)是 Java 开发中常见的错误之一。它通常发生在尝试对一个 null 对象引用进行操作时。
使用工具如 IntelliJ IDEA 的代码分析功能、SonarQube、FindBugs、Checkstyle 等,这些工具可以帮助检测可能的空指针异常问题。
在方法和构造函数中,进行参数 null 检查,抛出适当的异常。
对可能返回 null 的方法结果进行检查或处理。
对可能的参数值都进行null检查。

考虑是否存在事务失效的问题场景

• 方法的访问权限必须是public,其他private等权限,事务失效
• 方法被定义成了final的,这样会导致事务失效。
• 在同一个类中的方法直接内部调用,会导致事务失效。
• 一个方法如果没交给spring管理,就不会生成spring事务。
• 多线程调用,两个方法不在同一个线程中,获取到的数据库连接不一样的。
• 表的存储引擎不支持事务
• 如果自己try…catch误吞了异常,事务失效。
• 错误的传播特性

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【C++】单例模式的解析与应用
  • Centos7离线安装Sumo全过程(xerces-c、Cmake、gymnasium等)
  • Windows自动化3️⃣WindowsPC拽起时长问题解决方案
  • Java学习Day30:Mysql 第三章:玄阶高级斗技:八极崩!
  • 查券机器人如何提升电商返利系统的用户体验
  • Visual C++ 2010 学习版
  • Selenium实战:深度解析Python中嵌套Frame与iFrame的定位与切换技巧,解决Selenium定位不到的问题
  • 掌握Jenkins自动化部署:从代码提交到自动上线的全流程揭秘
  • 国内服务器安装Docker提示Failed to connect to download.docker.com port 443的解决方案
  • 使用 Hugging Face 和 Milvus 构建 RAG 系统
  • 机器学习——第十二章计算学习理论
  • 笔记(day21) 多线程以及锁的概念(超级完整版)
  • ASPICE标准与汽车网络安全:协同确保软件质量与系统安全
  • pycharm windows/mac 指定多版本python
  • 思科OSPF动态路由配置8
  • C++类的相互关联
  • ComponentOne 2017 V2版本正式发布
  • Phpstorm怎样批量删除空行?
  • Python3爬取英雄联盟英雄皮肤大图
  • Redux 中间件分析
  • SpingCloudBus整合RabbitMQ
  • vue--为什么data属性必须是一个函数
  • Vue学习第二天
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • - 概述 - 《设计模式(极简c++版)》
  • 工作中总结前端开发流程--vue项目
  • 老板让我十分钟上手nx-admin
  • 双管齐下,VMware的容器新战略
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 我有几个粽子,和一个故事
  • 一天一个设计模式之JS实现——适配器模式
  • 用Python写一份独特的元宵节祝福
  • 做一名精致的JavaScripter 01:JavaScript简介
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • # 移动硬盘误操作制作为启动盘数据恢复问题
  • (1)bark-ml
  • (1)Hilt的基本概念和使用
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (leetcode学习)236. 二叉树的最近公共祖先
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (阿里云在线播放)基于SpringBoot+Vue前后端分离的在线教育平台项目
  • (二)构建dubbo分布式平台-平台功能导图
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (含笔试题)深度解析数据在内存中的存储
  • (四)stm32之通信协议
  • (算法)前K大的和
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (一)kafka实战——kafka源码编译启动
  • (一)spring cloud微服务分布式云架构 - Spring Cloud简介
  • (转)scrum常见工具列表
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复