微服务Spring Cloud Gateway入门

Spring Cloud Gateway入门

  • (1)网关是什么?
    网关(Gateway) 就是一个网络连接到另一个网络的“关口”。就是网络关卡。
    从一个房间走到另一个房间,必然要经过一扇门。同样,从一个网络向另一个网络发送信息,也必须经过一道“关口”
  • (2)SpringCloud的网关是什么?
    Spring Cloud Gateway的核心就是一系列的过滤器,可以将客户端的请求转发到不同的微服务。主要作用:过滤和路由。

Spring Cloud Gateway入门

  • (1)GateWay如何使用
    》依赖
    》配置路由信息
    id 路由id,可以任意
    uri 代理的服务地址
    predicates 路由断言: 可以匹配映射路径
    》启用
    》启动

pom.xml

 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

application.properties

spring.application.name=demo04_gateway_1001
server.port=1001
eureka.client.service-url.defaultZone=http://127.0.0.1:10086/eureka
# route
spring.cloud.gateway.routes[0].id=demo04_gateway_1001
#spring.cloud.gateway.routes[0].uri.=http://127.0.0.1:8001
spring.cloud.gateway.routes[0].uri=lb://demo01-provider-user
spring.cloud.gateway.routes[0].predicates[0]=Path=/**
#spring.cloud.gateway.routes[0].predicates[0]=Path=/users/*
spring.cloud.gateway.routes[0].filters[0]=PrefixPath=/users

main

@SpringBootApplication
@EnableDiscoveryClient
public class Demo04Gateway1001Application 

面向服务的路由 uri

  • (1)面向服务的路由是什么?
    配置路由信息时,使用服务的名称来代替 ip+port的配置方式
    只需要在配置文件中指定路由路径类似: lb://user-service
  • (2)代理的服务地址;lb表示从eureka中获取具体服务
  • (3)注意事项
    lb 之后编写的服务名必须要在eureka中注册才能使用
  • (4)分析
    路由配置中uri所用的协议为lb时(以uri: lb://user-service为例),gateway将使用 LoadBalancerClient把user-service通过eureka解析为实际的主机和端口,并进行ribbon负载均衡。

路由前缀处理 filter

  • (1)路由的前缀
    请求地址与微服务的服务地址如果不一致的时候,可以通过配置路径过滤器实现路径前缀的添加和去除。
    提供服务的地址:http://127.0.0.1:8001/user/8
    》 添加前缀:对请求地址添加前缀路径之后再作为代理的服务地址;
    http://127.0.0.1:101/8 --> http://127.0.0.1:8001/user/8 添加前缀路径/user
spring.cloud.gateway.routes[0].predicates[0]=Path=/**
spring.cloud.gateway.routes[0].filters[0]=PrefixPath=/users

》去除前缀:将请求地址中路径去除一些前缀路径之后再作为代理的服务地址;
http://127.0.0.1:101/api/user/8 --> http://127.0.0.1:8001/user/8 去除前缀路径/api

spring.cloud.gateway.routes[0].predicates[0]=Path=/api/users/**
spring.cloud.gateway.routes[0].filters[0]=StripPrefix=1

过滤器简介

  • (1)过滤器
    符合条件的请求放行,否则不放行
  • (2)Gateway自带过滤器有几十个,常见自带过滤器有
    在配置文件中指定要使用的过滤器名称
  • (3)案例:添加响应头过滤器
spring.cloud.gateway.default-filters[0]=AddResponseHeader=name,rose
spring.cloud.gateway.default-filters[1]=AddResponseHeader=age,34

在这里插入图片描述

过滤器分类

  • (1)过滤器的分类 两类
    》局部过滤器
    只对当前路由起作用
    spring.cloud.gateway.routes.filters
    》全局过滤器
    作用在所有的路由上
    》spring.cloud.gateway.default-filters + 实现GatewayFilterFactory接口的过滤器
    》实现GlobalFilter接口,不需要配置
    在这里插入图片描述

自定义全局过滤器

判断请求上的token值是否为空,不为空放行

  • (1)实现GlobalFilter
  • (2)实现Ordered接口
  • (3)符合条件,放行
  • (4)否则结束响应
//1:本类为全局网关过滤器 /*
@Component
@Slf4j
public class MyGlobalFilter  implements GlobalFilter, Ordered {
    
    
    //exchange  =  req + resp
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    
    
        //拦截方法,拦截到请求后,自动执行
        log.info("filter 拦截方法,拦截到请求后,自动执行 ");
        //以后开发中,不会将 user对象存到session,只会在地址上带上token
        //根据token是否有空可以判断是否登录
        //http://localhost:8001/users/3?token=10001&pageSize=30
        String token = exchange.getRequest().getQueryParams().getFirst("token");
        if(token == null || "".equals(token)){
    
    
            //未登录 跳转到登录页
            log.info("----跳到登录页面");
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);//2 全部放行
    }

    @Override
    public int getOrder() {
    
    //3:系统调用该方法获得过滤器的优先级
        return 1; //数字越小,越优先
    }
}

自定义局部过滤器

  • (1)使用场景:请求鉴权、异常处理、记录调用时长等。
  • (2)步骤
    》》配置
    MyParam=name,address
    》》定义Config
    》》MyParamGatewayFilterFactory继承AbstractGatewayFilterFactory
    》》实现shortcutFieldOrder
    》》实现apply

application.properties

spring.cloud.gateway.routes[0].filters[0]=MyParam=name,address

MyParamGatewayFilterFactory

//1:本类为局部过滤器类
@Component
@Slf4j
public class MyParamGatewayFilterFactory extends AbstractGatewayFilterFactory<MyParamGatewayFilterFactory.Config> {

    //5:将config交给父类的构造方法

    public MyParamGatewayFilterFactory() {
        super(Config.class);
    }

    @Override //4:过滤器
    public GatewayFilter apply(Config config) {
        GatewayFilter gatewayFilter = new GatewayFilter(){

            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                //http://127.0.0.1:1001/users/3?token=333&name=jack&address=bj
                String name = exchange.getRequest().getQueryParams().getFirst(config.name);
                String address = exchange.getRequest().getQueryParams().getFirst(config.address);
                log.info("filter ....name"+name);
                log.info("filter ....address"+address);
                log.info("filter ....拦截了请求");
                return chain.filter(exchange);//全部放行
            }
        };
        return gatewayFilter;//返回一个自己定义的过滤器
    }

    //3:定义顺序
    @Override
    public List<String> shortcutFieldOrder() {//定义变量的顺序
        List<String> order = new ArrayList<>();
        order.add("name");
        order.add("address");
        return order;
    }

    //name,address
    //http://127.0.0.1:8001/users/1?name=jack&address=bj
    @Data //2:定义config
    public static class Config{
        private String name;
        private String address;
    }
}

Guess you like

Origin blog.csdn.net/qq_40711092/article/details/110245100