99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

Spring Cloud(七)服務網(wǎng)關 Zuul Filter 使用

2019-04-17 13:59 更新

上一篇文章中,講了Zuul 轉發(fā),動態(tài)路由,負載均衡,等等一些Zuul 的特性,這個一篇文章,講Zuul Filter 使用,關于網(wǎng)關的作用,這里就不再次贅述了,重點是zuul的Filter ,我們可以實現(xiàn)安全控制,比如,只有請求參數(shù)中有token和密碼的客戶端才能訪問服務端的資源。那么如何來實現(xiàn)Filter了?

Spring Cloud Zuul

zuul 執(zhí)行流程

執(zhí)行流程圖

Zuul大部分功能都是通過過濾器來實現(xiàn)的。Zuul中定義了四種標準過濾器類型,這些過濾器類型對應于請求的典型生命周期。

PRE:這種過濾器在請求被路由之前調用。我們可利用這種過濾器實現(xiàn)身份驗證、在集群中選擇請求的微服務、記錄調試信息等。

ROUTING:這種過濾器將請求路由到微服務。這種過濾器用于構建發(fā)送給微服務的請求,并使用Apache HttpClient或Netfilx Ribbon請求微服務。

OST:這種過濾器在路由到微服務以后執(zhí)行。這種過濾器可用來為響應添加標準的HTTP Header、收集統(tǒng)計信息和指標、將響應從微服務發(fā)送給客戶端等。

ERROR:在其他階段發(fā)生錯誤時執(zhí)行該過濾器。

除了默認的過濾器類型,Zuul還允許我們創(chuàng)建自定義的過濾器類型。例如,我們可以定制一種STATIC類型的過濾器,直接在Zuul中生成響應,而不將請求轉發(fā)到后端的微服務。

準備工作

我們先拿之前兩篇文章,構建的兩個微服務代碼為基礎,進行下面的操作

建議先閱讀以下兩篇文章

Spring Cloud(四) 服務提供者 Eureka + 服務消費者 Feign
Spring Cloud(三) 服務提供者 Eureka + 服務消費者(rest + Ribbon)

http://www.ymq.io/2017/12/06/spring-cloud-feign/

http://www.ymq.io/2017/12/05/spring-cloud-ribbon-rest/

Eureka Service

導入第三篇文章中的項目:作為服務注冊中心

spring-cloud-eureka-service

Eureka Provider

導入第三篇文章中的項目:作為服務的提供者

spring-cloud-eureka-provider-1
spring-cloud-eureka-provider-2
spring-cloud-eureka-provider-3

簡單使用

新建項目 spring-cloud-zuul-filter

添加依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>

開啟服務注冊

在程序的啟動類 ZuulFilterApplication 通過 @EnableZuulProxy 開啟 Zuul 服務網(wǎng)關

package io.ymq.example.zuul.filter;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;


@EnableZuulProxy
@SpringBootApplication
public class ZuulFilterApplication {


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

添加配置

配置文件 application.yml

spring:
  application:
    name: zuul-service-filter


server:
  port: 9000


zuul:
  routes:
    api:
        path: /**
        serviceId: eureka-provider


eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

TokenFilter

ZuulFilter 是Zuul中核心組件,通過繼承該抽象類,覆寫幾個關鍵方法達到自定義調度請求的作用

TokenFilter 過濾器

package io.ymq.example.zuul.filter;


import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import javax.servlet.http.HttpServletRequest;


/**
 * 描述: 過濾器 token
 *
 * @author yanpenglei
 * @create 2017-12-11 14:38
 **/
public class TokenFilter extends ZuulFilter {


    private final Logger LOGGER = LoggerFactory.getLogger(TokenFilter.class);


    @Override
    public String filterType() {
        return "pre"; // 可以在請求被路由之前調用
    }


    @Override
    public int filterOrder() {
        return 0; // filter執(zhí)行順序,通過數(shù)字指定 ,優(yōu)先級為0,數(shù)字越大,優(yōu)先級越低
    }


    @Override
    public boolean shouldFilter() {
        return true;// 是否執(zhí)行該過濾器,此處為true,說明需要過濾
    }


    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();


        LOGGER.info("--->>> TokenFilter {},{}", request.getMethod(), request.getRequestURL().toString());


        String token = request.getParameter("token");// 獲取請求的參數(shù)


        if (StringUtils.isNotBlank(token)) {
            ctx.setSendZuulResponse(true); //對請求進行路由
            ctx.setResponseStatusCode(200);
            ctx.set("isSuccess", true);
            return null;
        } else {
            ctx.setSendZuulResponse(false); //不對其進行路由
            ctx.setResponseStatusCode(400);
            ctx.setResponseBody("token is empty");
            ctx.set("isSuccess", false);
            return null;
        }
    }


}

PasswordFilter

ZuulFilter 是Zuul中核心組件,通過繼承該抽象類,覆寫幾個關鍵方法達到自定義調度請求的作用

PasswordFilter 過濾器

package io.ymq.example.zuul.filter;


import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import javax.servlet.http.HttpServletRequest;


/**
 * 描述: 過濾器 Password
 *
 * @author yanpenglei
 * @create 2017-12-11 15:40
 **/
public class PasswordFilter extends ZuulFilter {


    private final Logger LOGGER = LoggerFactory.getLogger(TokenFilter.class);


    @Override
    public String filterType() {
        return "post"; // 請求處理完成后執(zhí)行的filter
    }


    @Override
    public int filterOrder() {
        return 1; // 優(yōu)先級為0,數(shù)字越大,優(yōu)先級越低
    }


    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        return (boolean) ctx.get("isSuccess");
        // 判斷上一個過濾器結果為true,否則就不走下面過濾器,直接跳過后面的所有過濾器并返回 上一個過濾器不通過的結果。
    }


    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();


        LOGGER.info("--->>> PasswordFilter {},{}", request.getMethod(), request.getRequestURL().toString());


        String username = request.getParameter("password");
        if (null != username && username.equals("123456")) {
            ctx.setSendZuulResponse(true);
            ctx.setResponseStatusCode(200);
            ctx.set("isSuccess", true);
            return null;
        } else {
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(400);
            ctx.setResponseBody("The password cannot be empty");
            ctx.set("isSuccess", false);
            return null;
        }
    }
}

開啟過濾器

在程序的啟動類 ZuulFilterApplication 添加 Bean

@Bean
public TokenFilter tokenFilter() {
    return new TokenFilter();
}


@Bean
public PasswordFilter PasswordFilter() {
    return new PasswordFilter();
}

filterType

filterType:返回一個字符串代表過濾器的類型,在zuul中定義了四種不同生命周期的過濾器類型,具體如下:

  • pre:路由之前
  • routing:路由之時
  • post: 路由之后
  • error:發(fā)送錯誤調用
  • filterOrder:過濾的順序
  • shouldFilter:這里可以寫邏輯判斷,是否要過濾,本文true,永遠過濾。
  • run:過濾器的具體邏輯??捎煤軓碗s,包括查sql,nosql去判斷該請求到底有沒有權限訪問。

測試服務

依次啟動項目:

spring-cloud-eureka-service
spring-cloud-eureka-provider-1
spring-cloud-eureka-provider-2
spring-cloud-eureka-provider-3
spring-cloud-zuul-filter

啟動該工程后,訪問服務注冊中心,查看服務是否都已注冊成功:http://localhost:8761/

查看各個服務注冊狀態(tài)

查看 eureka 監(jiān)控,看服務是否都注冊成功

token 測試

訪問:http://127.0.0.1:8761/

步驟一 提示 token is empty

訪問:http://127.0.0.1:9000/

瀏覽器訪問

步驟二 加上token ?token=token-uuid ,已經(jīng)驗證通過了,提示 The password cannot be empty

訪問:http://127.0.0.1:9000/?token=token-uuid

token is empty

password 測試

![The password cannot be empty][3]

加上tokenpassword &password=123456 ,已經(jīng)驗證通過

訪問:http://127.0.0.1:9000/?token=token-uuid&password=123456

F5 刷新,每次都驗證通過,并且負載均衡

Hello Zuul

                

源碼下載

GitHub:https://github.com/souyunku/spring-cloud-examples/tree/master/spring-cloud-zuul-filter

碼云:https://gitee.com/souyunku/spring-cloud-examples/tree/master/spring-cloud-zuul-filter

Contact

  • 作者:鵬磊
  • 出處:http://www.souyunku.com
  • Email:admin@souyunku.com
  • 版權歸作者所有,轉載請注明出處
  • Wechat:關注公眾號,搜云庫,專注于開發(fā)技術的研究與知識分享

    關注公眾號-搜云庫

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號