getway網關


官網

  上一代zuul 1.X:    https://github.com/Netflix/zuul/wiki

  當前gateway:      https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/

概述

 

 

 

 

 

一句話

Spring Cloud Gateway 使用的Webflux中的reactor-netty響應式編程組件,底層使用了Netty通訊框架

源碼架構

 

 能干嘛

反向代理 鑒權 流量控制 熔斷 日志監控

微服務架構中網關在哪里

 

 我們為什么選擇Gatway?

1.neflix不太靠譜,zuul2.0一直跳票,遲遲不發布

 

 2.SpringCloud Gateway具有如下特性

 

 3.SpringCloud Gateway與Zuul的區別

 

 GateWay模型

三大核心概念

Route(路由)

路由是構建網關的基本模塊,它由ID,目標URI,一系列的斷言和過濾器組成,如果斷言為true則匹配該路由

Predicate(斷言)

參考的是java8的java.util.function.Predicate開發人員可以匹配HTTP請求中的所有內容(例如請求頭或請求參數),如果請求與斷言相匹配則進行路由

Filter(過濾)

指的是Spring框架中GatewayFilter的實例,使用過濾器,可以在請求被路由前或者之后對請求進行修改。

總體

案例:gateway的簡單入門

創建cloud-gateway-gateway9527模塊

第一步pom文件

<?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/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-gateway-gateway9527</artifactId>
    <dependencies>

        <!--SpringBoot熱部署配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--整合熔斷器-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

        <!--getWay網關-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

  第二步yml文件

server:
  port: 9527
spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
        - id: after_route
          uri: http://localhost:8004
          predicates:
            - Path=/payment/**
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    serviceUrl:
      defaultZone: http://localhost:7001/eureka/ #單機版

  第三步編寫啟動類

@SpringBootApplication
@EnableEurekaClient
public class GetWayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GetWayApplication.class,args);
    }
}

  測試 配置gateway之前

配置之后發現

 

 

 服務訪問並不會暴露真實的端口

通過微服務名實現動態路由

默認情況下Gateway會根據注冊中心的服務列表,以注冊中心上微服務名為路徑創建動態路由進行轉發,從而實現動態路由的功能

一個eureka7001+兩個服務提供者8004/8005

server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #開啟從注冊中心動態創建路由的功能,利用微服務名進行路由
routes:
- id: after_route
#uri: http://localhost:8004
uri: lb://cloud-payment-servic
predicates:
- Path=/payment/**
eureka:
client:
register-with-eureka: true
fetch-registry: true
serviceUrl:
defaultZone: http://localhost:7001/eureka/ #單機版

需要注意的是uri的協議為lb,表示啟用Gateway的負載均衡功能。 

lb://serviceName是spring cloud gateway在微服務中自動為我們創建的負載均衡uri

測試

 

 

 

 

Predicate的使用

  是什么

 

 

 RoutePredicateFactories是什么

 

 

 

 

 

 常用的Route Predicate

 

 

 

  predicates:
            - Path=/payment/lb/**   #斷言,路徑相匹配的進行路由
            #- After=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]
            #- Cookie=username,zhangshuai #並且Cookie是username=zhangshuai才能訪問
            #- Header=X-Request-Id, \d+ #請求頭中要有X-Request-Id屬性並且值為整數的正則表達式
            #- Host=**.atguigu.com
            #- Method=GET
            #- Query=username, \d+ #要有參數名稱並且是正整數才能路由

說白了,Predicate就是為了實現一組匹配規則,讓請求過來找到對應的Route進行處理

Filter的使用

路由過濾器允許以某種方式修改傳入的HTTP請求或傳出的HTTP響應。路由過濾器適用於特定路由。Spring Cloud Gateway包括許多內置的GatewayFilter工廠。

Spring Cloud Gateway的Filter 

過濾器的分類

生命周期 

在業務邏輯之前  在業務邏輯之后

種類

單一 GatewayFilter   全局 GlobalFilter

常用的GatewayFilter    AddRequestParameter

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        filters:
        - AddRequestHeader=X-Request-red, blue #過濾工廠會在匹配的請求頭加上一對請求頭,名稱為X-Request-red 值為blue

  自定義過濾器

兩個主要接口介紹  impiemerts   GlobalFilter ,Ordered

能干嘛  

全局日志記錄  統一網關鑒權

案例代碼

package com.atguigu.springcloud.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Date;

@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter,Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        log.info("*********come in MyLogGateWayFilter: "+new Date());
        String uname = exchange.getRequest().getQueryParams().getFirst("username");
        if(StringUtils.isEmpty(username)){
            log.info("*****用戶名為Null 非法用戶,(┬_┬)");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);//給人家一個回應
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

  

 


免責聲明!

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



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