IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 接口响应过慢的原因排查 -> 正文阅读

[网络协议]接口响应过慢的原因排查

最近一次的项目体验,手机用户在训练完成之后,会有服务器超时的提示,在用户量大的时候,每晚的7-9点时间段发生的尤为频繁,所以作了一些的排查。

排查的顺序乃是这样的:

  1. 确定是哪个接口存在性能问题
  2. 确定这个接口的内部逻辑是怎样的,做了哪些事情
  3. 分析接口存在性能问题的根本原因
  4. 寻找确立优化方案
  5. 回归验证方案效果

首先哪个接口的话,代码当中马上就找到了,立刻开始确定里面的逻辑,这一下就发现了问题了,里面的逻辑随着业务的增加,这里面变得越来越臃肿,包括对多张表的查询、几张表的更新与新增,这一下就看到了,可是里面的一些逻辑实在太难拆出来了,上下的连接性太严重,需要前面的数据,后面的业务才能继续的走下去。没办法,就看看还有什么其他的地方需要优化的。

  1.在sql日志的打印中,喜不自胜的看到了一连串了slow 慢sql语句,这下子可以从这些sql语句上着手的,这是肯定要优化的,都是一些执行时间大于1s的,更有甚者到达了5-6s。

?最严重的,我发现这是一条update语句,竟然不是select查询语句,后来查了一下的资料,发现可能是因为事务的原因,线程被阻塞,锁住了要查询的表,导致sql语句过慢,接口也就相对应的慢起来,发现这个update的语句,会对播放记录play_total多次的进行+1的操作,每次当前视频video被跳一次,它的热度就作+1处理,导致这个字段被更新的过于频繁,这张表被锁死了,其他对video的查询操作进行不下去,整个接口的响应被拖慢了。

解决方案:将这个play_total字段单独拿出来做张副表,专门对这个字段作更新+1的操作,这样在频繁也不会,对其他的查询操作有影响了,尤其是对video的影响

?PS:其实还有更好的方法,对于这种频繁操作,但是却不太重要的字段,可以直接存在缓存当中,在服务器启动时,做一次查询操作,后面所有的更新操作直接在缓存里进行,这样也就不会对数据库有任何的影响了。隔段时间作同步操作,将缓存的数据同步到数据库中,这个涉及到数据的同步,可能会增加复杂度,使用的话,慎重。

  2.在作了这些操作之后,当晚发布后,第二天再次到达晚上用户量较多时,发现情况稍有好转,但是问题仍旧存在,有一些其他接口的响应时长在30s以上,用户还是时常会报服务器超时,于是再次排查问题所在,又再次发现了,问题接口里的逻辑写的有些问题,很多的for循环里嵌套了一些其他的一些实现类,然后里面包含对数据库的操作,这样也就相当于循环多少次,会建立多少次的连接,严重拖慢了接口的响应。

?于是作了一些的操作,在for循环外面将所有数据查询出来,sql里面用in? foreach标签,这2个sql作了联表查询,

?  3.还有最后一个问题就是,后台会经常报“断开的管道”这个异常,实在是不经常见到的错误,所以在网上搜了一些的答案

?https://blog.csdn.net/zqz_zqz/article/details/52235479

在这里面的文章里找到一些有用的内容,原来是因为接口响应过慢,导致前端那边设置的超时时间到了,直接主动切断了与后端的连接,但是后端还在查数据,查完以后想返给前端,发现管道已经断掉了,就只好报这个错误的

?后来又找了一些其他的资料,终于找到了解决方案,

?

解决方法

1、调大防火墙的连接切断时长#

这是一个临时解决方法,比如将防火墙的连接超时时间调整为8小时,这样可以尽量避免空闲连接的切断,但无法完全避免,因为无法预计连接会被空闲多久,如果你的系统不是总有人访问的话,那么连接迟早会因为空闲而被切断,导致一些不可预计的问题,而调大超时时间只是缓解而已

2、tcp keepalive功能#

tcp的keepalive,其实就是用来保持tcp连接的,其原理简单说就是如果一个TCP连接在指定的时间内没有任何活动,会发送一个探测包到连接的对端,检测连接的对端是否仍然存在,如果对端一定时间内仍没有对探测的响应,会再次发送探测包,发送几次后,仍然没有响应,就认为连接已经失效,关闭本地连接。
tcp keepalive并不是默认开启的,在开发程序时可以设置tcp keepalive为true,这样tcp连接在一定时间内没有任何数据报文传输则启动探测,这个时间一般是操作系统规定,Linux系统中可以通过设置net.ipv4.tcp_keepalive_time来修改,默认是7200秒,即2小时。当然在编程时也可以设置这个时间用于当前socket,但是Java的Socket API中好像只有设置keepalive=true,并没法设置tcp_keepalive_time
当设置了tcp keepalive之后,只要tcp探测包发送的时间小于防火墙的连接超时时间,防火墙就会检查到连接中仍然有数据传输,就不会断开这个连接。

使用JDBC创建的数据库tcp连接是没有设置keepalive的,这点可以通过Linux的netstat或ss命令在数据库客户端(即应用端)验证
使用命令netstat -ano?或?ss -ano,其中参数o都是显示timer计时器,timer计时器在连接建立状态下可以对连接保活计时
netstat命令对没有开启keepalive的tcp连接显示为:off (0.00/0/0)
ss命令对没有keepalive的tcp连接,不会显示timer计时器

3、程序不定时执行查询#

以上几种方法要么是利用tcp连接keepalive特性,要么是采用数据库端的空闲连接检测,我们的程序中也可以主动做这种心跳检测

Druid数据库连接池从1.0.28开始,添加了druid.keepAlive属性,默认关闭
打开druid.keepAlive之后,当连接池空闲时,池中的minIdle数量以内的连接,空闲时间超过minEvictableIdleTimeMillis,则会执行keepAlive操作,即执行druid.validationQuery指定的查询SQL,一般为select * from dual,只要minEvictableIdleTimeMillis设置的小于防火墙切断连接时间,就可以保证当连接空闲时自动做保活检测,不会被防火墙切断

这就是整个问题的解决,希望可以帮到大家。

https://blog.csdn.net/zqz_zqz/article/details/52235479

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-07-25 12:00:04  更:2021-07-25 12:00:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 17:44:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码