提升后端API性能的几种解决方案

🔔目的

提升后端API性能的主要目的是为了提高系统整体的响应速度、并发能力以及可用性。主要原因包括:

  1. 提高用户体验

    后端API性能好可以减少响应延迟,给用户流畅的体验。

  2. 提高系统吞吐量

    优化API性能可以提高系统的整体吞吐量,处理更多用户请求。

  3. 节省服务器资源成本

    优化API提高资源利用率,减少对计算、内存、网络等资源的占用。

  4. 提高系统稳定性

    良好的API性能可以防止请求积压造成的链路阻塞,减少超时、服务降级等问题。

  5. 促进业务发展

    性能良好的API可以支撑更复杂的业务场景,为产品迭代和业务增长提供保障。

  6. 提升运维效率

    代码和架构优化可以降低重复工作量,减少故障排查时间。

  7. 增强系统容错能力

    优化后可以应对更大的流量冲击和失效情形。

🔔优化概述

  1. 代码优化

    通过算法优化、减少IO等方式优化程序,使其高效运行。

  2. 缓存使用

    通过Redis、Memcache等缓存数据库缓存常用数据,减少数据库查询。

  3. CDN加速

    使用CDN缓存静态资源,减少服务器压力。

  4. 异步处理

    通过消息队列、事件驱动等方式实现异步处理,提高并发能力。

  5. 服务拆分

    将服务拆分为小的单元服务,采用微服务架构。

  6. 流量控制

    通过限流、降级等方式控制流量并保护服务稳定运行。

  7. 数据库优化

    优化数据库模式,使用索引、读写分离等技术提升数据库效率。

  8. 并发优化

    通过线程池、非阻塞IO等方式提升系统并发性能。

  9. 服务器扩容

    垂直扩容服务器或利用云服务横向扩容,增强处理能力。

🔔具体实践

  • 线程池化

    池化技术(Pooling)的关键思想就是重用,其目的是为了避免每次需要资源时都要重复创建和销毁,从而提高性能和资源利用率。
    以数据库连接池为例,不使用连接池的时候,每次操作数据库都需要:

    1. 创建数据库连接
    2. 执行sql语句
    3. 关闭数据库连接

    这样重复创建和关闭连接会非常耗费资源。
    而引入连接池后,可以提前创建好一定数量的连接,放入连接池待用。需要时直接从池中取出已有连接使用,操作完毕再放回池中,而不需要重复创建连接。
    同样,线程池也是提前创建线程,组成线程池待用,需要时直接派一个空闲线程执行任务,从而避免了频繁创建和销毁线程的资源消耗。
    池化技术重在提高资源的重复利用率。目的是为了提高性能,减少不必要的性能开销。现在几乎所有的连接资源都会使用池化技术进行管理。

  • 批量入库

    对于需要批量插入或者更新到数据库的操作,可以先批量处理逻辑完之后再统一一次性插入数据库,这样做的优势在于

    1. 减少网络交互,提高写入效率

      向数据库批量插入可以减少客户端与数据库之间的网络往返。

    2. 可以对数据进行预处理。

      可以在入库前对数据进行过滤、转换等优化。

    3. 减少索引更新开销

      可以关闭索引,批量插入后再重建索引,从而减少索引更新带来的开销。

    4. 可以执行更复杂的SQL逻辑。

      批处理可以构建更复杂的SQL逻辑完成数据导入。

    5. 提高数据库并发能力。

    批量写入可以聚合成少量大事务,可以减少数据库并发Transaction的数量。

  • 异步执行

    在设计接口时,对于一些非核心业务逻辑,如果这部分逻辑执行时间长且不影响主业务流程,我们可以考虑“异步”执行这些逻辑。
    具体来说,可以通过以下技术方案实现:

    1. 使用消息队列,让主业务逻辑快速返回,将非核心逻辑作为消息放入队列异步执行。

    2. 设计异步线程或定时任务,在主线程返回后,异步线程负责后台执行非核心逻辑。

    3. 利用事件编程模型,主业务逻辑触发事件,事件监听者异步响应事件执行非核心逻辑。

    4. 非核心逻辑作为微服务单独部署,主业务快速调用微服务,微服务后台异步执行逻辑。

    5. 使用reactor模式,主线程接收请求触发非核心逻辑,再通过多线程异步执行非核心处理。

    常见的异步有:

    • 多线程 - 在新线程中执行异步任务,主线程不等待异步线程结束即返回。
    • 事件/回调 - 主线程注册回调,异步任务完成后由系统调用回调函数,通知主线程。
    • Future/Promise - 主线程返回一个future对象,异步线程设置future的结果,主线程可以获取future的结果。
    • Reactor模式 - 基于事件循环的模型,主线程接收请求,dispatch事件给异步线程池处理。
      -消息队列 - 主线程产生消息,通过消息队列进行异步处理。如 RabbitMQ, Kafka。
    • Observable - 主线程注册Observer,由Observable异步调用Observer的回调方法。如 RxJava。
    • Async/Await - 使用async标记的函数自动异步执行,await可以等待异步函数结果。
    • 协程 - 可以手动控制协程的切换,实现异步处理。如Goroutine。
  • 使用缓存

    恰当地使用缓存,可以大大的提升接口的性能。

    使用缓存的主要好处有:

    1. 减少数据库查询,降低后端负载
      缓存可以存储热点数据,减少对数据库的查询,降低后端存储系统的压力。

    2. 加速读取速度
      从缓存读取数据比数据库查询要快得多,可以显著提高访问速度。

    3. 改善用户体验
      加速系统响应,用户会感受到更流畅的用户体验。

    4. 提高系统扩展能力
      缓存层可以作为数据库前的缓冲层,让系统支持更高的负载。

    5. 降低基础设施成本
      减少存储系统扩容提升需求,降低整体IT成本。

    6. 保护核心数据系统
      缓存可充当外部系统与核心存储之间的屏障。

    7. 帮助实现高可用性
      缓存可作为备份数据源,在主数据源不可用时提供冗余数据访问。

    常见的缓存有:

    • Redis - 基于内存的键值缓存,支持多种数据结构,性能极高。

    • Memcached - 简单的内存键值缓存,没有Redis丰富的数据结构。

  • 慢查询优化

    可以从以下几点优化:

    1. 数据库结构优化
      • 合理设计表结构,避免冗余数据。
      • 对于高并发修改的字段,拆分到单独表中。
      • 对访问频繁的列建立索引。
    2. SQL语句优化
      • 尽量避免全表扫描,先通过索引字段过滤数据。
      • 避免在索引列上做函数转换。
      • 对多个表Join时,保证Join条件列有索引。
      • 合理利用慢查询日志分析和调优查询。
    3. 数据库参数优化
      • 调整max_connections、table_open_cache等系统变量。
      • 调整innodb_buffer_pool_size、innodb_log_file_size等InnoDB存储引擎参数。
    4. 架构优化
      • 对热点数据进行缓存。
      • 对可读数据库使用主从复制分离读写。
      • 拆分数据库,分散压力。
      • 使用索引代替Join查询。
    5. 程序优化
      • 避免N+1问题,使用Join提前预加载关联数据。
      • 避免频繁小请求数据库,可以批处理或异步处理。
  • 锁粒度避免过粗

    在设计并发程序时,使用锁(mutex)来保护共享资源,但锁的范围不能设计得过于宽泛,这称为锁的粒度问题。
    过粗的锁粒度意味着锁的范围过于宽泛,例如对整个应用只有一把大锁。这会带来以下问题:

    1. 锁争用过于频繁,并发程度低

    2. 可能会发生死锁

    3. 锁的获取和释放频繁上下文切换,性能消耗严重

    因此需要注意锁粒度的选择:

    1. 只在访问共享资源时加锁,不要锁住无关代码

    2. 可以将一个大锁拆分为多个细粒度的锁

    3. 根据代码逻辑设计锁的范围,避免锁过多或过少

    4. 不同的线程访问不同资源应该用不同的锁

    示例

    private void A(){
    }//共享方法
    private void B(){
    }private int C(){synchronized(this){A();B();}
    }
    

    修改为

    private void A(){
    }//共享方法
    private void B(){
    }private int C(){A();synchronized(this){B();}
    }
    
  • 串行改并行

    在设计程序时,原本采用了串行逻辑,即一个任务完成后再执行下一个任务。这种模型导致任务只能顺序执行,整体吞吐量受到限制。
    为提高吞吐量,可以考虑将程序逻辑改为并行执行。具体做法是:

    1. 把任务进行拆分,同一类任务使用多个实例并行地执行。
    2. 对于需要顺序的任务,可以使用消息队列将任务异步化,提高并行程度。
    3. 对串行的业务流程进行重构,看哪些环节可以通过多线程、异步来并行执行。
    4. 对串行访问的共享资源,使用锁或CAS算法来控制并发访问。
    5. 使用线程池、actor模型等并发框架,提高程序对多核CPU的利用率。
      通过程序逻辑从串行改为并行,可以显著提升系统整体的吞吐量和处理能力。需要注意资源竞争和死锁等并发问题。适当保留关键串行流程来实现正确性。

    比如 串行

    1111725d79c854c85d6e8937c10a304

    改成

    并行

    image-20231010170351945

🔔写在最后

如果大家对相关文章感兴趣,可以关注公众号"架构殿堂",会持续更新AIGC,java基础面试题, netty, spring boot, spring cloud等系列文章,一系列干货随时送达!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/154361.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入理解强化学习——强化学习和有监督学习

分类目录:《深入理解强化学习》总目录 通过前文的介绍,我们现在应该已经对强化学习的基本数学概念有了一定的了解。这里我们回过头来再看看一般的有监督学习和强化学习的区别。以图片分类为例,有监督学习(Supervised Learning&…

利用Python构建自定义报告生成器支持SEO分析实战总结

在进行SEO(搜索引擎优化)分析时,定制化的报告生成器是非常有价值的工具之一。通过利用Python编程语言构建自定义报告生成器,可以更好地满足个性化的需求,并提供详尽的SEO分析结果。本文将分享一些实践经验,…

3、在 CentOS 8 系统上安装 PostgreSQL 15.4

PostgreSQL,作为一款备受欢迎的开源关系数据库管理系统(RDBMS),已经存在了三十多年的历史。它提供了SQL语言支持,用于管理数据库和执行CRUD操作(创建、读取、更新、删除)。 由于其卓越的健壮性…

对比纯软开与嵌入式硬件开发谁更好呢?

对比纯软开与嵌入式硬件开发谁更好呢? 你的纠结和犹豫是理解的,职业选择确实是一个重要的决策。我明白你在嵌入式和软件开发之间犹豫不决的原因。让我给你提供一些建议,帮助你做出更明智的决定。最近很多小伙伴找我,说想要一些嵌入…

MySQL对日期计算

mysql日期计算 前言使用场景一 日期作减法操作二 获取前一天或后一天的日期三 获取前一个月或后一个月的日期四 获取前一年或后一年的日期五 查询一个月内的申请记录 总结 前言 在MySQL中,日期计算是非常常见的操作。其中,日期减法操作可以用来计算两个…

Springboot接收http参数总结(最简单易懂)

1. 前端能携带请求参数的地方 http请求一半前端请求参数放在三个地方:请求头,请求查询参数(Query String),请求体。 请求体需要获取HttpServletRequest对象才能获取。 2. 请求体常见格式 而请求体中可以存放多种格式…

Springboot 订餐管理系统idea开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot 订餐管理系统是一套完善的信息系统,结合springboot框架和bootstrap完成本系统,对理解JSP java编程开发语言有帮助系统采用springboot框架(MVC模式开发),系统具有 完整的源代码和数据库&…

大数据与Hadoop入门理论

一、大数据的3种数据类型 1、结构化数据 可定义,有类型、格式、结构的强制约束 如:RDBMS(关系型数据库管理系统) 2、非结构化数据 没有规律没有数据约束可言,很复杂难以解析 如:文本文件,视…

02 认识Verilog HDL

02 认识Verilog HDL ‍ 对于Verilog的语言的学习,我认为没必要一开始就从头到尾认真的学习这个语言,把这个语言所有细节都搞清楚也不现实,我们能够看懂当前FPGA的代码的程度就可以了,随着学习FPGA深度的增加,再不断的…

Axure RP 9 for Mac(原型设计软件)中文正式版

Axure RP 9 是一款流行的原型设计和线框图软件,允许设计人员和开发人员为网站和移动应用程序创建交互式动态原型。它提供了一整套用于创建交互式设计的工具和功能,包括拖放小部件、条件逻辑、动态内容和动画。 软件下载:Axure RP 9 for Mac中…

2023版 STM32实战7 通用同步/异步收发器(串口)F103/F407

串口简介和习惯 -1-通用同步异步收发器 (USART) 能够灵活地与外部设备进行全双工数据交换,满足外部设备对工业标准 NRZ 异步串行数据格式的要求。 -2-硬件流控制一般是关闭的 -3-波特率指单位时间传输bit个数 -4-数据位一般是8位 -5-一般无校验位 编写代码思路 -1-参…

Java架构师高并发架构设计

目录 1 导学2 什么是高并发问题3 高并发处理之道4 akf扩展立方体5 细化理念应对高并发5 总结1 导学 本章的主要内容是大型系统架构设计的难点之一,高并发架构设计相关的知识落到实际项目上,就是订单系统的高并发架构设计。我们首先会去学习到底何为高并发问题,先把问题搞清楚…

神经网络中卷积和池化的区别

1、什么叫卷积? 卷积层是用一个固定大小的矩形区去席卷原始数据,将原始数据分成一个个和卷积核大小相同的小块,然后将这些小块和卷积核相乘输出一个卷积值(注意这里是一个单独的值,不再是矩阵了)。 卷积的…

【RabbitMQ 实战】10 消息持久化和存储原理

一、持久化 1.1 持久化对象 rabbitmq的持久化分为三个部分: 交换器的持久化。队列的持久化。消息的持久化。 1.1.1 交换器持久化 交换器的持久化是通过在声明交换器时, 指定Durability参数为durable实现的。若交换器不设置持久化,在rabb…

C++11 Thread线程库的使用

C11 Thread线程库的使用 传统的C(C11标准之前)中并没有引入线程这个概念,在C11出来之前,如果我们想要在C中实现多线程,需要借助操作系统平台提供的API,比如Linux的,或者windows下的 。 本文详细…

PPT课件培训视频生成系统实现全自动化

前言 困扰全动自化的重要环节,AI语音合成功能,终于可以实现自动化流程,在此要感谢团队不懈的努力和韧性的精神! 实现原理 请参照我的文章《Craneoffice云PPT课件培训视频生成系统》 基本流程 演示视频 PPT全自动 总结 过去实…

常见弯道输送机有哪些

提到弯道输送机您可能首先想到的就是弯道滚筒线,其实除了滚筒线之外,也有一些其他线体可以做弯道,下面就为您总结了4种常见的弯道输送机。 1、弯道皮带线:即线体转弯处设计成皮带输送机,这种形式的转弯设计可以实现不同…

如何在 Spring Boot 中进行文件上传

在 Spring Boot 中进行文件上传 文件上传是Web应用程序中常见的功能之一,它允许用户将文件从客户端上传到服务器。Spring Boot提供了便捷的方式来处理文件上传,并且整合了Spring框架的强大功能,使文件上传变得相对简单。本文将介绍如何在Spr…

【PPT制作】基础篇

文章目录 一、PPT制作必要的基础设置1.1 自动保存1.2 字体嵌入1.3 撤销步数1.4 图像大小和质量 二、必备快捷键三、设计四原则四、总结 ヾ(๑╹◡╹)ノ" 没有坚持的努力,本质上并没有多大意义ヾ(๑╹◡╹)ノ" 一、PPT制作必要的基础…

面对研究生粉丝机器视觉择业问题-视觉人机器视觉寄语

机器视觉是有门槛,他是一门综合学科。对基础课程的知识点有一定的需求,对于后来者​肯定没有一定储备,肯定要要进一步加深学习的。 人不吃饭,真的会饿死的。无论谁想学习机器视觉,我第一个劝导的是尽快就业。工作经验过…