线上问题定位追溯

2019-10-24  本文已影响0人  morning_king

问题定位追溯

准备方面

常见问题列表

  1. 服务报错,返回服务器错误;
  2. 服务无法访问;
  3. 服务很慢,很久才能返回结果;
  4. 数据接口并未按照预设的程序路径执行;

处理思路

1. 服务报错,返回服务器错误(Http-code为500);

分析:对于这种问题,属于最基本的线上问题,一般常见于数据校验缺失、程序逻辑问题、第三方依赖服务故障、网络故障等问题触发;

解决方法:(谁在什么时间节点发起了什么请求,命中了哪个程序路径,引发了什么错误)定位该请求的时间点,当时的请求参数和上下文信息,找到对应的堆栈,然后进行相应的排查;

常见诊断步骤:
  1. 通过IDE找到对应url的类名和方法名,比如通过/order/addOrder.json找到OrderInfoController.addOrder
  2. 从sku.log(找对应的业务日志,这里以商品订单为例)找到当时的报错堆栈,搜索OrderInfoController.addOrder,搜索命令为grep 'OrderInfoController.addOrder' sku.log或者通过elk进行查找,这里如果有多个过滤条件,可以使用linux管道,如查找方法名为OrderInfoController.addOrder且时间是2019-05-04 14:00:00可以使用grep 'OrderInfoController.addOrder' sku.log | grep '2019-05-04 14:00:00'
  3. 找到对应的日志记录行后,再去找出当时错误的具体原因,可以结合当时上下文信息来一起判断,这里可以通过线程号向上查询得出上下文信息(因此方法中需要有必须的上下文信息打印才可追溯,否则即使找到了堆栈,也需要靠推测和猜测);

2. 服务无法访问

分析:需要理清从客户端发起请求到服务端响应会经过哪些环节,是否其中某一个或者多个环节发生了问题;

解决方法:根据客户端的显示状况和http状态码来区别分析;

从客户端发起http请求到服务端响应一般需要经过的环节
  1. DNS域名解析:如果客户端是用域名访问,会做dns解析,得到ip;
  2. 建立TCP链接:通过第一步得到的ip和端口号(http默认是80,https默认是443),通过三次握手建立一条tcp链接;
  3. 传输数据(序列化和反序列化):客户端按照http请求格式组装请求,通过tcp链接传输到服务端;
  4. 代理服务器转发:一般服务端都会有代理服务器,进行反向代理,将请求传输到业务服务器;
  5. 定制拦截链过滤:业务服务器会有一系列定制的拦截链进行拦截过滤,比如身份认证、权限校验等;
  6. 业务处理:按照指定输入,执行业务开发人员开发的业务逻辑,这个过程中,会与外部依赖服务和中间件进行数据交换,最终返回相应的数据;
常见诊断步骤:
  1. 浏览器显示无法找到服务的ip地址、xxx的响应时间过长:域名问题|dns解析问题|vpn问题|端口权限问题;
  2. 服务502:应用服务器挂掉了,或者代理服务器认为应用服务器挂掉了,那代理服务器什么时候会认为应用服务器挂掉呢,应用服务器什么时候会挂掉呢?);
    • 应用服务器确实挂掉了,进程不在(使用ps -efjpspgrep均可);
    • 应用服务器和代理服务器网络不通,无法建立链接(使用ping判断配置的ip或域名是否可达);
    • 代理配置,nginx默认的proxy_next_stream功能,502和504都会认为上游应用挂掉了(http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream);
  3. 服务504:应用服务器响应超时,超过了代理服务配置的超时时间,应用处理慢的问题转到问题3;

3. 服务很慢,很久才能返回结果

分析:服务很慢就是响应时间很长,响应时间的公式为网络延迟+服务器处理延迟

解决方法:首先需要定位出问题在什么地方,这很依赖于系统和程序目前的状态,以及一些必要的日志,才能综合分析到底是哪个环节或者哪些环节累加导致了最终的高处理延迟;

常见诊断步骤
  1. 查看系统负载是否很高,通过命令wtop都可以看到load average,如果load average数值大于cpu核心数,表示系统很多任务在排队,流量较大,之前发生一起事故是运维将官网的代理和神农架代理放在一块,代理服务器是2核,导致服务响应持续超时,这种最好是做流量隔离,避免关键服务受到影响;
  2. 查看cpu占用率是不是有异常情况,通过命令top可以看到cpu占用率,如果cpu持续处于很高的占用率,说明程序有哪些地方在做cpu密集型的操作,极有可能死循环,可以通过top -H -p pid来定位到对应进程的各个线程信息,转4;
  3. 查看数据库是不是有sql处于执行中,这种情况很多,可以通过show full processlist来查看;
  4. 查看是不是有线程一直处于运行态,通过命令jstack -l pid来查看;
  5. 查看是不是有可能是一直在进行gc,通过命令jstat -gcutil pid frequency times来观察;

常用工具及选项

  1. grep:使用该命令可以快速从文本中找出指定输入的匹配行,输入可以是原生字符串也可以是正则表达式;


    常见选项:
    • -A:after,找出匹配行以及匹配行后指定数量的行;
    • -B:before,找出匹配行以及匹配行后指定数量的行;
    • -C:center,找出匹配行以及匹配行前后指定数量的行;
    • -E:extended-regexp,使用正则表达式来做字符串匹配;
  2. less:使用该命令以缓冲式窗口的方式来访问文本文件;


    常见选项:
    • f:向前翻一页;
    • b:向后翻一页;
    • Enter:向前滚动一行;
    • /:向下搜索"字符串";
    • ?:向上搜索"字符串";
    • n:对于/和?搜索命中的字符串,查找下一处命中的;
    • N:对于/和?搜索命中的字符串,查找上一处命中的;
    • q:退出浏览;
  3. ping:使用该命令来判断网络连通性;
  4. nctelnet:通过该命令来判断ip+端口是不是可达,一般使用nc -zv ip port
  5. jps:查看java进程;
  6. jstack:查看java线程堆栈,一般使用jstack -l来查看线程列表和相应状态;
  7. jstat:查看java进程内存占用率;

相关图示

线程状态机
)

机器故障排查
业务故障排查
linux命令导图

参阅

  1. https://mp.weixin.qq.com/s/AUST6fSc1zqeQ7rreC0gWA
  2. https://blog.csdn.net/GitChat/article/details/79019454
  3. https://docs.oracle.com/javase/8/docs/technotes/tools/index.html
  4. 《Java性能优化权威指南》
  5. http://nginx.org/en/docs/
上一篇 下一篇

猜你喜欢

热点阅读