springboot基于过滤器实现接⼝请求耗时统计操作Spring Boot中实现⼀个过滤器相当简单,实现javax.servlet.Filter接⼝即可。
下⾯以实现⼀个记录接⼝访问⽇志及请求耗时的过滤器为例:
1、定义ApiAccessFilter类,并实现Filter接⼝
@Slf4j
@WebFilter(filterName = "ApiAccessFilter", urlPatterns = "/*")
public class ApiAccessFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
Long requestId = IdByMem(); // 请求ID,这个是我业务中的id,⼤家可⾃⾏决定是否需要
long start = System.currentTimeMillis(); // 请求进⼊时间
log.info("[Api Access] start. id: {}, uri: {}, method: {}, client: {}", requestId,
filterChain.doFilter(servletRequest, servletResponse);
log.info("[Api Access] end. id: {}, duration: {}ms", requestId,
System.currentTimeMillis() - start);
}
@Override
public void destroy() {
}
/**
* 获取IP地址
*
* @param request 请求
* @return request发起客户端的IP地址
*/
private String getIP(HttpServletRequest request) {
if (request == null) {
return "0.0.0.0";
}
String Xip = Header("X-Real-IP");
String XFor = Header("X-Forwarded-For");
String UNKNOWN_IP = "unknown";
if (StringUtils.isNotEmpty(XFor) && !UNKNOWN_IP.equalsIgnoreCase(XFor)) {
//多次反向代理后会有多个ip值,第⼀个ip才是真实ip
int index = XFor.indexOf(",");
if (index != -1) {
return XFor.substring(0, index);
} else {
return XFor;
}
}
XFor = Xip;
if (StringUtils.isNotEmpty(XFor) && !UNKNOWN_IP.equalsIgnoreCase(XFor)) {
return XFor;
}
if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
XFor = Header("Proxy-Client-IP");
springcloud和springboot}
if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
XFor = Header("WL-Proxy-Client-IP");
}
if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
XFor = Header("HTTP_CLIENT_IP");
}
if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
XFor = Header("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
XFor = RemoteAddr();
}
return XFor;
}
}
2、启⽤该过滤器
springboot中两种启⽤过滤器的⽅式,第⼀种在FilterRegistrationBean中注册该Filter,第⼆种,采⽤注解的⽅式启⽤
个⼈觉得注册⽅式⽐较⿇烦,所有本例中使⽤的是第⼆种。
在Filter中添加注解@WebFilter(filterName = "ApiAccessFilter", urlPatterns = "/*"),配置了过滤器名和需要过滤的请求地址,/*表⽰过滤所有请求。然后在启动类上,通过@ServletComponentScan注解,指明该过滤器即可
@SpringBootApplication
@ServletComponentScan("louds.service.demo")
public class YCloudsServiceDemoApplication {
public static void main(String[] args) {
SpringApplication.run(YCloudsServiceDemoApplication.class, args);
}
}
3、效果展⽰
发送了两次http请求,每次都会打印⽇志内容,并且统计了整个请求的耗时情况。
补充知识:spring cloud gateway 之zuul通过filter配置接⼝请求的时间耗时记录到⽇志
zuul中的Filter的配置,zuul中提供了三种类型的Filter,preFilter,routeFilter和postFilter,分别对应请求中的不同的阶段,针对同⼀个请求,有⼀个RequestContext对象,在三个阶段的Filter中进⾏共享
假设我们要开发⼀个统计请求时间的功能,需要在preFilter⾥边记录开始时间,并将整个开始时间放在RequestContext中,在postFilter⾥边拿到开始时间,⽤当前的时间减去开始时间,就是请求执⾏的时间
定义⼀个preFilter:
package com.jiaoyiping.springcloud.zuul.filter;
import comflix.zuul.ZuulFilter;
import t.RequestContext;
import ption.ZuulException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloudflix.zuul.filters.support.FilterConstants;
/**
* Created with Intellij IDEA
*
* @author:
* Mail:
* Date:
* Time:
* To change this template use File | Settings | Editor | File and Code Templates */
public class TimeCostPreFilter extends ZuulFilter {
public static final String START_TIME_KEY = "start_time";
private Logger logger = Logger(TimeCostPreFilter.class);
@Override
public String filterType() {
return FilterConstants.PRE_TYPE;
}
@Override
public int filterOrder() {
return 0;
}
/**
* 判断是否要拦截的逻辑
*
* @return
*/
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
long startTime = System.currentTimeMillis();
return null;
}
}
定义以postFilter:
package com.jiaoyiping.springcloud.zuul.filter;
import comflix.zuul.ZuulFilter;
import t.RequestContext;
import ption.ZuulException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloudflix.zuul.filters.support.FilterConstants;
/**
* Created with Intellij IDEA
*
* @author:
* Mail:
* Date:
* Time:
* To change this template use File | Settings | Editor | File and Code Templates */
public class TimeCostPostFilter extends ZuulFilter {
private static final String START_TIME_KE = "start_time";
private Logger logger = Logger(TimeCostPostFilter.class); @Override
public String filterType() {
return FilterConstants.POST_TYPE;
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
long startTime = (long) CurrentContext().get(START_TIME_KE);
logger.info("请求完成,耗时{}秒", (System.currentTimeMillis() - startTime) / 1000);
return null;
}
}
在⼀个配置类中将这两个Filter注⼊:
package com.jiaoyiping.fig;
import com.jiaoyiping.springcloud.zuul.filter.PDSFilter;
import com.jiaoyiping.springcloud.zuul.filter.TimeCostPostFilter;
import com.jiaoyiping.springcloud.zuul.filter.TimeCostPreFilter;
import comflix.zuul.ZuulFilter;
import t.annotation.Bean;
import t.annotation.Configuration;
/**
* Created with Intellij IDEA
*
* @author:
* Mail:
* Date:
* Time:
* To change this template use File | Settings | Editor | File and Code Templates
*/
@Configuration
public class FilterConfig {
@Bean
public ZuulFilter timeCostPreFilter() {
return new TimeCostPreFilter();
}
@Bean
public ZuulFilter timeCostPostFilter() {
return new TimeCostPostFilter();
}
@Bean
public ZuulFilter pdsFilter() {
return new PDSFilter();
}
}
启动项⽬,可以发现,zuul⽹关已经注册到了eureka上:
请求provide对应的地址,发现,zuul可以成功地调⽤eureka上对应的服务,并将结果正确返回:
以上这篇springboot基于过滤器实现接⼝请求耗时统计操作就是⼩编分享给⼤家的全部内容了,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论