1. 在数据库中创一个新的表

因为需要存入数据库,所以根据你的实际业务创建这个表,我没弄多大,因为保存不到几天就会删掉。
表名称和字段都随你意:
    表名称:biz_monitor_time 
    id int 5 不是null 主键自增
    request_address varchar 50 不是null 请求地址
    waste_time int 5 不是null 耗费时间
    create_time datetime 默认值now() 不是null 创建时间

2. 根据创建的表生成代码

就是那几个层:mapper、service、serviceImpl、controller
你可以用代码生成器自动生成,当然你也可以手撸,如果你既不想手撸也没有生成器,我把代码会贴在下面,
供你参考:

domain :

package com.cema.manage.project.manage.monitorTime.domain;

/**
 * 统计http请求响应时间表 biz_monitor_time
 *
 * @author reasahi
 * @date 2021-04-27
 */
@TableName(value = "biz_monitor_time")
public class MonitorTime extends Model<MonitorTime> {
    private static final long serialVersionUID = 1L;

    /**
     * 主键
     */
    @TableId(value = "id")
    private Integer id;
    /**
     * 请求地址
     */
    @TableField(value = "request_address")
    private String requestAddress;
    /**
     * 耗费时间
     */
    @TableField(value = "waste_time")
    private Integer wasteTime;
    /**
     * 创建时间
     */
    @TableField(value = "create_time")
    private Date createTime;

    /**
     * 设置:主键
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * 获取:主键
     */
    public Integer getId() {
        return id;
    }

    /**
     * 设置:请求地址
     */
    public void setRequestAddress(String requestAddress) {
        if (requestAddress != null) {
            if (requestAddress.trim().isEmpty()) {
                this.requestAddress = null;
            } else {
                this.requestAddress = requestAddress;
            }
        }
    }

    /**
     * 获取:请求地址
     */
    public String getRequestAddress() {
        return requestAddress;
    }

    /**
     * 设置:耗费时间
     */
    public void setWasteTime(Integer wasteTime) {
        this.wasteTime = wasteTime;
    }

    /**
     * 获取:耗费时间
     */
    public Integer getWasteTime() {
        return wasteTime;
    }

    /**
     * 设置:创建时间
     */
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    /**
     * 获取:创建时间
     */
    public Date getCreateTime() {
        return createTime;
    }

    @Override
    protected Serializable pkVal() {
        return this.id;
    }
}

mapper :

package com.cema.manage.project.manage.monitorTime.mapper;

/**
 * 统计http请求响应时间 数据层
 * 
 * @author reasahi
 * @date 2021-04-27
 */
public interface MonitorTimeMapper  extends BaseMapper<MonitorTime>
{

    void insertMonitorTime(MonitorTime monitorTime);

}

xml :

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cema.manage.project.manage.monitorTime.mapper.MonitorTimeMapper">

    <!--  biz_monitor_time  -->
    <resultMap id="resultMapMonitorTime" type="com.cema.manage.project.manage.monitorTime.domain.MonitorTime">
        <id column="id" property="id"></id>
        <result column="request_address" property="requestAddress"></result>
        <result column="waste_time" property="wasteTime"></result>
        <result column="create_time" property="createTime"></result>
    </resultMap>

    <insert id="insertMonitorTime" parameterType="com.cema.manage.project.manage.monitorTime.domain.MonitorTime">
        INSERT INTO biz_monitor_time (request_address, waste_time)
        VALUES (#{requestAddress}, #{wasteTime});
    </insert>

</mapper>

service :

package com.cema.manage.project.manage.monitorTime.service;

/**
 * 统计http请求响应时间 服务层
 * 
 * @author reasahi
 * @date 2021-04-27
 */
public interface IMonitorTimeService extends IService<MonitorTime>
{

    void insertMonitorTime(MonitorTime monitorTime);
    
}

serviceImpl :
说明:
代码中的 @Async("asyncServiceExecutor") 为异步调用 里面的 asyncServiceExecutor 为自己创建的异步服务执行器的bean的名称,它实际上是一个线程池,我将它丢进去做异步处理,你可以自己撸一个,或者复制别人的,都没关系。如果你不喜欢手撸,那我会贴在下面,供你参考:

package com.cema.manage.project.manage.monitorTime.service;

/**
 * 统计http请求响应时间 服务层实现
 *
 * @author reasahi
 * @date 2021-04-27
 */
@Service
public class MonitorTimeServiceImpl extends ServiceImpl<MonitorTimeMapper, MonitorTime> implements IMonitorTimeService {

    @Resource
    private MonitorTimeMapper monitorTimeMapper;

    @Override
    @Async("asyncServiceExecutor")
    public void insertMonitorTime(MonitorTime monitorTime) {
        monitorTimeMapper.insertMonitorTime(monitorTime);
    }

}

异步任务配置 :

package com.cema.manage.config;

@Configuration
@EnableAsync
public class AsyncTaskConfig  {

    @Bean(name = "asyncServiceExecutor")
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor threadPool = new VisiableThreadPoolTaskExecutor();
        // 设置核心线程数
        threadPool.setCorePoolSize(1000);
        // 设置最大线程数
        threadPool.setMaxPoolSize(1000000);
        // 线程池所使用的缓冲队列
        threadPool.setQueueCapacity(Integer.MAX_VALUE);
        // 等待任务在关机时完成--表明等待所有线程执行完
        threadPool.setWaitForTasksToCompleteOnShutdown(true);
        // 等待时间 (默认为0,此时立即停止),并没等待xx秒后强制停止
        threadPool.setAwaitTerminationSeconds(60);
        // 线程名称前缀
        threadPool.setThreadNamePrefix("Derry-Async-");
        // 初始化线程
        threadPool.initialize();
        return threadPool;
    }

}

controller : 无需变化。

3. 实现拦截器

说明:通过构造方法给 iMonitorTimeService 赋值。

package com.cema.manage.config.Interceptor;

@Component
public class MonitoringTimeInterceptor implements HandlerInterceptor {

    private IMonitorTimeService iMonitorTimeService;

    public MonitoringTimeInterceptor(IMonitorTimeService iMonitorTimeService) {
        this.iMonitorTimeService = iMonitorTimeService;
    }

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        long start = System.currentTimeMillis();
        httpServletRequest.setAttribute("start", start);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        long start = (Long) httpServletRequest.getAttribute("start");
        long end = System.currentTimeMillis() - start;
        String uri = httpServletRequest.getRequestURI();
        MonitorTime monitorTime = new MonitorTime();
        monitorTime.setRequestAddress(uri);
        monitorTime.setWasteTime((int) end);
        iMonitorTimeService.insertMonitorTime(monitorTime);
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    }

}

4. 继承 WebMvc 配置适配器来添加你的拦截器,让它工作

说明:
registry.addInterceptor(这里就是你刚刚写好的拦截器,咱们通过构造函数赋值)。addPathPatterns(这里面填写你需要拦截的url,去看看你的controller层,如:"/pfs/**")。

package com.cema.manage.config;

@Configuration
public class ViewConfigure extends WebMvcConfigurerAdapter {

    @Resource
    private IMonitorTimeService iMonitorTimeService;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // .addPathPatterns("/**") //拦截所有请求/upload/ecology
        registry.addInterceptor(new MonitoringTimeInterceptor(iMonitorTimeService))
                .addPathPatterns("/token/**")
        ;
    }
}

5. 总结

代码部分就完结了,以后进了你拦截器的http请求都会被存入到数据库,如下图:

biz_monitor_time 表数据

你可以根据各接口响应时长来判断是否需要优化。你可以在数据库中使用一些聚合函数来看看最大响应时长的接口,或者某个接口的平均响应时间等。当然,这只是非常简单的拦截器以及数据的存入,你完全可以撸一个更好哒。

byeBye ^ ^~


Sorry
4 声望0 粉丝