SpringCloud無廢話入門05:Spring Cloud Gateway路由、filter、熔斷

1.什麼是路由網關html

        截至目前爲止的例子中,咱們建立了一個service,叫作:HelloService,而後咱們把它部署到了兩臺服務器(即提供了兩個provider),而後咱們又使用ribbon將其作了負載均衡。目前爲止這一切都看上運做的很好,咱們經過地址訪問地址http://localhost:9291/hello,實際是路由到了http://localhost:9191/hello和http://localhost:9192/hello兩個服務器上。前端

        緊接着,隨着業務更進一步,咱們又建立了UserService,又建立了ProductService,咱們提供的服務器也愈來愈多,可是咱們發現一個問題,即:即提供一種服務,前端程序員都須要經過IP+端口的形式去訪問,很快URL地址就多的爆炸了,並且,甚至某些別有用心的同窗由於知道了這些目標地址,開始採用很是規的手段去作些壞事。因此,咱們必須作些手段來規避這些糟糕的事情。程序員

        路由網關出現了。web

        當咱們輸入URL,好比zuikc.com/hello或者zuikc.com/user的時候,路由網關會去分析這個地址,而且根據地址的pattern,spring

        1:去決定究竟是訪問helloservice仍是userservice;apache

        2:到eureka註冊中心拿到該服務的id;服務器

        3:經過ribbon去訪問該服務id中的一臺provider;架構

        4:拿到response,返回給調用者;app

        而且,因爲路由網關能作這些事情,還有額外的一些事情,好比權限驗證(shiro,springsecurity等),就自然的適合放到路由網關也一併實現了。負載均衡

        關於路由網關,之前有zuul,可是zuul已經中止更新了,Spring Cloud Gateway被Spring Cloud官方推出來,做爲第二代網關框架,取代Zuul網關。

        總結一下,路由網關的做用就是:路由轉發、權限校驗、限流控制。

2.路由網關原理

        來看Spring Cloud Gateway官方提供的架構圖,

        客戶端向Spring Cloud Gateway發出請求。 Gateway Handler Mapping匹配路徑並將其發送到Gateway web handler處理。 Gateway web handler處理請求,將其發送給過濾器鏈。 

        過濾器鏈主要分兩大類:pre和post。「pre」過濾器通常進行權限、限流、日誌輸出等功能,以及請求頭的更改、協議的轉換;「post」過濾器是在收到響應後,能夠對響應數據作統一修改,好比響應頭、協議的轉換等。

3.實現

        如今,讓咱們用代碼實現一下吧。

        首先,建立子模塊,在咱們的例子中,建立完畢後,解決方案像以下這樣,

        如今,導入依賴以下:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <parent>

        <artifactId>springcloud.parent</artifactId>

        <groupId>com.zuikc</groupId>

        <version>1.0-SNAPSHOT</version>

    </parent>

    <modelVersion>4.0.0</modelVersion>

    <packaging>war</packaging>

    <name>gateway</name>

    <artifactId>gateway</artifactId>

    <dependencyManagement>

        <dependencies>

            <dependency>

                <groupId>org.springframework.cloud</groupId>

                <artifactId>spring-cloud-dependencies</artifactId>

                <version>Greenwich.RELEASE</version>

                <type>pom</type>

                <scope>import</scope>

            </dependency>

        </dependencies>

    </dependencyManagement>

    <dependencies>

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-gateway</artifactId>

        </dependency>

    </dependencies>

</project>

        先建立一個最簡單的application.yml,

server:

  port: 8880

        而後,讓咱們建立application類,

package com.zuikc;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.gateway.route.RouteLocator;

import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;

import org.springframework.context.annotation.Bean;

import org.springframework.web.bind.annotation.RestController;

/**

 * @ClassName GatewayApplication

 * @Description 咱們提供諮詢和培訓服務,關於本文有任何困惑,請關注並聯系「碼農星球」

 * @Author 碼農星球

 **/

@SpringBootApplication

@RestController

public class GatewayApplication {

    public static void main(String[] args) {

        SpringApplication.run(GatewayApplication.class, args);

    }

    @Bean

    public RouteLocator myRoutes(RouteLocatorBuilder builder) {

        return builder.routes()

                .route("host_route", r -> r.path("/hello/**").filters(f -> f.stripPrefix(1)).uri("http://localhost:9291"))

                .route("host_route", r -> r.path("/user/**").filters(f -> f.stripPrefix(1)).uri("http://localhost:9391"))

                .build();

    }

}

        在這個類中,咱們將「域名/hello」下的全部請求轉發到了HelloService所在ribbon服務器中,將「域名/user」下全部的請求轉到User所在的ribbon下。

        而後,啓動application。這個時候,讓咱們輸入地址:http://localhost:8880/hello/hello,能夠看到結果相似以下:

        服務將在兩個provider中切換。注意,上述url中,第一個hello,是指路由到helloservice中,第二個hello,是具體的服務。

        接下來,讓咱們試一下,http://localhost:8880/user/something。因爲咱們目前並無開發UserService,因此就出現errorpage了~~

4.使用配置實現

        咱們也可使用配置來實現路由。

        在上面的代碼中,咱們首先去掉application中的bean,

package com.zuikc;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.gateway.route.RouteLocator;

import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;

import org.springframework.context.annotation.Bean;

import org.springframework.web.bind.annotation.RestController;

/**

 * @ClassName GatewayApplication

 * @Description 咱們提供諮詢和培訓服務,關於本文有任何困惑,請關注並聯系「碼農星球」

 * @Author 碼農星球

 **/

@SpringBootApplication

@RestController

public class GatewayApplication {

    public static void main(String[] args) {

        SpringApplication.run(GatewayApplication.class, args);

    }

}

        而後,修改application.yml,

server:

  port: 8880

spring:

  cloud:

    gateway:

      routes:

      - id: host_route

        uri: http://localhost:9291

        predicates:

        - Path=/hello/**

        filters:

        - StripPrefix=1

      - id: host_route

        uri: http://localhost:9391

        predicates:

        - Path=/user/**

        filters:

        - StripPrefix=1

        而後,重啓application,獲得的效果是同樣同樣滴。

5.經過filters使用Hystrix

        若是注意上文中的http://localhost:8880/user/something,咱們發現原來在gateway中也是能夠指定熔斷器fallback的。

        那就好辦了,首先,讓咱們引入hystrix,

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>

        </dependency>

        其次,建立一個fallback,

package com.zuikc;

import org.springframework.stereotype.Component;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

/**

 * @ClassName FallBack

 * @Description 咱們提供諮詢和培訓服務,關於本文有任何困惑,請關注並聯系「碼農星球」

 * @Author 碼農星球

 **/

@RestController

@RequestMapping("/fallback")

public class FallBack {

    @RequestMapping("")

    public String fallback(){

        return "error";

    }

}

        再次,修改咱們的配置文件,

server:

  port: 8880

spring:

  cloud:

    gateway:

      routes:

      - id: host_route

        uri: http://localhost:9291

        predicates:

        - Path=/hello/**

        filters:

        - StripPrefix=1

      - id: host_route

        uri: http://localhost:9391

        predicates:

        - Path=/user/**

        filters:

        - StripPrefix=1

        - name: Hystrix

          args:

            name: fallbackcmd

            fallbackUri: forward:/fallback

        重啓application。

        這個時候,再次訪問http://localhost:8880/user/something,頁面輸出爲error。

        感謝關注「碼農星球」。本文版權屬於「碼農星球」。咱們提供諮詢和培訓服務,關於本文有任何困惑,請關注並聯系咱們。

本文參考:https://spring.io/guides/gs/gateway/

一些官方的例子在:

http://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.0.0.RELEASE/single/spring-cloud-gateway.html

相關文章
相關標籤/搜索