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请求都会被存入到数据库,如下图:
你可以根据各接口响应时长来判断是否需要优化。你可以在数据库中使用一些聚合函数来看看最大响应时长的接口,或者某个接口的平均响应时间等。当然,这只是非常简单的拦截器以及数据的存入,你完全可以撸一个更好哒。
byeBye ^ ^~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。