我的编程空间,编程开发者的网络收藏夹
学习永远不晚

服务器诡异的请求超时问题

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

服务器诡异的请求超时问题

服务器诡异的请求超时问题

前些日子,监控显示线上偶尔发生请求两秒超时的情况。解决这个问题前前后后花了不少时间,也走了一些弯路。这里记录下来备忘。

前期分析

首先需要了解一下我们的服务:

  • 我们的服务是一组无状态的前端服务器加上有状态的后端存储层。
  • 这些服务都部署在腾讯云黑石服务器上面。

第一件事是要定位问题出现在前端还是后端。通过日志,我们发现在出错时间段里,每个前端服务器都有报错,并且出错请求都是发往同一后端服务器的。由此可见,问题出现在后端服务上。

接下来,需要分析出错的特征。通过日志发现错误都是因为前端两秒超时导致,而后端在前端超时之后事实上是完成了请求。因为是存储服务,我们自然在第一时间就查看了磁盘的情况。果然,在出错时,磁盘的io.util非常高(sar -dp的输出,从第4列开始分别是tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util):

iostat output

需要注意的是:

  • io.util非常高,且只持续了2~3秒
  • 几乎所有盘的io.util都高
  • io的tps和吞吐并不高

另外,还发现了另外一个规律:单台机器,大概每12小时左右会出现io.util高,并伴随着超时出错:

iostat output

问题排查

快速排查

我们做了一些快速排查,试图以比较小的代价找到问题的根源:

  1. 查看系统的定时任务
  2. 查看系统日志
  3. 查看存储服务代码中的定时任务

可惜,都没有发现有价值的线索。于是推测,一定是有一个我们不知道的存在以12小时为周期在消耗IO。

追踪IO使用状况

先使用iotop来定位出错时刻是谁占用了大量IO:

python /sbin/iotop -bPto -n 86400  > iotop.log

上述命令以批处理的形式,每1秒一个输出,一共持续86400秒(24小时)。同样,并没有发现除了我们程序之外的可疑线程。

Iotop虽然是一个好工具,然而一个缺陷是并没有详细的文档说明它的工作原理。对于一个系统工具来说,原理性的文档还是很有必要的。在这种情况下,我们怀疑iotop并不能真实的反映进程的IO使用状况。为了再次确认,我们采用SystemTap来统计IO调用。下面是改良过的iotop.stp:

global count_stacks
global size_stacks

global max_seconds = 172800
global elapsed_seconds = 0
global interval = 2

probe ioblock.request {
    if(devname == "sdd") {
        count_stacks[pid(), execname(), bio_rw_str(rw), backtrace()]++
        size_stacks[pid(), execname(), bio_rw_str(rw), backtrace()] += size
    }
}

probe timer.s(1)
{
    if (++elapsed_seconds % interval == 0) {
        if (elapsed_seconds >= max_seconds) {
            delete count_stacks
            exit()
        }

        time_string = ctime(gettimeofday_s())

        foreach ([process_id, process_name, read_write, stack] in count_stacks- limit 5) {
            printf("==== %25s %6d %20s %s %d
", time_string, process_id, process_name, read_write, count_stacks[process_id, process_name, read_write, stack])
            print_syms(stack)
        }

        foreach ([process_id, process_name, read_write, stack] in size_stacks- limit 5) {
            printf("++++ %25s %6d %20s %s %d
", time_string, process_id, process_name, read_write, size_stacks[process_id, process_name, read_write, stack])
            print_syms(stack)
        }

        delete count_stacks
        delete size_stacks
    }
}

这个脚本以2秒间隔,采样发生在/dev/sdd上的所有IO读写请求,并分别按照请求栈出现的次数以及IO总大小,打印前5名。执行脚本:

nohup stap --suppress-handler-errors -d xfs ./iotop.stp > stap.log &

一个典型的部分结果是:

====  Wed Oct 24 09:19:03 2018   1984                 java W 20
 0xffffffff812c7130 : generic_make_request+0x0/0x130 [kernel]
 0xffffffff812cd89b : blkdev_issue_flush+0xab/0x110 [kernel]
 0xffffffffa0681dc9 : xfs_blkdev_issue_flush+0x19/0x20 [xfs]
 0xffffffffa066b506 : xfs_file_fsync+0x1e6/0x200 [xfs]
 0xffffffff8120f975 : do_fsync+0x65/0xa0 [kernel]
 0xffff882025940b80 : 0xffff882025940b80
 0xffffffff8120fc40 : SyS_fsync+0x10/0x20 [kernel]
 0xffffffff81645909 : system_call_fastpath+0x16/0x1b [kernel]
====  Wed Oct 24 09:19:03 2018   1984                 java R 5
 0xffffffff812c7130 : generic_make_request+0x0/0x130 [kernel]
 0xffffffff8121f630 : do_mpage_readpage+0x2e0/0x6e0 [kernel]
 0xffffffff8121fb1b : mpage_readpages+0xeb/0x160 [kernel]
 0xffffffffa065fa5d : xfs_vm_readpages+0x1d/0x20 [xfs]
 0xffffffff81175cdc : __do_page_cache_readahead+0x1cc/0x250 [kernel]
 0xffff88201534cf00 : 0xffff88201534cf00
 0xffffffff81175ee6 : ondemand_readahead+0x126/0x240 [kernel]
 0xffffffff811762c1 : page_cache_sync_readahead+0x31/0x50 [kernel]
 0xffffffff8120e0d6 : __generic_file_splice_read+0x556/0x5e0 [kernel]
 0xffffffff8120c9b0 : spd_release_page+0x0/0x20 [kernel]
 0xffffffff81513d48 : sk_reset_timer+0x18/0x30 [kernel]
 0xffffffff81582ce5 : tcp_schedule_loss_probe+0x145/0x1e0 [kernel]
 0xffffffff81583b40 : tcp_write_xmit+0x2b0/0xce0 [kernel]
 0xffffffff8163cb5b : _raw_spin_unlock_bh+0x1b/0x40 [kernel]
 0xffffffff815154a8 : release_sock+0x118/0x170 [kernel]
 0xffffffff815769e6 : tcp_sendmsg+0xd6/0xc20 [kernel]
 0xffffffff8120e19e : generic_file_splice_read+0x3e/0x80 [kernel]
 0xffffffffa066bc5b : xfs_file_splice_read+0xab/0x140 [xfs]
 0xffffffff8120d222 : do_splice_to+0x72/0x90 [kernel]
 0xffffffff8120d2f7 : splice_direct_to_actor+0xb7/0x200 [kernel]

第一个栈是我们的程序在做fsync,第二个栈是程序在做read ahead。这两个我们都排除了:

  • 系统压力并不大,fsync也是一直在做的操作
  • read ahead我们通过blockdev也修改了,并没有效果

至此,我们的调查陷入僵局:并没有谁在做IO,然而io.util就是高。

找到元凶

继续思考,我们推测:可能有某个操作并没有做大量的IO,但是可能会把盘给夯住。注意,这个推测和我们最初对IO的分析是一致的。

于是,我们想到用top来看看当时的进程状况(按道理这是第一个需要尝试的手段!):

nohup top -b -d 1 -n 86400 > top.log &

即,以批处理的方式,每1秒打印一次进程状况,一共持续24小时。然后,在发生问题的时刻,我们搜素所有处于D状态的(等IO)的进程。果然,发现一个可疑进程:

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
32289 root      20   0    2148   1528    212 D   0.0  0.0   0:00.00 sas3flash

sas3flash是个什么进程呢?先找到他的位置:

$ locate sas3flash
/usr/local/agenttools/agent/plugins/titan_tools/sas3flash

所在的目录貌似是属于一个agent的,嗯~相当可疑。看看他是被谁调用的:

   /usr/local/agenttools/agent/plugins$ grep sas3flash * -r
Binary file titan_for_serverV1.0 matches

   /usr/local/agenttools/agent/plugins$ strings titan_for_serverV1.0 | grep sas3flash
sas3flash
/usr/local/agenttools/agent/plugins/titan_tools/sas3flash -list
/usr/local/agenttools/agent/plugins/titan_tools/sas3flash
report_hba_by_sas3flash
report_hba_by_sas3flash
report_hba_by_sas3flash

再通过一通搜索,我们得知:

  • sas3flash貌似是一个HBA管理工具(pdf)
  • agenttools这个目录是腾讯云黑石的监控组件目录
  • sas3flash --list看上去是一个查看命令,貌似人畜无害,但很可能是问题的元凶

于是执行sas3flash --list,果然问题重现!用strace查看可知,该命令并没有发什么IO请求,而是做了一些ioctl的调用。实验证实这些查询调用会夯住IO。

/usr/local/agenttools/agent/Agent_log.log日志文件中,我们能够找到这个命令执行的时间点和输出,考虑到执行-汇报时间差,可以发现该命令执行的时间点就是线上超时错误问题出现的时间点:

[2018-10-25 19:12:13] Send warning info, id:36149, value:[CollectID:
ServerSN:2102311YMD10J1000212
Avago Technologies SAS3 Flash Utility
Version 09.00.00.00 (2015.02.03)
Copyright 2008-2015 Avago Technologies. All rights reserved.

        Adapter Selected is a Avago SAS: SAS3008(C0)

        Controller Number              : 0
        Controller                     : SAS3008(C0)
        PCI Address                    : 00:01:00:00
        SAS Address                    : 5e86819-f-8f0a-f000
        NVDATA Version (Default)       : 0b.02.00.01
        NVDATA Version (Persistent)    : 0b.02.00.01
        Firmware Product ID            : 0x2721 (IR)
        Firmware Version               : 12.00.02.00
        NVDATA Vendor                  : LSI
        NVDATA Product ID              : SAS3008
        BIOS Version                   : 08.29.02.00
        UEFI BSD Version               : 17.00.04.00
        FCODE Version                  : N/A
        Board Name                     : SAS3008
        Board Assembly                 : N/A
        Board Tracer Number            : 022CDECNHC010620

        Finished Processing Commands Successfully.
        Exiting SAS3Flash.
]

通过仔细查看这个目录下面的文件,就会发现,这个监控组件有着自己的一套定时任务逻辑以及日志输出。这就是为什么我们通过系统的crontab、cron.d以及系统日志无法定位问题的原因。

至于,为什么这个命令会导致IO夯,我们还在等腾讯云的答复。临时的解决方案是禁掉这个命令的执行(这也需要腾讯云出一个监控组件的hotfix包才能完成,单纯的删除sas3flash没有用)。

小结

纵观整个排查过程,我们其实是走了一些弯路,通过分析IO特征,如果第一时间采用top就能更快的发现问题。

同时,我也深深感受到了以下一些痛点:

  1. iotop应该有原理性文档
  2. 腾讯云的监控组件不应该完全独立于系统。如果走的是系统的contab,或者日志,我们可以很快定位问题
  3. 系统的监控组件应该得到充分的测试

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

服务器诡异的请求超时问题

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

服务器诡异的请求超时问题

前些日子,监控显示线上偶尔发生请求两秒超时的情况。解决这个问题前前后后花了不少时间,也走了一些弯路。这里记录下来备忘。 前期分析 首先需要了解一下我们的服务: 我们的服务是一组无状态的前端服务器加上有状态的后端存储层。 这些服务都部署在腾讯云黑石服务器上
服务器诡异的请求超时问题
2016-05-01

springboot如何实现异步响应请求(前端请求超时的问题解决)

这篇文章主要给大家介绍了关于springboot如何实现异步响应请求(前端请求超时的问题解决)的相关资料,文中通过实例代码介绍的非常详细,对大家学习或者使用springboot具有一定的参考学习价值,需要的朋友可以参考下
2023-01-30

使用PHP解决http请求超时的问题

利用PHP解决HTTP请求超时的指南PHP会设置30秒的默认超时时间,但延迟、拥塞或不稳定的连接可能导致超时。解决此问题需要:识别根本原因增加PHP超时时间(不推荐)使用持久化连接优化服务器端脚本调整服务器配置减少请求大小使用分布式缓存(如Redis)使用异步请求(如Swoole)实施超时重试机制
使用PHP解决http请求超时的问题
2024-04-02

HttpWebRequest多线程性能问题,请求超时的错误

转自:http://hi.baidu.com/ju_feng/blog/item/b1c41dbf09ad9e0119d81fb0.html通过Netstat –abn | find “:443” 如果有两个Time_Wait 和CLOSE
2023-06-04

线上SpringCloud Feign请求服务超时异常怎么排查

今天小编给大家分享一下线上SpringCloud Feign请求服务超时异常怎么排查的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一
2023-06-26

租用高防服务器请求超时如何排查

租用高防服务器请求超时可能由多种原因引起,以下是一些常见的排查方法:检查网络连接:首先要检查服务器的网络连接,确保网络连接正常。可以通过ping命令测试服务器的网络连通性,如果网络连接存在问题,需要联系服务器提供商或网络运营商解决。检查服务
租用高防服务器请求超时如何排查
2024-05-09

如何处理Go语言中的并发网络请求超时问题

在Go语言中处理并发网络请求超时问题,可以使用`context`包来实现。`context`包提供了一种在跨多个Goroutine传递请求范围数据、取消信号以及设置超时的方式。下面是一个处理并发网络请求超时问题的示例代码:```gopack
2023-10-09

如何处理Go语言中的并发网络请求超时问题?

如何处理Go语言中的并发网络请求超时问题?在使用Go语言进行网络请求的过程中,经常会遇到并发请求的情况。而并发请求的一个关键问题就是如何处理超时。本文将介绍如何在Go语言中处理并发网络请求的超时问题,并提供具体的代码示例。在Go语言中,处理
2023-10-22

请求阿里云服务器超时的原因及解决方法

本文将探讨请求阿里云服务器超时的原因,并提供一些解决方法,帮助用户解决这一常见问题。在使用阿里云服务器时,有时候我们会遇到请求超时的问题,这给我们的工作和业务带来了很大的困扰。那么,为什么会出现这种情况呢?下面我们将从以下几个方面来分析这个问题,并给出相应的解决方法。1.网络延迟网络延迟是导致请求超时的常见原因之
请求阿里云服务器超时的原因及解决方法
2024-01-16

云服务器超时问题怎么解决

解决云服务器超时问题的方案检查网络连接,优化服务器配置,优化代码和应用程序,监控和故障排除,其他方案(负载均衡器、升级、分布式架构、DNS优化)。
云服务器超时问题怎么解决
2024-04-09

云服务器超时问题怎么解决

在解决云服务器超时问题时,可以尝试以下几个方法:1. 检查网络连接:确保服务器与互联网的连接正常。可以使用ping命令测试服务器是否能够与其他计算机进行通信,如果无法ping通,可能是网络配置或者防火墙设置的原因。2. 检查防火墙设置:确保
2023-09-16

解决云服务器连接超时问题

1.检查网络连接首先,我们需要确保您的网络连接正常。请检查您的网络连接是否稳定,并确保您的设备已正确连接到互联网。您可以尝试重新启动您的路由器或调整网络设置来解决连接问题。2.检查防火墙设置如果您的网络连接正常,但仍然无法连接到云服务器,可能是由于防火墙设置导致的。请确保您的防火墙允许与云服务器的通信。您可以尝试禁用防火墙或添加相应的规则来允许连接。3.检查云服务器配置另一个可能的原因是云服务器的配置问...
2023-10-27

在Go语言中如何解决并发网络请求的请求服务降级和异常处理问题?

在Go语言中如何解决并发网络请求的请求服务降级和异常处理问题?随着互联网的快速发展,越来越多的应用需要进行并发网络请求。然而,在高并发的情况下,网络请求可能会导致超时、阻塞等问题,从而影响到整个系统的稳定性和可靠性。面对这个问题,我们可以使
2023-10-22

编程热搜

目录