中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

springboot使用過濾器實現接口請求耗時統計操作

發布時間:2020-10-30 15:47:23 來源:億速云 閱讀:1326 作者:Leah 欄目:開發技術

這篇文章將為大家詳細講解有關springboot使用過濾器實現接口請求耗時統計操作,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

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 = IdGenUtils.nextIdByMem(); // 請求ID,這個是我業務中的id,大家可自行決定是否需要
    long start = System.currentTimeMillis(); // 請求進入時間
 
    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發起客戶端的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)) {
      //多次反向代理后會有多個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 = 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,第二種,采用注解的方式啟用

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

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

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

3、效果展示

springboot使用過濾器實現接口請求耗時統計操作

發送了兩次http請求,每次都會打印日志內容,并且統計了整個請求的耗時情況。

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

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

zuul中的Filter的配置,zuul中提供了三種類型的Filter,preFilter,routeFilter和postFilter,分別對應請求中的不同的階段,針對同一個請求,有一個RequestContext對象,在三個階段的Filter中進行共享

springboot使用過濾器實現接口請求耗時統計操作

假設我們要開發一個統計請求時間的功能,需要在preFilter里邊記錄開始時間,并將整個開始時間放在RequestContext中,在postFilter里邊拿到開始時間,用當前的時間減去開始時間,就是請求執行的時間

定義一個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("請求完成,耗時{}秒", (System.currentTimeMillis() - startTime) / 1000);
    return null;
  }
}

在一個配置類中將這兩個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();
  }
}

啟動項目,可以發現,zuul網關已經注冊到了eureka上:

springboot使用過濾器實現接口請求耗時統計操作

請求provide對應的地址,發現,zuul可以成功地調用eureka上對應的服務,并將結果正確返回:

springboot使用過濾器實現接口請求耗時統計操作

關于springboot使用過濾器實現接口請求耗時統計操作就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

云梦县| 河间市| 顺平县| 柳林县| 秭归县| 宁安市| 黔南| 常德市| 牙克石市| 隆子县| 扎鲁特旗| 白朗县| 尚义县| 弋阳县| 宁陕县| 左云县| 蕉岭县| 察哈| 涿鹿县| 曲沃县| 宁城县| 星座| 沙湾县| 定边县| 遵义市| 延庆县| 金塔县| 宜州市| 大丰市| 营口市| 尉犁县| 息烽县| 兖州市| 金川县| 桂平市| 大庆市| 盐池县| 宁明县| 本溪市| 石门县| 景宁|