ゲートウェイサービス(zuul)がルーティングフィルタリングを設定する(ZuulFilter)

週末にメモを取る

ZuulFilterのライフサイクル

ここに画像の説明を挿入

フィルタタイプfilterType

Zuulのフィルターは、以前に使用したjavax.servlet.Filterとは異なります。javax.servlet.Filterのタイプは1つだけであり、対応する要求はurlPatternsを構成することでインターセプトできます。

Zuulには合計4種類のフィルターがあり、それぞれの種類に対応する使用シナリオがあります。
1)
リクエストがルーティングされる前にpreを呼び出すことができます。ID認証のシナリオに適用可能で、認証に合格した後、次のプロセスに進みます。
2)ルート
は、リクエストをルーティングするときに呼び出されます。これはグレースケールの公開シナリオに適しており、ルーティングが実行されようとしているときにいくつかのカスタムロジックを実行できます。
3)post
は、ルートおよびエラーフィルターの後に呼び出されます。このフィルターは、リクエストが特定のサービスにルーティングされた後に実行されます。応答ヘッダーの追加や応答ログの記録などのアプリケーションシナリオに適しています。
4)
リクエストの処理中にエラーが発生すると、エラーが呼び出されます。実行中にエラーを送信すると、エラーフィルタに入り、エラー情報を一律に記録するために使用できます。

package com.cloudyoung.zuul.filter;

import com.cloudyoung.zuul.service.RedisService;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;

@Configuration
public class PreFilter  extends  ZuulFilter {
    
    


    private final String Shiro_Session="shiro:session:";

    @Resource
    private RedisService redisService;

    private static Logger log = LoggerFactory.getLogger(PreFilter.class);
    /**
     * 请求前处理
     * @return
     */
    @Override
    public String filterType() {
    
    
        return "pre";
    }

    @Override
    public int filterOrder() {
    
    
        return  PRE_DECORATION_FILTER_ORDER - 1;
    }


    /**
     * 是否需要过滤  true 默认false
     * @return
     */
    @Override
    public boolean shouldFilter() {
    
    
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String requestUrl = request.getRequestURL().toString();
        // 请求URL内不包含login或join则需要经过该过滤器,即执行run()
        return !requestUrl.contains("login") && !requestUrl.contains("logout");
    }

    @Override
    public Object run() throws ZuulException {
    
    
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        log.info(String.format("%s 方式请求 %s", request.getMethod(), request.getRequestURL().toString()));
        //获取传来的参数accessToken
       // Object accessToken = request.getParameter("Authorization");
        Object accessToken = request.getHeader("Authorization");
        if(accessToken == null) {
    
    
            log.warn("Authorization token is empty");
            //过滤该请求,不往下级服务去转发请求,到此结束
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            ctx.setResponseBody("{\"result\":\"Authorization is empty!\"}");
            return null;
        }else if(accessToken!=null && !accessToken.equals("")){
    
    
            String key = String.valueOf(accessToken);
            String result = redisService.get(Shiro_Session+key);
            boolean notBlank = StringUtils.isNotBlank(result);
            if(notBlank){
    
    
                ctx.setSendZuulResponse(true);
                ctx.setResponseStatusCode(200);
                //如果有token,则进行路由转发
                log.info("Authorization token ok");
            }else{
    
    
                ctx.setSendZuulResponse(false);
                ctx.setResponseStatusCode(401);
                ctx.setResponseBody("{\"result\":\"Authorization is unefftive!\"}");
            }
        }
        return null;

    }
}

RequestContextを使用してパラメーターを渡す

		RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();


		/过滤该请求,不往下级服务去转发请求,到此结束		
		 ctx.setSendZuulResponse(false);

このフィルターは、ルートに入った後にのみ要求パスをフィルターします。(api / serach /またはapi / portrait /の後のリクエストのみがフィルタリングされます)
yml構成

#添加路由前缀 api
zuul:
  prefix: /api
  routes:
    ai-serach:
      path: /serach/**
      serviceId: ai-serach
    ai-portrait:
          path: /portrait/**
          serviceId: ai-portrait
  add-host-header: true #添加host头信息
  sensitive-headers:    #敏感头信息
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 12000   #熔断 超时时长 5000ms

#ribbon的默认超时时长:(read + connect) * 2, 必须小于hystrix的时长
ribbon:
  ConnectionTimeOut: 5000   #ribbon 链接超时时长
  ReadTimeout: 5000   #ribbon 读取超时时长
  MaxAutoRetries: 0   #ribbon 当前服务重试次数
  MaxAutoRetriesNextServer: 0   #ribbon 切换服务重试次数

おすすめ

転載: blog.csdn.net/qq_38893133/article/details/104727839