欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

springboot基于過濾器實(shí)現(xiàn)接口請求耗時(shí)統(tǒng)計(jì)操作

 更新時(shí)間:2020年09月26日 09:58:40   作者:ye17186  
這篇文章主要介紹了springboot基于過濾器實(shí)現(xiàn)接口請求耗時(shí)統(tǒng)計(jì)操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧

Spring Boot中實(shí)現(xiàn)一個(gè)過濾器相當(dāng)簡單,實(shí)現(xiàn)javax.servlet.Filter接口即可。

下面以實(shí)現(xiàn)一個(gè)記錄接口訪問日志及請求耗時(shí)的過濾器為例:

1、定義ApiAccessFilter類,并實(shí)現(xiàn)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 = IdGenUtils.nextIdByMem(); // 請求ID,這個(gè)是我業(yè)務(wù)中的id,大家可自行決定是否需要
    long start = System.currentTimeMillis(); // 請求進(jìn)入時(shí)間
 
    log.info("[Api Access] start. id: {}, uri: {}, method: {}, client: {}", requestId,
      request.getRequestURI(), request.getMethod(), getIP(request));
    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發(fā)起客戶端的IP地址
   */
  private String getIP(HttpServletRequest request) {
    if (request == null) {
      return "0.0.0.0";
    }
 
    String Xip = request.getHeader("X-Real-IP");
    String XFor = request.getHeader("X-Forwarded-For");
 
    String UNKNOWN_IP = "unknown";
    if (StringUtils.isNotEmpty(XFor) && !UNKNOWN_IP.equalsIgnoreCase(XFor)) {
      //多次反向代理后會(huì)有多個(gè)ip值,第一個(gè)ip才是真實(shí)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 = request.getHeader("Proxy-Client-IP");
    }
    if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
      XFor = request.getHeader("WL-Proxy-Client-IP");
    }
    if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
      XFor = request.getHeader("HTTP_CLIENT_IP");
    }
    if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
      XFor = request.getHeader("HTTP_X_FORWARDED_FOR");
    }
    if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
      XFor = request.getRemoteAddr();
    }
    return XFor;
  }
}

2、啟用該過濾器

springboot中兩種啟用過濾器的方式,第一種在FilterRegistrationBean中注冊該Filter,第二種,采用注解的方式啟用

個(gè)人覺得注冊方式比較麻煩,所有本例中使用的是第二種。

在Filter中添加注解@WebFilter(filterName = "ApiAccessFilter", urlPatterns = "/*"),配置了過濾器名和需要過濾的請求地址,/*表示過濾所有請求。然后在啟動(dòng)類上,通過@ServletComponentScan注解,指明該過濾器即可

@SpringBootApplication
@ServletComponentScan("com.yclouds.service.demo")
public class YCloudsServiceDemoApplication {
 
  public static void main(String[] args) {
    SpringApplication.run(YCloudsServiceDemoApplication.class, args);
  }
}

3、效果展示

發(fā)送了兩次http請求,每次都會(huì)打印日志內(nèi)容,并且統(tǒng)計(jì)了整個(gè)請求的耗時(shí)情況。

GitHub地址:https://github.com/ye17186/spring-boot-learn

補(bǔ)充知識:spring cloud gateway 之zuul通過filter配置接口請求的時(shí)間耗時(shí)記錄到日志

zuul中的Filter的配置,zuul中提供了三種類型的Filter,preFilter,routeFilter和postFilter,分別對應(yīng)請求中的不同的階段,針對同一個(gè)請求,有一個(gè)RequestContext對象,在三個(gè)階段的Filter中進(jìn)行共享

假設(shè)我們要開發(fā)一個(gè)統(tǒng)計(jì)請求時(shí)間的功能,需要在preFilter里邊記錄開始時(shí)間,并將整個(gè)開始時(shí)間放在RequestContext中,在postFilter里邊拿到開始時(shí)間,用當(dāng)前的時(shí)間減去開始時(shí)間,就是請求執(zhí)行的時(shí)間

定義一個(gè)preFilter:

package com.jiaoyiping.springcloud.zuul.filter; 
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.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 = LoggerFactory.getLogger(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();
    RequestContext.getCurrentContext().set(START_TIME_KEY, startTime);
    return null;
  }
}

定義以postFilter:

package com.jiaoyiping.springcloud.zuul.filter; 
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.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 = LoggerFactory.getLogger(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) RequestContext.getCurrentContext().get(START_TIME_KE);
    logger.info("請求完成,耗時(shí){}秒", (System.currentTimeMillis() - startTime) / 1000);
    return null;
  }
}

在一個(gè)配置類中將這兩個(gè)Filter注入:

package com.jiaoyiping.springcloud.zuul.config; 
import com.jiaoyiping.springcloud.zuul.filter.PDSFilter;
import com.jiaoyiping.springcloud.zuul.filter.TimeCostPostFilter;
import com.jiaoyiping.springcloud.zuul.filter.TimeCostPreFilter;
import com.netflix.zuul.ZuulFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.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();
  }
}

啟動(dòng)項(xiàng)目,可以發(fā)現(xiàn),zuul網(wǎng)關(guān)已經(jīng)注冊到了eureka上:

請求provide對應(yīng)的地址,發(fā)現(xiàn),zuul可以成功地調(diào)用eureka上對應(yīng)的服務(wù),并將結(jié)果正確返回:

以上這篇springboot基于過濾器實(shí)現(xiàn)接口請求耗時(shí)統(tǒng)計(jì)操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 微信APP支付Java代碼

    微信APP支付Java代碼

    這篇文章主要為大家詳細(xì)介紹了微信APP支付Java代碼,感興趣的小伙伴們可以參考一下
    2016-07-07
  • Eclipse創(chuàng)建java程序可執(zhí)行jar包教程

    Eclipse創(chuàng)建java程序可執(zhí)行jar包教程

    這篇文章主要為大家分享了Eclipse創(chuàng)建java程序可執(zhí)行jar包教程,具有一定的實(shí)用性和參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-05-05
  • Java使用線程實(shí)現(xiàn)異步運(yùn)行的方法

    Java使用線程實(shí)現(xiàn)異步運(yùn)行的方法

    在Java中,實(shí)現(xiàn)異步運(yùn)行的一個(gè)常用方式是使用Thread類,這篇文章主要介紹了Java使用線程實(shí)現(xiàn)異步運(yùn)行,需要的朋友可以參考下
    2024-07-07
  • Java中的深拷貝和淺拷貝介紹

    Java中的深拷貝和淺拷貝介紹

    對象拷貝(Object Copy)就是將一個(gè)對象的屬性拷貝到另一個(gè)有著相同類類型的對象中去。在程序中拷貝對象是很常見的,主要是為了在新的上下文環(huán)境中復(fù)用對象的部分或全部 數(shù)據(jù)。Java中有三種類型的對象拷貝:淺拷貝(Shallow Copy)、深拷貝(Deep Copy)、延遲拷貝(Lazy Copy)
    2014-03-03
  • Java的Spring?AOP詳細(xì)講解

    Java的Spring?AOP詳細(xì)講解

    章主要為大家詳細(xì)介紹了Java的Spring?AOP,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • 新版SpringSecurity5.x使用與配置詳解

    新版SpringSecurity5.x使用與配置詳解

    Spring Security是一個(gè)強(qiáng)大且高度可定制的身份驗(yàn)證和訪問控制框架,本文主要介紹了新版SpringSecurity5.x使用與配置詳解,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-08-08
  • 一文盤點(diǎn)五種最常用的Java加密算法

    一文盤點(diǎn)五種最常用的Java加密算法

    大家平時(shí)的工作中,可能也在很多地方用到了加密、解密,比如:支付功能等,所以本文為大家盤點(diǎn)了Java中五個(gè)常用的加密算法,希望對大家有所幫助
    2023-06-06
  • Java學(xué)習(xí)教程之定時(shí)任務(wù)全家桶

    Java學(xué)習(xí)教程之定時(shí)任務(wù)全家桶

    這篇文章主要給大家介紹了關(guān)于Java學(xué)習(xí)教程之定時(shí)任務(wù)全家桶的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Java this、final等關(guān)鍵字總結(jié)

    Java this、final等關(guān)鍵字總結(jié)

    這篇文章主要對java中this、final等關(guān)鍵字進(jìn)行了總結(jié),需要的朋友可以參考下
    2017-04-04
  • java實(shí)現(xiàn)彈球小游戲

    java實(shí)現(xiàn)彈球小游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)彈球小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06

最新評論