【问题复盘】第三方接口变慢导致服务崩溃

一、事件经过

-1、一个不在公司的下午,接到客户投诉,说平台不能访问了。

0、介入调查,发现服务器http请求无法访问,https请求却可以正常访问,一时有些无法理解;(后来发现,http和https协议是两个不同的线程池。)

1、排查发现Tomcat的线程数达到maxThreads设定的值,于是选择调大maxThreads,原以为问题会这样就被解决了,但在重启服务后,线程数飙升,不一会儿线程数又达到最大值;

Linux查看Tomcat线程命令 (可用top命令查看进程ID)

ps -T -p <Tomcat进程ID> | wc -l

详解tomcat的连接数与线程池 - 编程迷思 - 博客园 (cnblogs.com)

2、开始陷入迷惘,因为最近的代码只是简单修复了一些bug,不应该会造成线程数剧增。 为了进一步确认是否是代码造成的问题,将代码回滚到之前正常的版本,结果线程数同样剧增,直至设定的最大值。

3、困惑加深,难道不是代码的问题? 陷入毫无头绪之中,于是选择以日志作为突破口,有一行WARN日志引起了注意。 这行WARN日志会反复出现,而且出现的同时伴随着不断增加的线程数,由此断定,这行日志就是问题的关键。

4、柳暗花明。 但这行日志看不懂,于是开始了面向百度解决问题。去网上找各种关于这个日志的博客,尝试了博客里的多种方法,也试过了GPT提供的方法,但始终无法确定日志产生的原因,这行WARN日志依旧一直存在。

5、或许,一开始方向就错了。 解决警告日志的问题,就应该先定位到,具体是哪一行代码产生的警告日志。或许是夜太深了,连排查问题的基本思路都迷糊了。

6、突然,在网上看到一篇说明这个报警日志的博客,里面提到了一句,产生这个报警日志的原因在于调用了第三方接口,问题是出现在第三方平台。

关键文章

7、起初,这篇博客没有引起我的注意,因为印象中好像平台基本没有调用第三方接口。但当试了各种方法都没有用以后,想起了这篇博客说的,再试试或许能行呢? 刚好也想到最近确实有调用一个上传记录的第三方接口,于是选择将那部分代码注释了,然后进行测试。

8、果然,一注释掉那行代码,线程数就立刻不增加了。再测试一下那个三方接口,发现请求一次居然要花费5秒钟,之前那个接口调用只需要1-2秒,某些神秘原因导致接口变慢。而设备访问自己平台的频次是2秒一次,2秒没有结果后,就会重新再次发起请求。相当于因为请求超时,然后设备一直不停的访问。(在排查过程中,有那么几次怀疑服务器是被人攻击了,因为在设备配置的是ip+端口号,有心人想要攻击实在太容易了)

9、注释三方接口代码重新部署后,服务又恢复了正常。

10、悬着的心终于放下了,看看外面,天空已经露出了一丝丝鱼肚白。。。

二、问题代码优化

  • 代码业务逻辑

设备上传数据到平台,平台再把数据上传到第三方平台。

  • 初始代码

初始逻辑:在controller层,拿到数据后处理后,调用postDataToAPI方法上传数据。

@Autowired
private RestTemplate restTemplate;
/*** 发送POST请求* @param url* @param requestBody* @return*/
public  boolean postDataToAPI(String url, String requestBody) {HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);HttpEntity<String> entity = new HttpEntity<>(requestBody, headers);ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);String bodyStr = response.getBody().toString();JSONObject responseBodyObject = JSONObject.parseObject(bodyStr);String code = responseBodyObject.getString("ResultCode");if (!StringUtils.isEmpty(code) && "0".equals(code)) {return true;}return false;
}
  • 改进后的代码

改进逻辑:

controller层拿到数据后,不调用postDataToAPI方法,而是将数据保存到数据库,然后将成功结果返回。

调用三方接口上传数据的过程,单独启用一个定时任务执行。在执行的过程中,使用FixedThreadPool线程池来多线程执行,增加上传数据的效率。 如果数据上传成功,则删除数据库数据,失败则保留至下一轮尝试再次上传。

// 固定线程数的线程池
private final ExecutorService executorService = Executors.newFixedThreadPool(5);
@Scheduled(fixedRate = 60000)
public void timedUpload(){// 获取第一页数据List<TemptData> list1 = getDataByPage(0, 8);// 获取第二页数据List<TemptData> list2 = getDataByPage(8, 8);// 获取第三页数据List<TemptData> list3 = getDataByPage(16, 8);// 获取第四页数据List<TemptData> list4 = getDataByPage(24, 8);// 获取第五页数据List<TemptData> list5 = getDataByPage(32, 8);// 提交任务给线程池执行executorService.submit(() -> executeUpload(list1));executorService.submit(() -> executeUpload(list2));executorService.submit(() -> executeUpload(list3));executorService.submit(() -> executeUpload(list4));executorService.submit(() -> executeUpload(list5));
}// 查询数据
private List<TemptData> getDataByPage(int start, int pageSize) {return temptDataMapper.getDataList(start, pageSize);
}// 上传数据
public void executeUpload(List<TemptData> list) {if (!list.isEmpty()){for (TemptData temptData : list) {sendToDongshun(temptData);}}
}

注意:

  • getDataByPage获取数据时,需要考虑重复消费的问题。因为可能在60秒内,线程还没有执行完,然后下一轮又开始拿到相同的数据执行了。
  • 需要考虑到异常导致数据上传失败的问题,可以采用try catch finally的方式,将上传失败的数据保留和标记。

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

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

相关文章

网络编程(八)

网络编程&#xff08;八&#xff09; 数据库数据库的分类基于嵌入式的数据库什么是SQLite?为什么使用SQLite?sqlite3数据库的安装 sqlite3中的点命令.open 数据库文件名字.tables [数据库文件名].schema 表名.database.quit.head on.mode column SQLite数据库中的数据类型SQL…

《混凝土坝安全监测资料整编规程》的深入解读与实际应用

在水利工程中&#xff0c;混凝土坝作为重要的建筑物&#xff0c;其安全监测工作至关重要。为了确保监测工作的准确性和有效性&#xff0c;制定一套规范的混凝土坝安全监测资料整编规程显得尤为重要。本文将对《混凝土坝安全监测资料整编规程》进行深入解读&#xff0c;并探讨其…

泛型基础及深入

泛型深入 泛型定义&#xff1a; JDK5引入的特性&#xff0c;可以在编译阶段约束操作的数据类型&#xff0c;并进行检查 泛型格式&#xff1a; <数据类型> 注意&#xff1a;泛型只能支持引用数据类型 优势&#xff1a; 统一数据类型&#xff1b; 把运行时期的问题提前到…

快速排序(Quick Sort)(C语言) 超详细解析!!!

生活的本质是什么呢? 无非就是你要什么就不给你什么. 而生活的智慧是什么呢? 是给你什么就用好什么. ---马斯克 索引 一. 前言二. 快速排序的概念三. 快速排序的实现1. hoare2. 挖坑法3. 前后指针法 总结 正文开始 一. 前言 接上文, 前面我们了解了插入排序, 与优化版本希尔…

HQL面试题练习 —— 向用户推荐好友喜欢的音乐

目录 1 题目2 建表语句3 题解 题目来源&#xff1a;腾讯。 1 题目 现有三张表分别为&#xff1a; 用户关注表 t_follow(user_id,follower_id)记录用户ID及其关注的人ID&#xff0c;请给用户1 推荐他关注的用户喜欢的音乐名称 ------------------------ | user_id | follower…

六月可以闭眼入的宠物空气净化器:希喂、安德迈、霍尼韦尔真实PK

俗话说得好&#xff0c;猫咪一年到头都在掉毛&#xff0c;仿佛它们是四季常在的"蒲公英"&#xff0c;随时随地都在播撒毛发。猫毛不仅遍布它们自己的身体&#xff0c;还可能飘到你的床铺、沙发、衣物上……面对这样的状况&#xff0c;既要应对无处不在的猫毛&#xf…

基于卷积神经网络(CNN)的垃圾分类模型研究

摘要&#xff1a; 随着城市化进程的加快&#xff0c;垃圾问题日益严重。传统的垃圾分类方法存在效率低下、准确率不高等问题。本文提出了一种基于卷积神经网络&#xff08;CNN&#xff09;的垃圾分类模型&#xff0c;该模型能够自动识别并分类不同类型的垃圾。实验表明&#xf…

Kruskal算法求最小生成树

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #define MAX 100 #define NO INT_MAX//NO表示没有边&#xff0c;相当于INFtypedef struct Graph {int arcnum;int vexnum;char vextex[MAX][20];int martrix[MAX][MA…

什么无线领夹麦克风音质最好?领夹麦克风品牌排行榜前十名推荐

​在当今的数字化浪潮中&#xff0c;个人声音的传播和记录变得尤为重要。无论是会议中心、教室讲台还是户外探险&#xff0c;无线领夹麦克风以其卓越的便携性和连接稳定性&#xff0c;成为了人们沟通和表达的首选工具。面对市场上琳琅满目的无线麦克风选择&#xff0c;为了帮助…

Doris insert into 插入语句执行成功,且select查询成功,返回结果不报错,但查不到该插入数据

问题&#xff1a;Doris insert into 正常执行成功&#xff0c;select 查询也执行成功&#xff0c;但查不到该写入数据 原因&#xff1a;由于有其他 insert commit 事务待提交且该任务处于锁的状态&#xff0c;导致不断在回滚&#xff0c;进而造成其他的insert into 语句也执行成…

26 - 超过5名学生的课(高频 SQL 50 题基础版)

26 - 超过5名学生的课 select class fromCourses group byclass havingcount(*)>5;

Seed-TTS语音编辑有多强?对比实测结果让你惊叹!

GLM-4-9B 开源系列模型 前言 就在最近&#xff0c;ByteDance的研究人员最近推出了一系列名为Seed-TTS的大规模自回归文本转语音(TTS)模型,能够合成几乎与人类语音无法区分的高质量语音。那么Seed-TTS的表现究竟有多强呢?让我们一起来感受下Seed-TTS带来的惊喜吧! 介绍Seed-TTS…

组装服务器重装linux系统【idrac集成戴尔远程控制卡】

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 &#x1f3c5;阿里云ACE认证高级工程师 &#x1f3c5;阿里云开发者社区专…

数据结构 | 超详细讲解七大排序(C语言实现,含动图,多方法!)

目录 ​编辑 排序的概念 常见排序算法 ​编辑 1.冒泡排序 &#x1f379;图解 &#x1f973;代码实现 &#x1f914;时间复杂度 2.插入排序 &#x1f379;图解 &#x1f334;深度剖析 &#x1f34e;代码思路 &#x1f973;代码实现 &#x1f914;时间复杂度 3.希尔…

2024 年适用于 Linux 的 5 个微软 Word 替代品

对于那些最近由于隐私问题或其他原因而转向 Linux 的用户来说&#xff0c;可能很难替换他们最喜欢的、不在 Linux 操作系统上运行的应用程序。 寻找流行程序的合适替代品可能会成为一项挑战&#xff0c;而且并不是每个人都准备好花费大量时间来尝试弄清楚什么可以与他们在 Win…

读书笔记|《把自己变成稀缺资产》:我们都拥有100分的欲望,却只有1分的耐心。

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 最近在读一本书《把自己变成稀缺资产》&#xff0c;其中一章讲到耐心的重要性&#xff0c;很有共鸣。 当今社会&#xff0c;生活节奏越来越快&#xff0c;我们都在急于求成的追求结果&#xff0c;对过程越来越缺乏耐…

2024050402-重学 Java 设计模式《实战责任链模式》

重学 Java 设计模式&#xff1a;实战责任链模式「模拟618电商大促期间&#xff0c;项目上线流程多级负责人审批场景」 一、前言 场地和场景的重要性 射击&#x1f3f9;需要去靶场学习、滑雪&#x1f3c2;需要去雪场体验、开车&#x1f697;需要能上路实践&#xff0c;而编程…

Scanpy(4)用与数据整合和批次处理

Scanpy包,用与数据整合和批次处理,包含批次效应的BBKNN算法和用于对比的ingest基础算法比较,及其原理简介。 1. 依赖: (1)数据集(全部需要挂VPN): PBMC:pbmc3k_processed()(需要下载);pbmc68k_reduced()(scanpy自带)Pancreas(需要下载)(2)Python包:Scanp…

【Python】把xmind转换为指定格式txt文本

人工智能训练通常需要使用文本格式&#xff0c;xmind作为一种常规格式不好进行解析&#xff0c;那如何把xmind转换为txt格式呢&#xff1f; 软件信息 python python -v Python 3.9.13 (tags/v3.9.13:6de2ca5, May 17 2022, 16:36:42) [MSC v.1929 64 bit (AMD64)] on win32…

Python 包安装及常用命令【python 入门】

背景&#xff1a; 近期看到一个项目&#xff0c;做微信只能机器人&#xff0c;服务是使用python搭建的&#xff0c;于是拷贝下来自己打算跑一跑&#xff0c;部署一下&#xff0c;可是自己又没有python的经验&#xff0c;于是各种查资料学习&#xff0c;跟着敲一敲&#xff0c;顺…