首页 > 其他分享 >记一次接口优化操作

记一次接口优化操作

时间:2022-12-01 22:24:19浏览次数:36  
标签:拦截器 请求 数据库 接口 耗时 操作 优化 public

  项目正式上线之后,后期主要是不断地进行版本迭代,开发新的功能。自己参与

开发的项目正式开始使用后,人数还不少,早上高峰期的时候一个接口一个小时的请求

数达到约3万。而且这只是部分用户在进行使用,还没有大规模地放开,服务器已经

开始告警,某一个接口的查询超过四五秒。收到这个信息后,负责人立马让我们查看

日志信息,排查问题。通过命令 grep “接口请求的URL” 日志文件名,查看多台服务

器上面打印的日志信息,发现确实有多台服务器上打印的接口耗时都超过5S以上。

  查看日志的方式是自己在网上搜索的,可是接口耗时却是系统中写的,如何衡量一个

接口的好坏?其中一个指标就是处理请求的能力,可以通过jmeter来做接口的性能测试。

这个在测试阶段,专业的测试人员都已经测试过,肯定是符合要求我们才上生产。可是

现在已经是服务在生产上面跑,在生产阶段,不能在使用那种方式来处理。对于后端

开发人员来说,可以在需要的接口请求中,打印每一次接口的耗时。简单处理方式如下:

首先需要定义一个拦截器:

@Slf4j

public class InterfaceInterceptor implements HandlerInterceptor {

    @Override

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        request.setAttribute("REQUEST_START_TIME", String.valueOf(System.currentTimeMillis()));

        return true;

    }

 

    @Override

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        String requestURI = request.getRequestURI();

        String requestStartTime = (String)request.getAttribute("REQUEST_START_TIME");

        log.info("接口 {} 请求耗时: {} ms", requestURI, System.currentTimeMillis() - Long.parseLong(requestStartTime));

    }

}

重写两个方法,一个方法是在处理请求前调用的preHandle方法,处理逻辑很简单,设置一个固定的变量值,

具体的值设置为当前的时间戳,将其放在请求对象中。接口请求处理完成之后,调用afterCompletion方法,

将之前存入的值取出来,转换为Long类型,然后用当前时间时间戳减去最开始请求的时间戳,就可以计算出单个接口处理的耗时。

接下来写一个简单的测试方法,如下

@Slf4j

@RestController

@RequestMapping("/happy/yilang")

public class TestControlelr {

    @GetMapping("/interface")

    @LcloudThreadLimiter(maxThread="max_thread", waitTime="wait_time")

    public String interfaceTest(){

        return "接口耗时统计";

    }

}

最后将拦截器添加到拦截器配置类中,即是注册拦截器,拦截的指定的路径为/happy/**,可以

按需要进行灵活的配置,如下

@Configuration

public class WebMvcConfig extends WebMvcConfigurerAdapter {

 

    /**

     *  Function:  addInterceptors

     *  Author :  kaye0110,

 *  Version : 1.0

     *  Description : 注册拦截器

     *  Param and Description :

     *  @param registry

     */

    @Override

    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(InterfaceInterceptor()).addPathPatterns("/happy/**");

        super.addInterceptors(registry);

    }

    @Bean

    public InterfaceInterceptor InterfaceInterceptor(){

        return  new InterfaceInterceptor();

    }

}

启动项目,测试结果如下

 

 

 

拿到每一次接口请求的耗时数据,对于性能要求是一个重要的参考指标。每个公司的要求都不一样,有的可能要求1s内返回,

有的可能要求500ms内返回,有的可能要求20ms内返回。根据公司自己的要求,然后来对比接口的耗时,就可以判断出这个

接口的性能如何,是否需要优化。

  自己在排查日志的过程中发现,这个接口就是一个简单的接口,没有做比较复杂的计算操作,就是根据主键ID查询一条数据

信息,为什么会导致这么慢呢?怎么进行优化呢?之后经过仔细分析,发现在请求高峰期的时候,数据库的CPU达到90%多,

因为数据库的性能急剧下降。负责人经过查看数据库服务器的相关信息,普通开发人员没权限看,还发现MQ在快速的大量的

向数据库中写数据, 还有定时任务也在频繁的向数据库写数据,所以导致数据库的性能解决下降。由于起了多台服务器,定时

任务的处理就更加地频繁,如果每间隔两分钟处理一次定时任务,5台服务器两分钟就处理10次。因此就找到对应的解决方案:

.1.扩容数据库;.2.这个接口实时查询数据库修改为从缓存中取数据;.3.增加定时任务的处理时间间隔;4.降低MQ消息消费的流量。

定时将需要查询的所有数据,预先加载到缓存中,然后查询的时候就直接从缓存当中取,不再去查询数据库。通过这几步的优化,

最终很好地解决了这个接口的性能问题。

  如果有其他更好建议的小伙伴,欢迎留言讨论。

标签:拦截器,请求,数据库,接口,耗时,操作,优化,public
From: https://www.cnblogs.com/yilangcode/p/16942979.html

相关文章

  • 操作系统
    操作系统综合操作系统的特征:并发、共享、虚拟、异步 进程管理进程与程序什么是进程1.进程是指在系统中正在运行的一个应用程序,程序一旦运行就是进程;2.进程可以......
  • 前端之DOM操作
    一、概念javascriptjavascript是一种脚本语言,可以被浏览器解析,所以它可以称之为前端的三把利器之一。javascript跟java没有半毛钱关系。声明局部变量:使用关键字var应......
  • 总算给女盆友讲明白了,如何使用stream流的filter()操作
    一、引言在上一篇文章中《这么简单,还不会使用java8stream流的map()方法吗?》分享了使用stream的map()方法,不知道小伙伴还有印象吗,先来回顾下要点,map()方法是把一个流中的......
  • C++输出页面的相关操作
    下文需要用到的头文件等#include<bits/stdc++.h>#include<Windows.h>#include<stdlib.h>#include<time.h>#include<conio.h>#defineintlonglongusingnamesp......
  • 【51cto】top1全栈接口测试教程 jmeter接口测试,接口自动化测试
    测试时优先对其进行结构化拆分,将测试整体拆分为各个场景创建线程组,简单控制器,HTTP请求默认值,HTTP信息头管理器将测试目标结构化,可以更好地管理测试框架和整合其他组件,有利于......
  • 【51cto】top1全栈接口测试教程 jmeter接口测试,接口自动化测试【2】
    延时等待(全局性)api测试⽤例执⾏速度⾮常快,某些时候因为业务的特性想让它延迟⼏秒执⾏,那么这个时候就使⽤延时等待。参数化可以理解为:⼀个测试点需要多次操作,并且每......
  • Linux Bash字符串操作
    1.在SHELL中同时判断多个条件在SHELLif语句中使用"||"和"&&"要用两个独立的[]if[a-gtb]&&[a-ltc]2.判断字符串为空的方法if["$str"=""......
  • css基础操作
    今日内容总结表单标签的补充说明基于form表单发送数据1.用于获取用户数据的标签含有name属性 name属性相当于字典的键用户输入的数据会被保存到标签的value属性......
  • 私藏!资深数据专家SQL效率优化技巧 ⛵
    ......
  • 一次SQL查询优化原理分析:900W+数据,从17s到300ms
    有一张财务流水表,未分库分表,目前的数据量为9555695,分页查询使用到了limit,优化之前的查询耗时16s938ms(execution:16s831ms,fetching:107ms),按照下文的方式调......