讲个故事:关于一次接口性能优化的心里路程
这是一个程序猿写的第一个故事,请各位懂行的客官静下心来,慢慢品读。就知道我为什么要单独写一个文章来记录这次过程了,因为实在是太坎坷了......
背景介绍
近期项目投产时遇到一个问题,投产后在验证时发现大部分用户系统登录非常慢。由于没有找到具体原因。只能回退到投产前的版本。
后来通过分析生产的日志,发现是登录接口中有段代码涉及到频繁切换数据源,这段代码耗时比较长。
到这里我先简单说下项目,用到oracle和gbase数据库,oracle数据库和业务相关,gbase数据库主要用来存在一些日志的。默认数据源是oracle。项目的一个filter里会把所有请求后台接口的相关信息记录在gbase库中,另外登录接口也会把登录成功与否的情况也记录在gbase库。
比较耗时的代码就是登录接口有两处分别向gbase库不同表写日志,每次都需要先切换到gbase,写完要切回oracle数据源,而且这2个逻辑紧挨着。所以这里就会4次切换数据源。本次投产增加了其中一次向gbase写库,还有就是本次投产filter向gbase写库的逻辑。
到这里,基本所有背景交代完了。我先把这次投产向gbase写库的代码注释了。发现登录耗时确实下来了。通过工具性能压测响应时间下来了,但是tps非常低,不到10。这个接口优化路程才真正开始了.........
#排查过程#
第一季:老子代码没问题,怀疑网络节点限流
我们去掉了一次想gbase写库的逻辑,也就减少了2切换数据源,还剩一次原代码就保留的写gbase库。但是发现这个写gbase还是比较耗时,大概900ms左右,其他业务代码耗时200ms。我就加了线程池,把写gbase库的逻辑放到线程里,包括2次切换数据源。按理说这时候tps会提升不少,结果出人意料,tps还不到10.还是很低。(这里压测的都是测试环境的登录接口。并发量分别50、100、150)测试人员各种并发量压测,tps都是非常低。
到这里开始怀疑不是代码问题,是不是pod之外的网络节点(比如F5)做了限制。为了验证这个想法我让测试人员在测试环境压测健康检查的接口,健康检查接口非常简单,没有数据库交互,直接返回固定的字符串。竟然发现这个健康检查接口压测的tps也是不到10。这更坚定了我猜测的中间网络节点限流了。健康检查接口的tps都不到10,这肯定是网络节点限流了啊。
后来通过找相关人员,得到结论F5没有限制任何请求。我靠,奔溃了,那问题在哪啊??????
这时突然想起,以前的一个同事给项目在filter加过一个流控。(好像发现了新大陆),经过了解这个流控的阈值 是每秒请求1000。我们的还不到10呢,人家流控肯本限制不了我们,但是还是不死心,把流控的代码逻辑注释了,果然tps还是很低,和流控没有任何关系.........
第二季:压测本地健康检查接口,发现代码猫腻
网络节点没问题,流控没问题。说真的不知道是哪里出问题了。一个简单的健康检查接口都tps不到10。怎么才能排除是不是网络节点的问题呢?压测我本地代码,同时把filter的流控的逻辑注释了,还是压测健康检查接口。结果是tps还是非常低不到10。
完犊子了,这个tps就跨不过10了吗?
由于被压测结果震惊了,却忽略了这次压测测试的目的是什么?直接压测我本地,tps还很低,这中间可没有了任何网络节点,流控也注释了,那只能是我代码问题了。只要找到方向,那就好说了,虽然具体原因还是不清楚。
上次投产回退的代码,我在filter里加了向gbase写日志的逻辑,难道、或许,应该是这里出问题了吧。那这个好办,把filter里写gbase的逻辑放到线程池里完成,你在耗时去子线程里耗时去吧,别干扰我主线程。
修改代码后,继续让测试人员压测我本地的健康检查接口。
结果呢?结果就是tps还是不到10。我当时就原地石化了.........
第三季:成也线程池,败也线程池
程序猿轻易不言败,我们就是踩不死的小强。
我放了个大招,把filter里写gbase库的逻辑注释了,继续压测我本地健康检查接口。奇迹终于出现了,tps到了190左右。这就不对了,为什么线程池没解决问题呢?我用的线程是实现了Callable,我们都知道这个线程有返回值。我们可以获取每个线程的返回结果。但是我们记录日志,不需要等待返回结果。我就换了一种实现方法,就是实现Runable接口,这个线程就是不会返回结果。(这里只讲故事,不讲技术啊,我就不帖想代码了,如果还有不了解这些的小伙伴,可以参考我以前的关于线程池的文章,关于线程池我写过好几篇文章,其中一篇是:ThreadPoolExecutor线程池详解)
把线程池相关逻辑更改后,压测本地健康检查接口,tps终于上来了,到达200左右。既然找到问题了,就继续优化我的登录接口,把写gbase库的逻辑放到线程里,以前登录接口的线程也是实现Callable接口,都改成实现Runable接口,奶奶滴,以前还真不知道,这两种写法差别这么大。说实话这块的知识点,还真不知道,以前只知道,要想得到线程执行结果用Callable,不需要线程结果用Runable。我就想了反正都是线程,用哪个不是用,就用Callable呗,万一以后领导想要每个线程执行结果呢?毕竟领导脑袋里想啥,我们有不知道。跑偏了,我们继续讲故事,不吐槽领导了
登录结果代码的线程池优化后,继续压测我本地的登录接口的tps到155了,这个完全可以满足我们的业务需求了。毕竟是内部系统,没那么大请求量。
然后就是在测试环境验证,测试环境压测登录接口,50并发情况下,tps到190左右,嗯,还不错,就是偶尔测试环境会慢........
各位看官,是不是认为到这里就结束了,因为解决了登录慢问题,tps也上来了嘛。嗯,我也是这么认为的,就这样我们就投产了。。。。。
第四季:忽略小细节,造成大隐患
路漫漫其修远兮,吾将上下而求索!信心满满,经过这段时间折腾,终于解决了这个问题。终于可以投产了.......啦啦啦啦啦
然而,现实很残酷,没想到打脸来的如此之快,脸打的如此之响!!!!我们又双叒叕投产失败,回退了..........啊啊啊啊啊。
这次投产后,登录是没问题,不慢了,就是登录系统后,首页的某些特定操作比较慢,其他的大部分功能都正常。这就很奇怪,如果说我这次优化失败了,测试环境没问题,就是生产也是就某些操作慢而已嘛,怎么是我代码问题呢,绝对不是。当然这是我内心的想法。
后来发现,慢的操作的接口里有写gbase库,什么这里也写gbase库?
后来想想,写也没事啊,gbase是本来就是大数据的应用场景,TB级别的数据查询库比oracle快多了。反正就是内心深处不认为是我代码问题,这是不是程序猿的通病啊.......
通过分析生产的日志发现,filter里大部分线程写gbase库的耗时达到了23s左右(幸亏我当时在线程里记录了耗时情况,看了多打印日志还是比较好的,要不这次问题很难发现)。那问题就明朗了,gbase不抗揍啊。
这里再简单交代下项目,系统登录后,首页加载会调用大概20多个后端接口获取数据,如果刚投产成功,会存在好多用户登录验证功能,一个用户登录后就调20个接口,如果是50个用户同时登录,就是1000次调用后台接口,这时filter就会同时写gbase库1000次。所以登录后其他操作涉及到写gbase库的都比较慢。
这时候我突然想到测试环境压测时,偶尔会出现某些操作比较慢,由于我们的关注点一直在登录接口的tps上,把这个忽略了。还有个关键点,就是我们在测试环境压测,是在晚上加班时压测的,这时间点用我们系统的人少,也没人反应,只是测试人员登录测试环境发现的,也是偶然现象,因为并不是所有操作都慢嘛,只有涉及的写gbase库的操作才会慢。也就没有当回事。
通过这次发现gbase和oracle的区别。打个比喻吧。oracle和gbase是2个剑客高手。
oracle剑客的优点是,面对众多对手都是小卡拉米、菜鸟时,得心应手。但是对手中有几个高手,那oracle就不行了。
gbase剑客的优点是,对手是多个和自己水平一样的高手,这能轻松应对。但是对手是一群菜鸟,那gbase就难应付了。
注:这里得小卡拉米、菜鸟指的是每次和数据库交互的数据量大小。
最后终结
故事到目前为止算是讲完了,还是做个总结吧。
第一,线程池那块知识还是掌握不牢固,比如这次Runable和Callble的两个接口,除了线程有无返回值的区别,前者的tps比后者要高的。
第二,在进行某个接口压测时,一定要站在全局考虑,是否数据库能抗住,是否会影响项目其他功能使用。
第三,就是不要对自己写的代码太自信了。。。。。。。
哈哈,细心的人是不是发现了,你问题没解决啊!由于业务其他原因,我们暂时把filter里和登录接口中写gbase的日志逻辑先注释了。
虽然领导说先不记录日志了,但是我还想研究下,在向gbase记录日志的情况下,怎么解决现在的问题。这里就给大家留下猜测吧,我后续在把以后的故事发展在补充上。
有人会问,为什么今天不写完呢?因为我们今天也投产,就是把相关写gbase逻辑的代码注释了,当然还有其他功能投产。各位保佑我这次投产顺利吧,都回退2次了,在回退就拜拜了
相关文章:
讲个故事:关于一次接口性能优化的心里路程
这是一个程序猿写的第一个故事,请各位懂行的客官静下心来,慢慢品读。就知道我为什么要单独写一个文章来记录这次过程了,因为实在是太坎坷了...... 背景介绍 近期项目投产时遇到一个问题,投产后在验证时发现大部分用户系统登…...
Centos7升级到openssh9.9
openssh9.9 是2024.9.20出的最新版ssh。因为客户扫描出一大堆centos7的漏洞,全是这个openssh的,好多补丁,所以索性升级到最新版。 需要自己制作rpm包,这个我是不懂,照这个来: Linux服务器升级openssh9.9最…...
使用 STM32F407 串口实现 485 通信
准备工作 了解485通信基本概念与原理:RS485通信详解_485通讯de接什么口-CSDN博客 安装编译软件:keil uVision 5.6 软件资料:STM32CubeF4 固件包,正点原子RS485通信例程 参考视频:第26讲 基础篇-新建H…...
基于NERF技术重建学习笔记
NeRF(Neural Radiance Fields)是一种用于3D场景重建的神经网络模型,能够从2D图像生成逼真的3D渲染效果。它将场景表征为一个连续的5D函数,利用了体积渲染和神经网络的结合,通过学习光线穿过空间时的颜色和密度来重建场…...
webView 支持全屏播放
webView 支持全屏播放 直接上代码 public class CustomFullScreenWebViewClient extends WebChromeClient {WebView webView;Context context;/*** 视频全屏参数*/protected static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS new FrameLayout.LayoutParams(ViewG…...
QGIS之三十二DEM地形导出三维模型gltf
效果 1、准备数据 (1)dem.tif (2)dom.tif 2、qgis加载dem和dom数据 3、安装插件 插件步骤可以参考这篇文章 QGIS之二十四安装插件 安装了Qgis2threejs插件,结果...
【python爬虫】携程旅行景点游客数据分析与可视化
一.选题背景 随着旅游业的快速发展,越来越多的人选择通过互联网平台预订旅行产品,其中携程网作为国内领先的在线旅行服务提供商,拥有大量的旅游产品和用户数据。利用爬虫技术可以获取携程网上各个景点的游客数据,包括游客数量、游…...
python实现onvif协议下控制摄像头变焦,以及融合人形识别与跟踪控制
#1024程序员节 | 征文# 这两天才因为项目需要,对网络摄像头的视频采集以及实现人形识别与跟踪技术。对于onvif协议自然起先也没有任何的了解。但是购买的摄像头是SONY网络头是用在其他地方的。因为前期支持探究项目解决方案,就直接拿来做demo测试使用。 …...
【Vue】Vue3.0(十四)接口,泛型和自定义类型的概念及使用
上篇文章: 【Vue】Vue3.0(十三)中标签属性ref(加在普通标签上、加在组件标签上)、局部样式 🏡作者主页:点击! 🤖Vue专栏:点击! ⏰️创作时间&…...
【C++】红黑树万字详解(一文彻底搞懂红黑树的底层逻辑)
目录 00.引入 01.红黑树的性质 02.红黑树的定义 03.红黑树的插入 1.按照二叉搜索树的规则插入新节点 2.检测新节点插入后,是否满足红黑树的性质 1.uncle节点存在且为红色 2.uncle节点不存在 3.uncle节点存在且为黑色 04.验证红黑树 00.引入 和AVL树一样&am…...
开源FluentFTP实操,操控FTP文件
概述:通过FluentFTP库,轻松在.NET中实现FTP功能。支持判断、创建、删除文件夹,判断文件是否存在,实现上传、下载和删除文件。简便而强大的FTP操作,提升文件传输效率。 在.NET中,使用FluentFTP库可以方便地…...
论文解读 | ECCV2024 AutoEval-Video:一个用于评估大型视觉-语言模型在开放式视频问答中的自动基准测试...
点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入! 点击 阅读原文 观看作者讲解回放! 作者简介 陈修元,上海交通大学清源研究院硕士生 概述 总结来说,我们提出了一个新颖且具有挑战性的基准测试AutoEvalVideo,用于全…...
postgresql14主从同步流复制搭建
1. 如果使用docker搭建请移步 Docker 启动 PostgreSQL 主从架构:实现数据同步的高效部署指南_docker安装postgresql主从同步-CSDN博客 2. 背景 pgsql版本:PostgreSQL 14.13 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4…...
企业信息化管理中的数据集成方案:销售出库单对接
企业信息化管理中的数据集成方案:销售出库单对接 销售出库单旺店通→金蝶:高效数据集成案例分享 在企业信息化管理中,数据的高效流动和准确对接是实现业务流程自动化的关键。本文将聚焦于一个具体的系统对接集成案例:如何将旺店通…...
3.cpp基本数据类型
cpp基本数据类型 1.cpp基本数据类型 1.cpp基本数据类型 C基本数据类型和C语言的基本数据类型差不多 注意bool类型:存储真值 true 或假值 false,C语言编译器C99以上支持。 C语言的bool类型:要添加 #include <stdbool.h>头文件 #includ…...
MCK主机加固与防漏扫的深度解析
在当今这个信息化飞速发展的时代,网络安全成为了企业不可忽视的重要议题。漏洞扫描,简称漏扫,是一种旨在发现计算机系统、网络或应用程序中潜在安全漏洞的技术手段。通过自动化工具,漏扫能够识别出系统中存在的已知漏洞࿰…...
《软件估算之原始功能点:精准度量软件规模的关键》
《软件估算之原始功能点:精准度量软件规模的关键》 一、软件估算的重要性与方法概述二、原始功能点的构成要素(一)数据功能(二)事务功能 三、原始功能点的估算方法(一)功能点分类估算࿰…...
序列化与反序列化
序列化和反序列化是数据处理中的两个重要概念,它们在多种场景下都非常有用,尤其是在分布式系统、网络通信、持久化存储等方面。下面是对这两个概念的详细解释: 序列化(Serialization) 定义:序列化是将对象…...
安装nginx实现多ip访问多网站
[rootlocalhost ~]# systemctl stop firewalld 关防火墙 [rootlocalhost ~]# setenforce 0 关selinux [rootlocalhost ~]# mount /dev/sr0 /mnt 挂载点 [rootlocalhost ~]# dnf install nginx -y 安装nginx [rootlocalhost ~]# nmtui 当前主机添加多地址 [rootlocal…...
每日回顾:简单用C写 冒泡排序、快速排序
冒泡排序 冒泡排序(Bubble Sort)是一种简单的排序算法,它通过重复遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复进行直到没有再需要交换,也就是说该数列已…...
前端_007_Axios库
文章目录 配置响应结构拦截器 引入: 官网: https://www.axios-http.cn/ 一句话简介:浏览器里基于XmlHttpRequests,node.js里基于http模块封装的网络请求库,使用非常方便 //通用例子axios({method:post,url: request…...
NAND FLASH 与 SPI FLASH
面试的时候再有HR针对从数据手册开始做,直接说明:例如RK3588等高速板设计板都有设计指导书,基本把对应的DDR等型号和布局规范都说明,或者DCDC电路直接给一个典型设计原理图,或者BMS更加经典,原理图给的是最…...
QTCreator打不开双击没反应
问题描述 双击后进程里显示有,当过几秒直接消失 解决 找到C\用户\AppData\Roaming\QtProject,删除目录下QtCreator.ini文件(这会重置QtCreator的默认设置),再打开QtCreator时会自动生成对应于默认设置的QtCreator.ini文件&…...
vue npm run ...时 报错-系统找不到指定的路径
vue项目修改时,不知道那一步操作错误了,运行npm run …时报错 系统找不到指定的路径,对此进行记录一下! 解决方法: 1、执行 npm install 命令,重新下载模块 2、根据下方提示执行 npm fund 查看详细信息 …...
54页可编辑PPT | 大型集团企业数据治理解决方案
这份PPT是关于大型集团企业数据治理的全面解决方案,它详细介绍了数据治理的背景、需求、管理范围、框架、解决思路,以及数据治理在实际操作中的关键步骤。内容涵盖了数据架构、数据质量、数据应用等方面的问题,并提出了数据资产透视、智能搜索…...
STM32嵌入式移植GmSSL库
前言 最近在做一个换电柜的项目,需要和云端平台对接json协议,由于服务端规定了,需要采用sm2 sm3 sm4用来加密。在嵌入式方面只能用北京大学的GmSSL了。 下载GmSSL 在https://github.com/guanzhi/GmSSL下载库 也可以通过git命令下载&#x…...
【mod分享】极品飞车10高清模组,,全新道路,全新建筑,高清植被,全新的道路围栏,全新的天空,画质直逼极品飞车20。支持光追
各位好,今天小编给大家带来一款新的高清重置魔改MOD,本次高清重置的游戏叫《极品飞车10卡本峡谷》。 《极品飞车10:卡本峡谷》该游戏可选择四个模式:生涯、快速比赛、挑战赛、多人连线游戏模式(已不可用)&…...
使用U-KAN训练自己的数据集 — 医疗影像分割
<U-KAN Makes Strong Backbone for Medical Image Segmentation and Generation> U-Net已成为各种视觉应用的基石,如图像分割和扩散概率模型。虽然通过整合变压器或mlp引入了许多创新设计和改进,但网络仍然局限于线性建模模式以及缺乏可解释性。为了应对这些挑战,受到…...
游戏盾在防御DDoS与CC攻击中的作用与实现
随着网络游戏的普及和发展,DDoS(分布式拒绝服务)攻击和CC(Challenge Collapsar)攻击成为了游戏服务器面临的主要威胁之一。游戏盾作为一种专门针对游戏行业设计的防御解决方案,能够在很大程度上减轻甚至消除…...
为什么说红帽认证(RHCE)是网络工程师的万金油证书?
在网络工程师圈子里,大家都知道考证的重要性,但面对一堆琳琅满目的认证,你可能会疑惑到底哪个证书含金量高、适用面广? 如果你问我,红帽认证(RHCE)绝对是当之无愧的“万金油”证书,…...
网站建设 厦门/深圳网络营销软件
文章转载地址https://www.cnblogs.com/jiafuwei/p/5699091.html感谢作者。 mysql距离计算,单位m,以及排序 lon 经度 lat 纬度 一般地图上显示的坐标顺序为,纬度在前(范围-90~90),经度在后(范…...
wordpress 开发视频/湖南网站建设推广
logging 用法1. 初始化 logger logging.getLogger("endlesscode"),getLogger()方法后面最好加上所要日志记录的模块名字,后面的日志格式中的%(name)s 对应的是这里的模块名字2. 设置级别 logger.setLevel(logging.DEBUG),Logging中有NOTSET &…...
外贸seo是什么/登封网站关键词优化软件
2019独角兽企业重金招聘Python工程师标准>>> Cadvisor有三种方式运行,实现方法各不同: 1)、Cadvisor命令: 下载地址:https://github.com/google/cadvisor/releases/latest 【直接下载命令,建议开…...
东戴河网站建设/免费推广seo
TCL(Transaction Control Language)事务控制语言 COMMIT 提交SAVEPOINT 设置保存点ROLLBACK 回滚SET TRANSACTION 转载于:https://www.cnblogs.com/Skyyj/p/6514874.html...
wordpress date/淘宝关键词怎么选取
单机1.0版包括6个class文件:TankClient.java : 主要执行部分,项目的大管家Tank.java : 实现Tank类,模拟坦克的运动Missile.java : 实现Missile类,模拟子弹的运动Explode.java : 实现Explode类,模拟爆炸的产生Wall.java…...
苏州做网站建设公司/seo专业培训学费多少钱
1. 运行时常量池和静态变量都存储到了堆中,MetaSpace存储类的元数据,MetaSpace直接申请在本地内存中(Native memory),这样类的元数据分配只受本地内存大小的限制,OOM问题就不存在了。除此之外,还有其他很多好处&#x…...