如何检测 Web 服务请求丢失问题
导读
『StabilityGuide』是阿里多位阿里技术工程师共同发起的稳定性领域的知识库开源项目,涵盖性能压测、故障演练、JVM、应用容器、服务框架、流量调度、监控、诊断等多个技术领域,以更结构化的方式来打造稳定性领域的知识库,欢迎您的加入。
@GitHub :https://github.com/StabilityMan/StabilityGuide
问题描述
最近偶尔有用户反馈某些 HTTP 接口出现超时问题,而 web 服务端的 Trace 监控没有出现 http 返回值为 503 等异常情况。出现这种情况一般是web容器出现问题,客户端连接不上来。本文将主要介绍如何去监控这类问题。
我们是用典型的 Web 服务架构,应用通过域名访问到我们的 LVS(Linux Virtual Server)机器,LVS 后面对应了多台 Web 服务器。

考虑到无法对 LVS 进行跟踪,而 Web 服务器(Tomcat 上出现堆积,无法评估影响范围)。考虑再三后,我们准备在Tomcat 和 LVS 上加一个 Nginx,用于追踪用户访问的真实情况。Nginx 是一款自由、开源的高性能 HTTP 服务器。通过 Nginx 代码,我们可以掌握第一手的用户访问的真实情况,本来是打算通过 Nginx 的 Access 日志来做统计, 后来参考 阿里云链路追踪的文档,用链路追踪可以把 HTTP 的埋点和 Tomcat 连起来看,可以更详情地发现问题。

环境准备和问题复现
编译安装 Nginx 和 Jaeger Agent,具体的安装过程可以参考 阿里云链路追踪文档。
测试环境:需要重现超时问题,写了一个小程序,开启 200 个线程,每个线程连续向服务发送 500 个请求。总共提交 100000 个请求。
排查过程
排查的主题思路, 对比 Web 服务端数据和 Nginx 服务端的链路统计数据,如果两种的请求数不一致,那可以确定有请求丢失。再根据链路上的详情数据来确定丢失请求的原因。
1、Web 服务端数据统计
发送请求后,发现 web 服务端一共处理 98717 个请求,比客户端少了 1283 个请求。

2、Nginx 服务端统计
查看 Nginx 的请求,一共有 100000 个请求,说明 Nginx 收到了全部请求,但是进入到 Web 服务上处理的只有 98717 个请求(通过 javax.servlet.Filter 埋点来监控)。
3、问题分析
检查 Nginx 服务,发现 Nginx 的有些请求的 HTTP 的返回码 499。如下图所示:

对比正常的 HTTP 链路,发现 Nginx 的请求的 HTTP 的返回码 499,只有一个 Span 就返回了,而 HTTP 返回码为 200 的,可以看到完整的调用链路(链路上除了 Nginx 的 Span,还有 Web服务的 Span),如下图展示:

我们可以这样来解释这个问题,客户端流量进入 Web 服务器,如果 Web 服务器处理不过来(超出可承受的最大流量或者 Web 服务器本身可能出现 FullGC,OOM,死锁,线程池慢问题), 那客户端设置超时的请求将会出现 499,未进入 javax.servlet.Filter 处理,Web 服务端看不到任何访问记录。
那是不是可以认为出现 HTTP 返回值为 499 的请求都是服务端处理失败的请求?
4、进一步排查
我们捞取下 Nginx 上返回 499 的请求,总共 2719条,大于 Web 服务丢失的 1283 个请求。这个数据对不上,是什么原因呢?我们在仔细查看了下数据,有 Nginx 返回 499 的请求,但是 Web 服务返回了 200。这些请求进入 Web 服务处理程序,但是 Web 服务还没返回就超时了。如果没有 Tracing 把上下文链接起来,我们很难通过 Nginx 日志或者 Web 服务日志来解释这个问题(一个请求,Nginx 返回 499,而 Web 服务返回 200),如下图所示:

把 Nginx 和 Web 容器服务(Tomcat)的链路打通,我们可以查看 HTTP 请求每个环节的状态,很方便地定位问题。
总结
针对这种 Web 服务无响应的问题,可以通过加一层代理(Nginx代码),很好的排查问题。同时也很好统计 Web 服务器造成多少请求失败,影响多少用户。对故障定级,影响面可以进行准确的评估。

推荐产品 Tracing Analysis
- 登录链路追踪控制台,在概览页面上打开 查看 Token 开关。
- 单击需要使用的链路数据采集客户端(Jaeger 或 Zipkin)按钮。
- 在下方表格中相应地域的 相关信息 Trace 列中,单击接入点信息末尾的复制按钮。
提示:如果应用部署于阿里云生产环境,则选择内网接入点,否则选择公网接入点。对于 Zipkin,一般情况下请使用 v2 版接入点,v1 版接入点仅限对 Zipkin 十分了解的高阶用户使用。
本文作者:徐建伟,花名竹影,阿里云技术专家,多年系统架构,性能调优经验, 目前主要从事链路跟踪,应用监控相关工作。
本文为云栖社区原创内容,未经允许不得转载。
如何检测 Web 服务请求丢失问题的更多相关文章
- WCF 扩展一:格式化Web服务请求XML
扩展原因 有一WebService,在工程中添加Web Service引用后调用不成功,但是用SoapUI测试正常 分析 用tctTrace跟踪报文后发现wcf生成的报文命名空间与SoapUI的不一样 ...
- Web服务器之Nginx详解(理论部分)
大纲 一.前言 二.Web服务器提供服务的方式 三.多进程.多线程.异步模式的对比 四.Web 服务请求过程 五.Linux I/O 模型 六.Linux I/O 模型具体说明 七.Linux I/O ...
- 【转】Web服务器之Nginx详解(理论部分)
大纲 一.前言 二.Web服务器提供服务的方式 三.多进程.多线程.异步模式的对比 四.Web 服务请求过程 五.Linux I/O 模型 六.Linux I/O 模型具体说明 七.Linux I/O ...
- 使用 ServiceStack 构建跨平台 Web 服务
本文主要来自MSDN杂志<Building Cross-Platform Web Services with ServiceStack>,Windows Communication Fou ...
- windows环境下解决web服务假死的问题
最近在windows系统在部署web服务器,发现很不稳定.web服务有容易假死,改过配置换过各种web软件,如apache.nginx都不管用. 所以干脆做个简易的定时检测Web服务状态的软件.一旦w ...
- Azure机器学习入门(四)模型发布为Web服务
接Azure机器学习(三)创建Azure机器学习实验,下一步便是真正地将Azure机器学习的预测模型发布为Web服务.要启用Web服务发布任务,首先点击底端导航栏的运行即"Run" ...
- Linux中web服务运行情况的方法
监控一般通过脚本实现,使用定时任务定期执行检测. 1.端口 本地:ss,netstat,lsof 远程:telnet,namp,nc 2.本地进程数 例如: lsof -i:80|wc -l ps - ...
- WEB服务重要基础
1.1用户访问房展基本流程 我们每天都会使用Web客户端上网浏览网页.最常见Web客户端就是Web浏览器,如通过的微软InternetExplorer(IE)以及技术人员偏爱的火狐浏览器.谷歌浏览器等 ...
- 使用 ServiceStack 构建跨平台 Web 服务(转)
出处:http://www.cnblogs.com/shanyou/p/3348347.html 本文主要来自MSDN杂志<Building Cross-Platform Web Service ...
随机推荐
- cocos构建的android项目的返回键相应
@Override public boolean dispatchKeyEvent(KeyEvent event) { //返回键 cocosActivity不相应onbackPressed和onKe ...
- 辞职信也要玩出高big
辞职信尊敬的各位公司领导:值此用人之际,不期请辞,实属不敬.历经四季,余以凡才,承蒙殊待,幸受公司各位领导知遇之恩,得以与诸位贤达公事.时光荏苒,吾经竭力而为,以图报效,虽幸遇领导执手相教,然资质愚钝 ...
- redis 分析rdb中key
1.问题: 单位一个redis集群内存报警,想找出所有的key的列表? 2.解决办法: 网上搜索是可以用redis-rdb-tools 这个工具进行分析 (1)centos6 默认安装python2. ...
- where I will go
为什么我选择了java? 作为一个0基础入门的编程小白,大一的时候我接触了C语言,写了我的第一个程序hello world,内心有点小骄傲(我也能编程了),那时候还不知道java是什么,然而实际公司的 ...
- leetcode-158周赛-5222-分割字符串
题目描述: 自己的提交: class Solution: def balancedStringSplit(self, s: str) -> int: if not s:return 0 res ...
- JAVA C 数据类型对应
{ Java—C和操作系统数据类型的对应表 Java Type C Type Native Representation boolean int 32-bit integer (customizabl ...
- delphi Copy函数 和 Pos函数
copy(a,b,c); a:就是copy源,就是一个字符串,表示你将要从a里copy一些东西, b:从a中的第b位开始copy(包含第1位), c:copy从第b位开始后的c个字符, 例如: m:= ...
- Dart编程数据类型
编程语言最基本的特征之一是它支持的数据类型集.这些是可以用编程语言表示和操作的值的类型. Dart语言支持以下类型 数字 字符串 布尔 列表list map 数字 Dart中的数字用于表示数字文字.D ...
- [Nowcoder] 数数字
题意:...咕咕懒得写了. 思路: 裸的记搜... #include <bits/stdc++.h> using namespace std; #define ll long long m ...
- 快速排序--Python实现
快速排序算法:1.选择一个基准数2.小于基准数的放左边,大于基准数的放右边3.利用递归的方法针对左边的数据进行快速排序,再对右边的数据进行快速排序4.递归停止的条件:数组为空或者只有一个元素 时间复杂 ...