美文网首页
一次排查记录

一次排查记录

作者: 只是肿态度 | 来源:发表于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。

    相关文章

      网友评论

          本文标题:一次排查记录

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