Spring Cloud Gateway (六) 自定義 Global Filter


Spring Cloud Gateway (六) 自定義 Global Filter


簡介

    在前面五篇的分析中,對 Spring Cloud Gateway 的 filter 組件有了一個大概的認知,今天就練練手,寫一個統計請求返回時長的 global filter

思路整理

    閱讀官方文檔和在前面讀源碼的過程中,大致知道 global filter 需要繼承 GlobalFilter 、 Ordered

  • GlobalFilter : 需要重寫 filter 方法,在其中實現自己的處理邏輯,很大部分都是對 exchange 進行操作,取值賦值等等
  • Ordered : 需要重寫 getOrder 方法,決定自定義 filter 在鏈中的位置,按照數字大小進行的排序

自定義時長統計 filter 編寫

    這里就簡單的借鑒下 GatewayMetricsFilter 的寫法,在 filter 鏈觸發完成后,無論失敗或者成功,都進行統計。filter 次序就簡單的取 WRITE_RESPONSE_FILTER_ORDER 之后(用它定義的次序減一)。代碼大致如下:

/**
 * 統計一次請求在filter鏈中的時長
 *
 * @author lw1243925457
 */
public class DurationStatisticsFilter implements GlobalFilter, Ordered {

	private static final Log log = LogFactory.getLog(DurationStatisticsFilter.class);
	private static final String START_STAMP = "startStamp";

	/**
	 * 請求響應時長統計
	 * 1.首先將請求進來時的時間戳寫入到 exchange中
	 * 2.filter鏈走完后,無論成功或者失敗,都視為完成,從exchange取出開始時間戳,打印時長信息
	 * @param exchange the current server exchange
	 * @param chain provides a way to delegate to the next filter
	 * @return mono
	 */
	@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		log.debug("duration statistics filter");

		exchange.getAttributes().put(START_STAMP, System.currentTimeMillis());
		return chain.filter(exchange)
				.doFinally(f -> printDurationTime(exchange));
	}

	private void printDurationTime(ServerWebExchange exchange) {
		long startStamp = exchange.getAttribute(START_STAMP);
		long endStamp = System.currentTimeMillis();
		log.debug("duration filter time : " + (endStamp - startStamp) + " ms");
	}

	/**
	 * 這里簡單位於 NettyWriteResponseFilter 之后吧
	 * @return order
	 */
	@Override
	public int getOrder() {
		return WRITE_RESPONSE_FILTER_ORDER - 1;
	}
}

主函數配置運行

    需要在主函數中配置 bean,整個代碼大致如下:

@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}

	@Bean
	public RouteLocator myRoutes(RouteLocatorBuilder builder) {
		return builder.routes()
				.route(p -> p
						.path("/")
						.filters(f -> f
								.addRequestParameter("test", "test")
								.addResponseHeader("return", "return")
								.retry(retryConsumer)
						)
						.uri("http://localhost:8082/"))
				.build();
	}

	@Bean
	public GlobalFilter durationStatisticsFilter() {
		return new DurationStatisticsFilter();
	}
}

    很簡單,大致就這些,運行起來,瀏覽器訪問,可以看到下面的輸出,over

o.s.c.g.sample.DurationStatisticsFilter  : duration statistics filter
o.s.c.g.sample.DurationStatisticsFilter  : duration filter time : 349 ms

Filter 相關分析記錄


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM