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

[Java实战]性能优化qps从1万到3万

一、问题背景

​ 事情起因是项目上springboot项目提供的tps达不到客户要求,除了增加服务器提高tps之外,作为团队的技术总监,架构师,技术扛把子,本着我不入地狱谁入地狱的原则,决心从代码上优化,让客户享受到飞一般的感觉。虽然大多数编程工作在写下第一行代码时已经完成,但本着谦虚使人进步,骄傲使人落后的原则还是一步一个脚印的把问题慢慢展开,慢慢分析。以下内容是抽丝剥茧的心路历程,请君欣赏。

二、TPS与 QPS

​ 说到性能优化就要说到高并发,说到高并发就要说到Tps和Qps。或许是小白第一次见到这个概念,但高手都是从低手走过来的,所以请高手以及高高手们,允许小人啰嗦的叙说吧!

以下是TPS(Transactions Per Second)与QPS(Queries Per Second)的核心区别及关联解析:

2.1. 定义与组成差异

  1. TPS(每秒事务数)
    • 定义:单位时间内系统完成的完整事务数量,一个事务包含从客户端请求到服务端处理并返回的全流程(例如:订单支付包含下单、扣款、生成凭证等多个操作)。
    • 组成:通常包括三个阶段:
    ◦ 客户端发起请求
    ◦ 服务端处理(含业务逻辑、数据库操作等)
    ◦ 服务端返回响应结果。

  2. QPS(每秒查询数)
    • 定义:单位时间内服务端响应的独立查询请求数量,通常指单个接口或操作的调用次数(例如:一次商品详情页查询)。
    • 组成:仅针对单一请求的响应,不涉及多步骤业务逻辑。

2. 应用场景与关系

指标 适用场景 与事务的关联性 典型示例
TPS 完整业务流程(如电商下单) 一个事务可能包含多个QPS(如支付流程涉及库存查询、支付接口调用) 支付系统需关注TPS以评估整体业务处理能力
QPS 单一接口或查询(如API调用) 单个查询可能属于某个事务的组成部分 商品搜索接口需关注QPS以优化响应速度

关系公式
• 当单事务仅包含一次查询时,TPS = QPS
• 当单事务包含多次查询时,QPS = TPS × 单事务内查询次数
• 系统整体吞吐量受限于性能最差的环节(如数据库瓶颈可能导致高QPS但低TPS)

3. 性能测试中的差异

  1. 测试目标
    • TPS反映系统处理复杂业务链路的综合能力(如银行转账事务)
    • QPS更关注接口层或服务的单点性能(如高并发下的缓存查询)

  2. 瓶颈分析
    • TPS低可能由事务中某个子环节(如第三方支付接口延迟)导致,需定位具体步骤
    • QPS低通常与服务器资源(CPU、内存)或代码效率直接相关

  3. 优化策略
    • 提升TPS:优化事务内耗时最长的环节(如数据库批量操作、异步处理)
    • 提升QPS:减少单次查询的响应时间(如索引优化、缓存命中率)

4. 总结

核心区别:TPS衡量完整业务流程的吞吐量,QPS衡量单一操作的频率。
选择依据:需根据业务场景决定主优化方向:
• 电商大促需优先保障TPS(确保订单流程不积压)
• 搜索引擎需优先优化QPS(提升单次查询效率)
关联性:两者共同构成系统吞吐量的评估体系,实际应用中常需结合分析。

​ 通过以上专业的介绍,想必各位已经知道了什么是Tps还是Qps了,如果各位还是不明白,那不能怪你们,要怪就怪小人说的太专业了。

​ 知道了客户想要的是什么,那么接下来就好办了,结合本身提供的api服务所使用的技术架构就很容易想到NIO和BIO,因为springboot项目打成jar包后是用的内嵌的tomcat,而tomcat7之前是BIO模式,sprinboot2.x内嵌的tomcat已经是8以上了,在spirngboot自动配置中,创建tomcat实例,默认启用NIO连接器。这一不小心又说的专业了,那BIO与NIO又是什么呢?对于小白来说,满脸的黑人问号,而高手只是轻轻一笑,这小伙子又在搞什么名堂,且待我慢慢看来。

三、BIO与NIO

​ 从TPS和QPS,再到BIO与NIO,各位看官辛苦了。虽然说是“书山有路勤为径,学海无涯苦作舟”,但是方法不对,努力全费,知道了需求,怎么去解决,那么了解BIO和NIO就是正确的解决之道了。

BIO(Blocking I/O)和NIO(New I/O 或 Non-blocking I/O)是两种常见的I/O模型,它们在处理网络请求和数据传输时有显著的区别,适用于不同的应用场景。

1. BIO(Blocking I/O)

  • 定义:BIO是同步阻塞I/O模型。线程在执行I/O操作时会被阻塞,直到数据准备完成。
  • 工作原理:每个连接都需要一个独立的线程来处理,线程在等待数据时无法执行其他任务。
  • 优点:实现简单,代码直观。
  • 缺点:线程资源消耗高,不适合高并发场景。
  • 适用场景:连接数较少且稳定的场景。

2. NIO(New I/O 或 Non-blocking I/O)

  • 定义:NIO是同步非阻塞I/O模型。线程在发起I/O请求后不会被阻塞,而是可以继续执行其他任务。
  • 工作原理:通过Selector(选择器)和Channel(通道)来管理多个连接。单个线程可以监听多个通道的I/O事件(如读、写、连接),从而实现高并发。
  • 优点:支持高并发,资源利用率高。
  • 缺点:编程复杂度较高,需要手动管理事件循环。
  • 适用场景:连接数多且连接较短(轻操作)的场景,如聊天服务器。

3. BIO与NIO的对比

特性 BIO NIO
阻塞模式 阻塞 非阻塞
数据处理方式 流(Stream) 块(Buffer)
核心组件 Socket/ServerSocket Channel/Buffer/Selector
并发能力 低(一线程一连接) 高(单线程多连接)
编程复杂度 简单 复杂

4. 应用领域

  • BIO:适用于低并发、简单应用场景,如内部工具或原型验证。
  • NIO:适用于高并发、实时通信场景,如API网关、聊天服务。

总结来说嘛,BIO和NIO各有优缺点,选择合适的I/O模型需要根据实际的业务需求和并发场景来决定。

​ 知道了目前已经是NIO模式了,那么怎么增加性能呢,换个语言不就得了,换个c吧,c是世界上最好的语言,嗯,是个不错的选择,换go吧,go是世界上最好的语言,嗯,这个也不错。想的都对,但还是用Java,Java是世界上最好的语言。

于是在一番思索后,依旧使用Java,因为 gRPC 实现依赖了netty,所以netty应该能满足客户的需求,那接下来就是见证奇迹的时刻, “实践是检验真理的唯一标准” ,是骡子是马是时候该拉出来溜溜了。

四、Netty方案

在薅掉十几根头发后,终于写出了这个替代方案,代码如下:

package com.example.demo;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import 

http://www.kler.cn/a/586218.html

相关文章:

  • 分布式事务管理:使用Seata简化微服务事务处理
  • vue3 中使用 Recorder 实现录音并上传,并用Go语言调取讯飞识别录音(Go语言)
  • 【环境问题】Vscode上ssh无法连接问题汇总
  • 用Java来创建数字游戏
  • HedgeAgents:开启金融交易新纪元的平衡系统
  • 微信小程序面试内容整理-JavaScript
  • HarmonyOS NEXT - 电商App实例四(登录界面)
  • Qt:绘图API
  • 20250314-vue-Props3
  • Free QWQ - 世界首个免费无限制分布式 QwQ API
  • Milvus 中常见相似度度量方法
  • 考研复习,主动学习”与“被动接收”的结合之道
  • Android自动化测试工具
  • 高级java每日一道面试题-2025年2月26日-框架篇[Mybatis篇]-Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式 ?
  • linux 下 ohmyzsh,miniconda 全局安装
  • 本地化语音识别CapsWriter结合内网穿透远程会议录音秒变文字稿
  • Java高频面试之集合-11
  • Day08 实例:3个网站实例探究算法对于密文加密的影响
  • Kafka 消费者组的重平衡
  • 深度学习优化-Gradient Checkpointing