Zuul实现请求自定义的过滤转发

本文介绍了在Zuul中实现请求自定义转发的四种方式:修改servletRequest属性绕开ZuulFilter、修改serviceId利用Ribbon转发、通过SimpleHostRouttingFilter实现基于IP的转发以及在Filter内直接实现转发。每种方式的优缺点和实现逻辑进行了详细阐述,最终项目选择了第四种方式,因为它虽然代码量较大,但逻辑简单,易于管理和调试。
摘要由CSDN通过智能技术生成

背景

最近工作中遇到一个场景,前端请求需要根据一个参数hash到固定的某个服务实例上,由于请求转发部分项目中使用的Zuul是通过Ribbon默认进行转发,在Eureka上选取的实例是不一定的,因此需要考虑如何替代Ribbon或其他方案来实现。

在实现过程中发现方式比较多,将常见的几种记录一下,大体的思路都是通过filter识别匹配到请求,要么绕开Zuul,要么能够告诉Zuul让其用指定的ip进行请求的发送。

实现方式一:定义一个Filter,修改servletRequest属性,绕开ZuulFilter进行自定义的转发

在Debug过程汇总,Filter的执行优先级高于ZuulFilter,因此考虑如果不希望ZuulFilter对请求进行转发处理,是否可以在ZuulFilter之前就对请求进行截获,通过跟踪源码发现,请求到达后会在DispatcherServlet中根据request的特征选择对应的handler进行处理,如下:

				// Determine handler for the current request.
				mappedHandler = getHandler(processedRequest);
				if (mappedHandler == null) {
   
					noHandlerFound(processedRequest, response);
					return;
				}

选择出对应的mappedHandler后会通过调用执行对应的逻辑,如下:

				// Determine handler adapter for the current request.
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

在决定使用哪一个hanlder的逻辑如下:

	protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
   
		if (this.handlerMappings != null) {
   
			for (HandlerMapping mapping : this.handlerMappings) {
   
				HandlerExecutionChain handler = mapping.getHandler(request);
				if (handler != null) {
   
					return handler;
				}
			}
		}
		return null;
	}

其中hanlderMappings中包含进程中经所有可用的hanlder,如下:
在这里插入图片描述
网关在集成zuul+ribbon后,默认会将请求的URL进行拆分,根据zuul配置的路由规则以及从Ribbon同步的服务实例列表进行比对,看看会否匹配,如果匹配,则就请求就会被ZuulHandlerMapping截获。
在这里插入图片描述
为了让请求绕开zuul的截获规则,需要看下源码中getHandler如何返回对应的handler,如下:

		// Pattern match?
		List<String> matchingPatterns = new ArrayList<>();
		for (String registeredPattern : this.handlerMap.keySet()) {
   
			if (getPathMatcher().match(registeredPattern, urlPath)) {
   
				matchingPatterns.add(registeredPattern);
			}
			else if (useTrailingSlashMatch()) {
   
				if (!registeredPattern.endsWith("/") && getPathMatcher().match(registeredPattern + "/", urlPath)) {
   
					matchingPatterns.add(registeredPattern + "/");
				}
			}
		}

		if (!matchingPatterns.isEmpty()) {
   
			matchingPatterns.sort(patternComparator);
			if (logger.isTraceEnabled() && matchingPatterns.size() > 1) {
   
				logger
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值