SpringCloud gatewayeFilter之一

Posted shigongp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud gatewayeFilter之一相关的知识,希望对你有一定的参考价值。

1、AddRequestHeader GatewayFilter

AddRequestHeader GatewayFilter采用名称和值参数。例如:

spring:
  cloud:
    gateway:
      enabled: true
      routes:
        - id: Goods-Server  # 路由 id,唯一标识
          uri: lb://producer
          predicates:
            #  - Path=/**  # 断言,路由匹配条件,匹配 /product 开头的所有 api
              - Path=/producer/**
          filters:
              - StripPrefix=1
              - AddRequestHeader=X-Request-red, blue

此列表将X-Request-red:blue标头添加到所有匹配请求的下游请求标头中。

Producer服务的controller:

@RequestMapping("/hello")
public String hello(String name, HttpServletRequest request) 
    System.out.println(request.getHeader("x-request-red"));
    return "hello," + name + "," + port;

访问http://localhost:8500/producer/hello,看到
 

 

AddRequestHeader也用于匹配路径或主机的URI变量:

spring:
  cloud:
    gateway:
      enabled: true
      routes:
        - id: Goods-Server  # 路由 id,唯一标识
          uri: lb://producer
          predicates:
            #  - Path=/**  # 断言,路由匹配条件,匹配 /product 开头的所有 api
              - Path=/producer/segment
          filters:
              - StripPrefix=1
              - AddRequestHeader=X-Request-red, Blue-segment

访问http://localhost:8500/producer/hello,看到
 

 

2、AddRequestParameter GatewayFilter

AddRequestParameter GatewayFilter采用名称和值参数。例如:

spring:
  cloud:
    gateway:
      enabled: true
      routes:
        - id: Goods-Server  # 路由 id,唯一标识
          uri: lb://producer
          predicates:
            #  - Path=/**  # 断言,路由匹配条件,匹配 /product 开头的所有 api
              - Path=/producer/segment
          filters:
              - StripPrefix=1
              - AddRequestHeader=X-Request-red, Blue-segment
              - AddRequestParameter=red, blue

这将为所有匹配请求的下游请求的查询字符串添加red=blue。

 

Producer服务controller:

@RequestMapping("/hello")
public String hello(String name, HttpServletRequest request) 
    System.out.println(request.getHeader("x-request-red"));
    System.out.println(request.getParameter("red"));
    return "hello," + name + "," + port;

访问http://localhost:8500/producer/hello,看到
 

 

AddRequestParameter也用于匹配路径或主机的URI变量:

spring:
  cloud:
    gateway:
      enabled: true
      routes:
        - id: Goods-Server  # 路由 id,唯一标识
          uri: lb://producer
          predicates:
            #  - Path=/**  # 断言,路由匹配条件,匹配 /product 开头的所有 api
              - Path=/producer/segment
          filters:
              - StripPrefix=1
              - AddRequestHeader=X-Request-red, Blue-segment
              - AddRequestParameter=red, bar-segment

访问http://localhost:8500/producer/hello,看到
 

 

3、AddResponseHeader GatewayFilter

AddResponseHeader GatewayFilter采用名称和值参数。这会将响应头添加到所有匹配请求的下游响应标头中。例如:

spring:
  cloud:
    gateway:
      enabled: true
      routes:
        - id: Goods-Server  # 路由 id,唯一标识
          uri: lb://producer
          predicates:
            #  - Path=/**  # 断言,路由匹配条件,匹配 /product 开头的所有 api
              - Path=/producer/segment
          filters:
              - StripPrefix=1
              - AddResponseHeader=X-Response-Red, Blue

访问http://localhost:8500/producer/hello,从浏览器控制台中可看到响应头:
 

 
AddResponseHeader也用于匹配路径或主机的URI变量:

spring:
  cloud:
    gateway:
      enabled: true
      routes:
        - id: Goods-Server  # 路由 id,唯一标识
          uri: lb://producer
          predicates:
            #  - Path=/**  # 断言,路由匹配条件,匹配 /product 开头的所有 api
              - Path=/producer/segment
          filters:
              - StripPrefix=1
              - AddResponseHeader=X-Response-Red, Blue-segment

访问http://localhost:8500/producer/hello,从浏览器控制台中可看到响应头:
 

 

4、DedupeResponseHeader GatewayFilter

DedupeResponseHeader GatewayFilter采用名称参数和可选策略参数。name可以包含一个以空格分隔的标头名称列表。例如:

spring:
  cloud:
    gateway:
      enabled: true
      routes:
        - id: Goods-Server  # 路由 id,唯一标识
          uri: lb://producer
          predicates:
            #  - Path=/**  # 断言,路由匹配条件,匹配 /product 开头的所有 api
              - Path=/producer/segment
          filters:
              - StripPrefix=1
              - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin

将删除Access-Control-Allow-Credentials和Access-Control-Allow-Origin头的重复值。

5、Spring Cloud CircuitBreaker GatewayFilter

Spring Cloud CircuitBreaker GatewayFilter工厂使用Spring Cloud CircutBreaker API将网关路由封装在断路器中。Spring Cloud CircuitBreaker支持可与Spring Cloud Gateway一起使用的多个库。Spring Cloud支持开箱即用的Resilience4J。在GatewayServer模块加入依赖:

<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId>
    </dependency>

并添加controller:

@RestController
public class Fallback 

    private String dateStr()
        return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
    

    /**
     * 返回字符串类型
     * @return
     */
    @GetMapping("/myfallback")
    public String helloStr() 
        return "myfallback, " + dateStr();
    

在application.yml配置:

spring:
  cloud:
    gateway:
      enabled: true
      routes:
        - id: Goods-Server  # 路由 id,唯一标识
          uri: lb://producer
          predicates:
            #  - Path=/**  # 断言,路由匹配条件,匹配 /product 开头的所有 api
              - Path=/producer/segment
          filters:
              - StripPrefix=1
              - name: CircuitBreaker
                args:
                    name: myCircuitBreaker
                    fallbackUri: forward:/myfallback

fallbackUri中的url要和上面controller中的url相同。当出现异常时会转发到fallbackUri。现在关闭Producer服务,访问http://localhost:8500/producer/hello,看到myfallback, 2023-05-04 08:27:53。

 

也可以根据响应状态码列表来触发熔断开关。可以配置响应状态码,也可以配置HttpStatus枚举。例如:

spring:
  cloud:
    gateway:
      enabled: true
      routes:
        - id: Goods-Server  # 路由 id,唯一标识
          uri: lb://producer
          predicates:
            #  - Path=/**  # 断言,路由匹配条件,匹配 /product 开头的所有 api
              - Path=/producer/segment
          filters:
              - StripPrefix=1
              - AddRequestHeader=X-Request-red, Blue-segment
              - AddRequestParameter=red, bar-segment
              - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
              - name: CircuitBreaker
                args:
                    name: myCircuitBreaker
                    fallbackUri: forward:/myfallback
                    statusCodes:
                      - 500

修改Producer的controller:

 @RequestMapping("/hello")
public String hello(String name, HttpServletRequest request, HttpServletResponse response) 
    System.out.println(request.getHeader("x-request-red"));
    System.out.println(request.getParameter("red"));
    response.setStatus(500);
    return "hello," + name + "," + port;

访问http://localhost:8500/producer/hello,看到myfallback, 2023-05-04 08:48:07。将response.setStatus(500);改成response.setStatus(404);重新访问http://localhost:8500/producer/hello,看到hello,null,8002。

修改gateway的application.yml配置

spring:
  cloud:
    gateway:
      enabled: true
      routes:
        - id: Goods-Server  # 路由 id,唯一标识
          uri: lb://producer
          predicates:
            #  - Path=/**  # 断言,路由匹配条件,匹配 /product 开头的所有 api
              - Path=/producer/segment
          filters:
              - StripPrefix=1
              - AddRequestHeader=X-Request-red, Blue-segment
              - AddRequestParameter=red, bar-segment
              - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
              - name: CircuitBreaker
                args:
                    name: myCircuitBreaker
                    fallbackUri: forward:/myfallback
                    statusCodes:
                      - 500
                      - "NOT_FOUND"

重新访问http://localhost:8500/producer/hello,看到myfallback, 2023-05-04 08:50:27。

springcloud情操陶冶-初识springcloud

许久之前便听到了springcloud如雷贯耳的大名,但是不曾谋面,其主要应用于微服务的相关架构。笔者对微服务并不是很了解,但其既然比较出众,遂也稍微接触研究下

springcloud特性

springcloud作为spring团队的微服务架构,其有如下的特性(摘自官方文档)

  • Distributed/versioned configuration(分布式/版本化配置)
  • Service registration and discovery(服务注册与发现)
  • Routing(路由)
  • Service-to-service calls(服务间远程调用)
  • Load balancing(负载均衡)
  • Circuit Breakers(熔断器)
  • Distributed messaging(分布式消息)

应该就是微服务的相关特性,笔者不对上述的概念进行阐述,读者可相应的查阅相关文档

springcloud config

springcloud板块下有很多的分支,根本看不过来,就挑笔者比较感兴趣的配置管理springcloud config作为分析的入口把。具体的使用以及概念本文就不展开了,在官方文档上都有,笔者喜欢从源码角度看下springcloud是如何整合springboot进行扩展的

MAVEN依赖

根据官方的例子,笔者最后还是通过IDEA开发工具引入Spring Initializr构建工具来生成springcloud config的相关maven配置

<?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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>cloud-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>cloud-demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.RC2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
    </repositories>

</project>

其依托于spring-boot-starter-parent板块进行构建,上述的简单配置其实引入了spring/springboot/springcloud三大板块及其相应依赖,具体就展示了,读者可自行查看

springcloud config 启动

官方文档上提供了命令方式的启动


linux方式启动

$ cd spring-cloud-demo
$ ./mvnw spring-boot:run

window方式启动

> cd spring-cloud-demo
> call mvnw.cmd spring-boot:run

IDEA方式启动,直接运行ConfigServerApplication启动类(springcloud包内的启动类,读者可下载源码来运行)

package org.springframework.cloud.config.server;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableAutoConfiguration
@EnableConfigServer
public class ConfigServerApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(ConfigServerApplication.class)
                .properties("spring.config.name=configserver").run(args);
    }

}

小结

笔者以此篇作为springcloud的开篇,后续将以springcloud config的源码作为分析的源头,慢慢去管中窥豹下它的魅力

以上是关于SpringCloud gatewayeFilter之一的主要内容,如果未能解决你的问题,请参考以下文章

springcloud配置常量

springcloud01-SpringCloud 概述

SpringCloud系列SpringCloud概述及微服务技术栈的使用

springcloud2020版本使用zuul和nacos服务发现

springcloud情操陶冶-初识springcloud

SpringCloud学习系列-SpringCloud