美文网首页
一次排查记录

一次排查记录

作者: 只是肿态度 | 来源:发表于2019-05-12 23:27 被阅读0次

现象

在SDMK的管理后台的订单管理模块中,发现获取订单列表数据的延迟非常高。经过测试,发现该接口在生产环境中的延迟竟然达到2.5S左右。

因此,我开始排查测试环境的接口,发现测试环境的接口稳定在500ms左右。说明这两个环境可能存在某种差异。这两个环境代码一致,环境配置一致,说明可能是哪个环节出现了问题。

慢慢开始排查这个接口的调用链信息,因为我们用的是微服务架构,每个接口可能会涉及多个模块。所以要在每个调用处添加日志打印以及记录调用接口调用时间。
比如:

 long start = System.currentTimeMillis();
 //接口调用
 long end = System.currentTimeMillis();
 invokeLogger.info("该接口耗时:{} ms", (end - start));

类似这样的代码添加在了多处调用点。

在测试环境,数据库请求在10ms以内,网络接口请求在20ms左右,并没有发现任何异常信息。
因此,想着在生产环境的一个节点部署下该版本,查验下究竟是哪里出现了问题。
果不其然,发现在请求官网账户中心的接口时,发现该接口不稳定,一直维持在90ms~200ms之间。

既然发现了问题所在,就要着手去解决。要解决这个问题有两种方案:

  • 给官网账户中心提需求,优化该接口。
  • 根据我们的业务需求,绕过请求官网账户中心。

目前来看第二种比较现实一点,因为第一种,需要跟他们沟通、提需求,这些都是时间成本,因此还不如自己动手来的快。

最后经过优化、改善,接口的调用稳定在200ms。

回顾

回顾这次问题。我们不难发现,在微服务架构中,多个服务相互调用的情况很常见。因此,服务间的调用日志、监控必不可少。难道我们需要像前面那样,每处网络调用都要加这几行代码么?先不说繁琐,万一漏掉了某处,恰好这处出现了问题,到时候排查问题的时候可能会更麻烦。

因此,可以从网络请求处着手,我们一般都是用的第三方客户端比如apache的httpClient。我们可以借此封装自己的客户端,在网络的请求以及响应处添加自己的业务逻辑。这样就可以监控到每一处的网络请求。

我们的项目中有些是用SpringBoot框架,其中基本上都是用的spring提供的RestTemplate。因此,我对它做了点小小的添加,来达到我监控网络请求的目的。

RestTemplate自己提供了添加拦截器的方法。

    /**
     * Sets the request interceptors that this accessor should use.
     */
    public void setInterceptors(List<ClientHttpRequestInterceptor> interceptors) {
        this.interceptors = interceptors;
    }

因此,我们实现相应的拦截器就好了。

public class LoggingRequestInterceptor implements ClientHttpRequestInterceptor{
    final private Logger invokeLogger = LoggerFactory.getLogger("invokeLog");

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        return writeLog(request, body, execution);
    }

    private ClientHttpResponse writeLog(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        long start = System.currentTimeMillis();
        ClientHttpResponse response = execution.execute(request, body);
        long end = System.currentTimeMillis();
        InvokeLog invokeLog = new InvokeLog(request.getURI().toString(), (end-start), response.getRawStatusCode());
        invokeLogger.info(invokeLog.toString());
        return response;
    }
}

然后在配置RestTemplate的时候添加上该拦截器:

   RestTemplate restTemplate = new RestTemplate();
   List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
   interceptors.add( new LoggingRequestInterceptor());
   restTemplate.setInterceptors(interceptors);

这就简单的实现了在SpringBoot框架下实现了网络请求的统一监控。

但是这仅仅是只是监控某个服务的网络调用。并无法来监控整个调用链的。如果想尝试针对整个调用链的监控,可以试试zipkin。

相关文章

  • 一次排查记录

    现象 在SDMK的管理后台的订单管理模块中,发现获取订单列表数据的延迟非常高。经过测试,发现该接口在生产环境中的延...

  • 再一次oom的记录

    上一次oom的记录在一次排查OOM的总结,这次oom的排查大概花了一天不到,和leader一起,我这边主要是根据后...

  • 一次完整的JVM堆外内存泄漏故障排查记录

    前言 记录一次线上JVM堆外内存泄漏问题的排查过程与思路,其中夹带一些JVM内存分配机制以及常用的JVM问题排查指...

  • 记录一次启动crash排查

    背景最近遇到一个启动的crash,这个启动是app的通知拉起来的,每次都会crash,而正常的启动则不会发生,所以...

  • 一次sparksql问题排查记录

    问题: 在调试一个sparksql左连接查询时发现数据结果不正确,经过一天折腾才发现使用子查询方式能够得到正确的...

  • 记录一次慢sql排查

    mysql的慢日志中,看到有这么一条 不算太复杂的一条sql,但是扫了200多万行的数据,所以慢。先看执行计划 m...

  • JNI编译错误-符号未定义

    这篇笔记记录了一次编译问题的排查过程,还简单介绍了一些C/C++编译的知识,希望对jni编译错误的排查能有点帮助。...

  • k8s环境应用访问不同排查步骤

    简单记录下自己的排查步骤

  • 【Android】记录一次换肤插件问题排查

    记录一次换肤插件问题排查 PS:出现的问题已经修复并发布至Github:https://github.com/Li...

  • 238桩更换

    2020-6-18排查汇报记录

网友评论

      本文标题:一次排查记录

      本文链接:https://www.haomeiwen.com/subject/fpfkaqtx.html