最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

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(); // 請(qǐng)求ID,這個(gè)是我業(yè)務(wù)中的id,大家可自行決定是否需要
    long start = System.currentTimeMillis(); // 請(qǐng)求進(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 請(qǐng)求
   * @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、啟用該過(guò)濾器

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

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

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

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

3、效果展示

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

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

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

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

假設(shè)我們要開(kāi)發(fā)一個(gè)統(tǒng)計(jì)請(qǐng)求時(shí)間的功能,需要在preFilter里邊記錄開(kāi)始時(shí)間,并將整個(gè)開(kāi)始時(shí)間放在RequestContext中,在postFilter里邊拿到開(kāi)始時(shí)間,用當(dāng)前的時(shí)間減去開(kāi)始時(shí)間,就是請(qǐng)求執(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("請(qǐng)求完成,耗時(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)注冊(cè)到了eureka上:

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

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

相關(guān)文章

  • 教你怎么用Java通過(guò)關(guān)鍵字修改pdf

    教你怎么用Java通過(guò)關(guān)鍵字修改pdf

    此方法只適合通過(guò)關(guān)鍵字位置,在pdf上添加字符直接上代碼,代碼比較長(zhǎng),大部分自己的理解都在代碼注釋中了,需要的朋友可以參考下
    2021-05-05
  • Struts2框架初學(xué)接觸

    Struts2框架初學(xué)接觸

    本文主要給大家從初學(xué)者的角度介紹了Struts2框架結(jié)構(gòu)和基本頁(yè)面代碼等內(nèi)容,一起來(lái)學(xué)習(xí)一下。
    2017-11-11
  • SpringBoot整合mybatis常見(jiàn)問(wèn)題(小結(jié))

    SpringBoot整合mybatis常見(jiàn)問(wèn)題(小結(jié))

    這篇文章主要介紹了SpringBoot整合mybatis常見(jiàn)問(wèn)題(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Java中excel表數(shù)據(jù)的批量導(dǎo)入方法

    Java中excel表數(shù)據(jù)的批量導(dǎo)入方法

    這篇文章主要為大家詳細(xì)介紹了Java中excel表數(shù)據(jù)的批量導(dǎo)入方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • 詳解Java的call by value和call by reference

    詳解Java的call by value和call by reference

    在本篇文章里小編給大家總結(jié)了關(guān)于Java的call by value和call by reference的相關(guān)用法和知識(shí)點(diǎn)內(nèi)容,需要的朋友們學(xué)習(xí)下。
    2019-03-03
  • java判斷用戶輸入的是否至少含有N位小數(shù)的實(shí)例

    java判斷用戶輸入的是否至少含有N位小數(shù)的實(shí)例

    下面小編就為大家分享一篇java判斷用戶輸入的是否至少含有N位小數(shù)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • idea中Maven鏡像源詳細(xì)配置步驟記錄(對(duì)所有項(xiàng)目)

    idea中Maven鏡像源詳細(xì)配置步驟記錄(對(duì)所有項(xiàng)目)

    Maven是一個(gè)能使我們的java程序開(kāi)發(fā)節(jié)省時(shí)間和精力,是開(kāi)發(fā)變得相對(duì)簡(jiǎn)單,還能使開(kāi)發(fā)規(guī)范化的工具,下面這篇文章主要給大家介紹了關(guān)于idea中Maven鏡像源詳細(xì)配置(對(duì)所有項(xiàng)目)的相關(guān)資料,需要的朋友可以參考下
    2023-05-05
  • Java異常報(bào)錯(cuò):java.nio.file.FileSystemException的多種解決方案

    Java異常報(bào)錯(cuò):java.nio.file.FileSystemException的多種解決方案

    在Java應(yīng)用程序中處理文件和目錄時(shí),java.nio.file.FileSystemException是一個(gè)常見(jiàn)的異常,這個(gè)異常發(fā)生在嘗試進(jìn)行文件系統(tǒng)操作時(shí),本文將詳細(xì)探討FileSystemException的成因,并提供多種解決方案,需要的朋友可以參考下
    2024-12-12
  • 使用Java的方式模擬Flutter的Widget實(shí)現(xiàn)多層括號(hào)嵌套

    使用Java的方式模擬Flutter的Widget實(shí)現(xiàn)多層括號(hào)嵌套

    這篇文章主要介紹了使用Java的方式模擬Flutter的Widget的實(shí)現(xiàn)多層括號(hào)嵌套問(wèn)題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-07-07
  • Spring?Boot?整合?Reactor實(shí)例詳解

    Spring?Boot?整合?Reactor實(shí)例詳解

    這篇文章主要為大家介紹了Spring?Boot?整合?Reactor實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09

最新評(píng)論

荆州市| 宾阳县| 萍乡市| 安顺市| 宾川县| 阳信县| 顺义区| 调兵山市| 无为县| 浪卡子县| 北海市| 五华县| 昂仁县| 枣阳市| 江孜县| 沈阳市| 花莲市| 泰顺县| 尼木县| 吴川市| 花莲市| 宝坻区| 和平区| 镇沅| 喀什市| 民县| 通州区| 顺平县| 谷城县| 葵青区| 宁国市| 黄骅市| 平果县| 西安市| 郁南县| 梁山县| 涟源市| 大连市| 清涧县| 九江县| 云南省|