网关Spring GateWay

SpringCloud Gateway 网关笔记

样例来源,参考博客

QUICK START

创建一个maven项目,其中完整的pom文件如下,重点在于导入gateway依赖。

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <parent>
 6         <groupId>org.springframework.boot</groupId>
 7         <artifactId>spring-boot-starter-parent</artifactId>
 8         <version>2.3.2.RELEASE</version>
 9         <relativePath/> <!-- lookup parent from repository -->
10     </parent>
11     <modelVersion>4.0.0</modelVersion>
12 
13     <groupId>cn.seaadd.demo</groupId>
14     <artifactId>sea-add</artifactId>
15 
16 
17     <properties>
18         <maven.compiler.source>17</maven.compiler.source>
19         <maven.compiler.target>17</maven.compiler.target>
20         <java.version>8</java.version>
21         <spring-cloud.version>Hoxton.SR7</spring-cloud.version>
22     </properties>
23 
24     <dependencies>
25         <dependency>
26             <groupId>org.springframework.cloud</groupId>
27             <artifactId>spring-cloud-starter-gateway</artifactId>
28         </dependency>
29     </dependencies>
30 
31     <dependencyManagement>
32         <dependencies>
33             <dependency>
34                 <groupId>org.springframework.cloud</groupId>
35                 <artifactId>spring-cloud-dependencies</artifactId>
36                 <version>${spring-cloud.version}</version>
37                 <type>pom</type>
38                 <scope>import</scope>
39             </dependency>
40         </dependencies>
41     </dependencyManagement>
42 
43 </project>

有两种方式访问,

其一,配置文件

在application.yml 文件中配置gateway

server:
  port: 9533
spring:
  application:
    name: sea-add
  cloud:
    gateway:
      routes:
        - id: sea-add                        # 路由id
          uri: https://baidu.com/    # 真实调用地址
          predicates:
            - Path=/seaadd                # 断言,符合规则进行路由
      
filters:
       - StripPrefix=1 #开启过滤器,过滤掉一级目录地址,即/seaadd这一级目录
 

启动类

package cn.seaadd.demo;

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;

/**
 * @author linhaizeng
 * @Description TODO
 * @date 2022/5/26-5:36 下午
 */
@SpringBootApplication
public class SeaAddApplication {
    public static void main(String[] args) {
        SpringApplication.run(SeaAddApplication.class, args);
    }

}

浏览器访问http://localhost:9533/seaadd 跳转到百度界面。

其二,Bean

不使用配置文件,直接使用配置类

package cn.seaadd.demo;

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;

/**
 * @author linhaizeng
 * @Description TODO
 * @date 2022/5/26-5:36 下午
 */
@SpringBootApplication
public class SeaAddApplication {
    public static void main(String[] args) {
        SpringApplication.run(SeaAddApplication.class, args);
    }

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("path_route", r -> r.path("/csdn")
                        .uri("https://baidu.com/"))
                .build();
    }
}

浏览器访问http://localhost:9533/csdn 跳转到百度界面。

问题

无法正常访问

- id: test_rewrite
  uri: http://www.baidu.com
  predicates:
    - Path=/abc

这样 http://localhost/abc 不能转到百度,但是下面的 URI 配置去掉 www. 又可以正常转发到了,奇怪

- id: test_rewrite
  uri: http://baidu.com
  predicates:
    - Path=/abc

URI

在gateway中配置uri配置有三种方式,包括
第一种:ws(websocket)方式: uri: ws://localhost:9000
第二种:http方式: uri: http://localhost:8130/
第三种:lb(注册中心中服务名字)方式: uri: lb://brilliance-consumer

上下文内容说明

1Filter(过滤器)

和Zuul的过滤器在概念上类似,可以使用它拦截和修改请求,并且对上游的响应,进行二次处理。过滤器为org.springframework.cloud.gateway.filter.GatewayFilter类的实例。

(2)Route(路由):

网关配置的基本组成模块,和Zuul的路由配置模块类似。一个Route模块由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配,目标URI会被访问。

3Predicate(断言)

这是一个 Java 8 的 Predicate,可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。断言的输入类型是一个 ServerWebExchange。

路由配置方式

server:
  port: 8080
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        - id: url-proxy-1
          uri: https://blog.csdn.net
          predicates:
            - Path=/csdn

各字段含义如下:

id:我们自定义的路由 ID,保持唯一

uri:目标服务地址

predicates:路由条件,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。

上面这段配置的意思是,配置了一个 id 为 url-proxy-1的URI代理规则,路由的规则为:

当访问地址http://localhost:8080/csdn/1.jsp时,

会路由到上游地址https://blog.csdn.net/1.jsp。

更多配置案例

  After Route Predicate Factory

匹配“美国丹佛时间2017-01-20 17:42”之后的任意请求

1 spring:
2   cloud:
3     gateway:
4       routes:
5       - id: after_route
6         uri: https://example.org
7         predicates:
8         - After=2017-01-20T17:42:47.789-07:00[America/Denver]

 Header Route Predicate Factory

这个路由匹配“请求头包含X-Request-Id并且其值匹配正则表达式\d+”的任意请求

1 spring:
2   cloud:
3     gateway:
4       routes:
5       - id: header_route
6         uri: https://example.org
7         predicates:
8         - Header=X-Request-Id, \d+

 Method Route Predicate Factory

这个路由匹配任意GET请求

1 spring:
2   cloud:
3     gateway:
4       routes:
5       - id: method_route
6         uri: https://example.org
7         predicates:
8         - Method=GET

 Path Route Predicate Factory

这个路由匹配这样路径的请求,比如:/foo/1 或 /foo/bar 或 /bar/baz

1 spring:
2   cloud:
3     gateway:
4       routes:
5       - id: host_route
6         uri: https://example.org
7         predicates:
8         - Path=/foo/{segment},/bar/{segment}

Query Route Predicate Factory

这个Predicate有两个参数:一个必须的参数名和一个可选的正则表达式

这个路由匹配“查询参数中包含baz”的请求

1 spring:
2   cloud:
3     gateway:
4       routes:
5       - id: query_route
6         uri: https://example.org
7         predicates:
8         - Query=baz

这个路由匹配“查询参数中包含foo,并且其参数值满足正则表达式ba.”的请求,比如:bar,baz

1 spring:
2   cloud:
3     gateway:
4       routes:
5       - id: query_route
6         uri: https://example.org
7         predicates:
8         - Query=foo, ba.

RemoteAddr Route Predicate Factory

这里路由匹配远程地址是这样的请求,例如:192.168.1.10

1 spring:
2   cloud:
3     gateway:
4       routes:
5       - id: remoteaddr_route
6         uri: https://example.org
7         predicates:
8         - RemoteAddr=192.168.1.1/24

过滤器

路由过滤器允许以某种方式修改传入的HTTP请求或传出HTTP响应。路由过滤器的作用域是特定的路由。Spring Cloud Gateway包含许多内置的网关过滤器工厂。

AddRequestHeader GatewayFilter Factory

spring:
  cloud:
    gateway:
      routes:
      - id: add_request_header_route
        uri: https://example.org
        filters:
        - AddRequestHeader=X-Request-Foo, Bar

对于所有匹配的请求,将会给传给下游的请求添加一个请求头 X-Request-Foo:Bar

AddRequestParameter GatewayFilter Factory

  cloud:
    gateway:
      routes:
      - id: add_request_parameter_route
        uri: https://example.org
        filters:
        - AddRequestParameter=foo, bar

对于所有匹配的请求,将给传给下游的请求添加一个查询参数 foo=bar

 AddResponseHeader GatewayFilter Factory

  cloud:
    gateway:
      routes:
      - id: add_response_header_route
        uri: https://example.org
        filters:
        - AddResponseHeader=X-Response-Foo, Bar

对于所有匹配的请求,添加一个响应头 X-Response-Foo:Bar

Hystrix GatewayFilter Factory

Hystrix网关过滤器允许你将断路器引入网关路由,保护你的服务免受级联失败的影响,并在下游发生故障时提供预备响应。

为了启用Hystrix网关过滤器,你需要引入 spring-cloud-starter-netflix-hystrix

Hystrix网关过滤器需要一个name参数,这个name是HystrixCommand的名字

spring:
  cloud:
    gateway:
      routes:
      - id: hystrix_route
        uri: https://example.org
        filters:
        - Hystrix=myCommandName

给这个过滤器包装一个名字叫myCommandName的HystrixCommand

Hystrix网关过滤器也接受一个可选的参数fallbackUri,但是目前只支持forward:前缀的URL。也就是说,如果这个fallback被调用,请求将被重定向到匹配的这个URL。

  cloud:
    gateway:
      routes:
      - id: hystrix_route
        uri: lb://backing-service:8088
        predicates:
        - Path=/consumingserviceendpoint
        filters:
        - name: Hystrix
          args:
            name: fallbackcmd
            fallbackUri: forward:/incaseoffailureusethis
        - RewritePath=/consumingserviceendpoint, /backingserviceendpoint

当fallback被调用的时候,请求将被重定向到/incaseoffailureusethis

  cloud:
    gateway:
      routes:
      - id: ingredients
        uri: lb://ingredients
        predicates:
        - Path=//ingredients/**
        filters:
        - name: Hystrix
          args:
            name: fetchIngredients
            fallbackUri: forward:/fallback
      - id: ingredients-fallback
        uri: http://localhost:9994
        predicates:
        - Path=/fallback

在这个例子中,专门定义了一个端点来处理/fallback请求,它在localhost:9994上。也就是说,当fallback被调用的时候将重定向到http://localhost:9994/fallback

PrefixPath GatewayFilter Factory

  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: https://example.org
        filters:
        - PrefixPath=/mypath

所有匹配的请求都将加上前缀/mypath。例如,如果请求是/hello,那么经过这个过滤器后,发出去的请求变成/mypath/hello

posted @ 2022-05-26 16:11  唯一不变的是变化  阅读(113)  评论(0)    收藏  举报