Springcloud_H版-alibaba学习笔记(十四)服务网关-Gateway

1.概述

1.是什么

Gateway是在Spring生态系统之上构建的API网关服务,基于Spring5,Springboot2 和Project Reactor等技术。
Gateway旨在提供一种简单有效的方式在对API进行路由,以及提供一些强大的过滤器功能,如熔断、限流、重试等。
SpringCloud Gateway是基于WebFlux框架实现的,使用WebFlux中的reactor-netty响应式编程组件, 而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。

2.能干嘛

反向代理、鉴权、流量控制、熔断、日志监控。

2.三大核心概念

Route(路由):路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如断言为true则匹配该路由
Predicate(断言):参考的是Java8的java.util.function.Predicate
开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由。
Filter(过滤):指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改.

3.Gateway工作流程

核心逻辑:路由转发+执行过滤器链。

4.入门配置

1.新建Module

cloud-gateway-gateway49527

2.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>dt-SpringCloud-2020</artifactId>  
        <groupId>com.dt.springcloud</groupId>  
        <version>1.0.0-SNAPSHOT</version>  
    </parent>  
    <modelVersion>4.0.0</modelVersion>  
  
    <artifactId>cloud-gateway-gateway9527</artifactId>  
  
    <properties>  
        <maven.compiler.source>8</maven.compiler.source>  
        <maven.compiler.target>8</maven.compiler.target>  
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
    </properties>  
    <dependencies>  
        <!--gateway-->  
        <dependency>  
            <groupId>org.springframework.cloud</groupId>  
            <artifactId>spring-cloud-starter-gateway</artifactId>  
        </dependency>  
        <!--eureka-client-->  
        <dependency>  
            <groupId>org.springframework.cloud</groupId>  
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>  
        </dependency>  
        <!--一般基础配置类-->  
        <dependency>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-devtools</artifactId>  
            <scope>runtime</scope>  
            <optional>true</optional>  
        </dependency>  
        <dependency>  
            <groupId>org.projectlombok</groupId>  
            <artifactId>lombok</artifactId>  
            <optional>true</optional>  
        </dependency>  
        <dependency>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter-test</artifactId>  
            <scope>test</scope>  
        </dependency>  
    </dependencies>  
</project>

3.yml

server:  
  port: 49527  
  
spring:  
  application:  
    name: cloud-gateway  
  cloud:  
    gateway:  
      routes:  
        - id: payment_routh #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名  
          uri: http://localhost:8001          #匹配后提供服务的路由地址  
          predicates:  
            - Path=/payment/get/**         # 断言,路径相匹配的进行路由  
  
        - id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名  
          uri: http://localhost:8001          #匹配后提供服务的路由地址  
          predicates:  
            - Path=/payment/lb/**         # 断言,路径相匹配的进行路由  
  
  
#服务注册Eureka配置  
eureka:  
  client:  
    register-with-eureka: true #表示向注册中心注册自己 默认为true  
    fetch-registry: true #是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡  
    service-url:  
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # 入驻集群版Eureka地址  
      # defaultZone: http://localhost:7001/eureka/ # 入驻单机版Eureka地址  
  instance:  
    instance-id: cloud-gateway-service # 服务名称

4.业务类:无

5.主启动类

package com.dt.springcloud;  
  
import org.springframework.boot.SpringApplication;  
import org.springframework.boot.autoconfigure.SpringBootApplication;  
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;  
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;  
  
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})  
@EnableEurekaClient  
public class GateWayMain49527 {  
  
    public static void main(String[] args) {  
        SpringApplication.run(GateWayMain49527.class, args);  
    }  
}

6.yml新增路由映射配置

spring:  
  application:  
    name: cloud-gateway  
  cloud:  
    gateway:  
      routes:  
        - id: payment_routh #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名  
          uri: http://localhost:8001          #匹配后提供服务的路由地址  
          predicates:  
            - Path=/payment/get/**         # 断言,路径相匹配的进行路由  
  
        - id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名  
          uri: http://localhost:8001          #匹配后提供服务的路由地址  
          predicates:  
            - Path=/payment/lb/**         # 断言,路径相匹配的进行路由

7.测试

启动eureka7001、eureka7002
启动8001
启动49527
访问
添加网关前访问
http://localhost:8001/payment/get/1
添加网关后访问
http://localhost:49527/payment/get/1

8.Gateway网关路由有两种配置方式

1.配置文件

参照上面的步骤。

2.代码中注入RouteLocator的Bean
1.实例

通过9527网关访问到外网的百度新闻网址。

2.编码

增加config

package com.dt.springcloud.config;  
  
import org.springframework.cloud.gateway.route.RouteLocator;  
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
  
@Configuration  
public class GateWayConfig {  
    @Bean  
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {  
        RouteLocatorBuilder.Builder routers = routeLocatorBuilder.routes();  
        routers.route("path_route_dt", r -> r.path("/news").uri("http://news.baidu.com")).build();  
        return routers.build();  
    }  
}

5. 通过微服务名实现动态路由

之前通过服务名称+ribbon实现负载轮询。
现在有了gateway之后,默认情况下Gateway会根据注册中心注册的服务列表,以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能。

1.启动

启动一个eureka7001、eureka7002 、两个服务提供者8001/8002
访问测试:http://localhost/consumer/diyLoadBalancedTest
该方式是通过在eureka上注册过的微服务名称结合Ribbon调用实现的轮询效果。

2.修改Gateway49527的yml配置

spring:  
  application:  
    name: cloud-gateway  
  cloud:  
    gateway:  
      discovery:  
        locator:  
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由  
      routes:  
        - id: payment_routh #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名  
#          uri: http://localhost:8001          #匹配后提供服务的路由地址  
          uri: lb://cloud-payment-service      #通过loadbalance的方式,利用注册中心(如:Eureka)中的服务名称 匹配后提供服务的路由地址  
                                               # uri的协议为lb,表示启用Gateway的负载均衡功能。  
                                               #lb://serviceName是spring cloud gateway在微服务中自动为我们创建的负载均衡uri  
          predicates:  
            - Path=/payment/get/**         # 断言,路径相匹配的进行路由  
  
        - id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名  
#          uri: http://localhost:8001          #匹配后提供服务的路由地址  
          uri: lb://cloud-payment-service          #通过loadbalance的方式,利用注册中心(如:Eureka)中的服务名称 匹配后提供服务的路由地址  
          predicates:  
            - Path=/payment/lb/**         # 断言,路径相匹配的进行路由

3.说明

需要注意的是uri的协议为lb,表示启用Gateway的负载均衡功能。
lb://serviceName是spring cloud gateway在微服务中自动为我们创建的负载均衡uri

没用gateway之前实现负载思路:

http->80(注册中心 +ribbon+服务名称)

使用gateway之后实现负载思路:

http->gateway -> lb(通过负载均衡方式)->lb://serviceName(spring cloud gateway在微服务中自动为我们创建的负载均衡uri)

4.访问测试

http://localhost:49527/payment/lb/getServerPort

6.Predicate的使用

Spring Cloud Gateway将路由匹配作为Spring WebFlux HandlerMapping基础架构的一部分。Spring Cloud Gateway包括许多内置的Route Predicate工厂。所有这些Predicate都与HTTP请求的不同属性匹配。多个Route Predicate工厂可以进行组合。

Spring Cloud Gateway 创建 Route 对象时, 使用 RoutePredicateFactory 创建 Predicate 对象,Predicate 对象可以赋值给 Route。 Spring Cloud Gateway 包含许多内置的Route Predicate Factories。

所有这些谓词都匹配HTTP请求的不同属性。多种谓词工厂可以组合,并通过逻辑and。

1.常用的Route Predicate

After Route Predicate

after 路由谓词工厂采用一个参数,即日期时间。此谓词匹配在指定日期时间之后发生的请求。

- id: payment_routh3   
  uri: lb://cloud-payment-service  
  predicates:  
    - Path=/payment/lb/**           
    - After=2023-06-25T15:30:24.699+08:00[Asia/Shanghai]
Before Route Predicate

before 路由谓词工厂采用一个参数 a datetime。此谓词匹配在指定的 之前发生的请求datetime

- id: payment_routh3  
  uri: lb://cloud-payment-service  
  predicates:  
    - Path=/payment/lb/**  
    - Before=2023-06-25T15:30:24.699+08:00[Asia/Shanghai]
Between Route Predicate

路由谓词工厂之间有两个参数,datetime1datetime2。此谓词匹配发生在 afterdatetime1和 before的请求datetime2datetime2参数必须在之后datetime1

- id: payment_routh3  
  uri: lb://cloud-payment-service  
  predicates:  
    - Path=/payment/lb/**  
    - Between=2023-05-25T15:30:24.699+08:00[Asia/Shanghai],2023-06-25T15:30:24.699+08:00[Asia/Shanghai]
Cookie Route Predicate

cookie 路由谓词工厂有两个参数,cookie 名称和正则表达式。此谓词匹配具有给定名称且其值与正则表达式匹配的 cookie。

- id: payment_routh3  
  uri: lb://cloud-payment-service  
  predicates:  
    - Path=/payment/lb/**  
    - Cookie=chocolate, ch
Header Route Predicate

标头路由谓词工厂有两个参数,标头名称和正则表达式。此谓词与具有给定名称且值与正则表达式匹配的标头匹配。

- id: payment_routh3  
  uri: lb://cloud-payment-service  
  predicates:  
    - Path=/payment/lb/**  
    - Header=X-Request-Id,\d+
Host Route Predicate

主机路由谓词工厂采用一个参数:主机名模式列表。该模式是一种 Ant 风格的模式,.以分隔符为分隔符。此谓词匹配Host与模式匹配的标头。

- id: payment_routh3  
  uri: lb://cloud-payment-service  
  predicates:  
    - Path=/payment/lb/**  
    - Host=**.somehost.org,**.anotherhost.org
Method Route Predicate

Method Route Predicate Factory 采用一个或多个参数:要匹配的 HTTP 方法。

- id: payment_routh3  
  uri: lb://cloud-payment-service  
  predicates:  
    - Path=/payment/lb/**  
    - Method=GET,POST
Path Route Predicate

Path Route Predicate Factory 有两个参数:一个 SpringPathMatcher模式列表和一个名为 的可选标志matchOptionalTrailingSeparator

- id: payment_routh3  
  uri: lb://cloud-payment-service  
  predicates:  
    - Path=/red/{segment},/blue/{segment}
Query Route Predicate

查询路由谓词工厂有两个参数:一个 requiredparam和一个 optional regexp

- id: payment_routh3  
  uri: lb://cloud-payment-service  
  predicates:  
    - Path=/payment/lb/**  
    - Query=green

7.Filter的使用

1.Filter是什么

路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用。

Spring Cloud Gateway 内置了多种路由过滤器,他们都由GatewayFilter的工厂类来产生。

2.Filter的分类

  • GatewayFilter:Spring Cloud Gateway 包含许多内置的 GatewayFilter 工厂。这个太多了,一般不用。
  • GlobalFilter:全局过滤器。

3.自定义全局过滤器测试

实现两个接口:GlobalFilter,Ordered。

package com.dt.springcloud.filter;  
  
import lombok.Data;  
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.web.server.ServerWebExchange;  
import reactor.core.publisher.Mono;  
  
import java.util.Date;  
  
  
/**  
 * 自定义Gateway Global Filter  
 */@Component  
@Slf4j  
public class MyLogGateWayFilter implements GlobalFilter, Ordered {  
  
    /**  
     * 自定义过滤器逻辑:请求种必须带有uname参数,不带不进行正常的路由转发并返回自定义状态码
     * @param exchange  
     * @param chain  
     * @return  
     */    @Override  
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {  
        log.info("*******come in MyLogGatewayFilter:" + new Date());  
        String uname = exchange.getRequest().getQueryParams().getFirst("uname");  
        if (uname == null) {  
            log.info("**********用户名称为null,非法用户! ");  
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);//设置不允许进入响应。  
            return exchange.getResponse().setComplete(); //返回操作完成  
        }  
        return chain.filter(exchange);//将信息增加到调用链中 继续执行后续过滤器  
    }  
  
    /**  
     * 过滤器执行顺序, 数值越小优先执行。  
     *  
     * @return     */    @Override  
    public int getOrder() {  
        return 0;  
    }  
}

4.访问测试

http://localhost:49527/payment/lb/getServerPort?uname=1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Alibaba Nacos 是一个服务注册中心和配置中心,可以实现服务的注册与发现、配置的动态管理等功能,同时还提供了容灾和高可用的支持。下面简单介绍如何使用 Nacos 实现 Spring Cloud 的配置容灾。 首先,在应用的 `pom.xml` 文件中添加如下依赖: ```xml <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2.2.3.RELEASE</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>2.2.3.RELEASE</version> </dependency> ``` 然后在 `application.properties` 中配置 Nacos 的地址和应用的名称: ```properties spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 spring.cloud.nacos.discovery.namespace=your-namespace spring.cloud.nacos.config.server-addr=127.0.0.1:8848 spring.cloud.nacos.config.namespace=your-namespace spring.cloud.nacos.config.file-extension=properties spring.application.name=your-application-name ``` 其中 `server-addr` 是 Nacos 的地址,`namespace` 是命名空间,`file-extension` 是配置文件的扩展名,`application.name` 是应用的名称。 接着在 `bootstrap.properties` 中配置应用的环境和配置来源: ```properties spring.profiles.active=dev spring.cloud.nacos.config.prefix=${spring.application.name}-${spring.profiles.active} spring.cloud.nacos.config.group=DEFAULT_GROUP spring.cloud.nacos.config.shared-dataids=${spring.application.name}-${spring.profiles.active}.properties ``` 其中 `spring.profiles.active` 是应用的环境,`prefix` 是配置文件的前缀,`group` 是配置文件所在的分组,`shared-dataids` 是配置文件的名称。 最后,在代码中使用 `@Value` 注解来获取配置项的值: ```java @RestController public class ConfigController { @Value("${config.key}") private String configValue; @GetMapping("/config") public String getConfig() { return configValue; } } ``` 其中 `config.key` 是配置项的名称。 以上就是使用 Nacos 实现 Spring Cloud 的配置容灾的简单示例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值