SpringCloud Hoxton版微服务- Gateway网关


一、Gateway概念

Cloud全家桶有个狠重要的组件就是网关,在1.x版本中都是采用Zuul网关;但是在2.x版本中,zuul的升级一致跳票,SpringCloud最后自己研发了一个网关替代Zuul, 那就是SpringCloud Gateway

二、三大核心概念

1.Route (路由)

路由是构建网关的基本模块,它由ID,目标URL,一系列的断言和过滤器组成,如果断言为true则匹配该路由

2.Predicate (断言)

参考的是Java8的java.util.function.predicate
开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由

3.Filter (过滤)

指的是Spring框架中的GatewayFilter 的实例,使用过滤器,可以在请求被路由前或者之后请求进行修改

三、工作流程图

在这里插入图片描述

客户端向 Spring Cloud Gateway 发出请求。如果 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。 过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。

四、工程搭建

1、新建Gateway网关工程

在这里插入图片描述

2、添加项目需要使用的依赖包

<dependencies>
    <!--gateway-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <!--consul-server服务注册发现-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-consul-discovery</artifactId>
    </dependency>
</dependencies>

3、application.yml配置

server:
  port: 8080
spring:
  application:
    name: cloud-gateway
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        service-name: ${spring.application.name}  # 注册到consul的服务名称
    gateway:
      routes:
        - id: payment_routh            #路由ID,没有固定的规则单要求唯一,最好和服务名称配置一致
          uri: http://localhost:9001   #匹配后提供路由的服务地址
          predicates:
            - Path=/payment/get/**     #断言,路径相匹配的进行断言
        - id: payment_routh            #======================可以匹配多个=======================
            uri: http://localhost:9001 #匹配后提供路由的服务地址
            predicates:
              - Path=/payment/consul/**   #断言,路径相匹配的进行断言

4、启动器

/**
 * @description: 网关启动器
 * @author: ydf
 * @date: 2021/1/3 16:08
 * @version: v1.0
 */
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
public class GatewayAppMain {

    public static void main(String[] args) {
        SpringApplication.run(GatewayAppMain.class,args);
    }
}

5、测试

在这里插入图片描述
在这里插入图片描述

6、转发功能同样可以通过代码来实现

/**
 * @description: Gateway配置
 * @author: ydf
 * @date: 2021/1/3 16:30
 * @version: v1.0
 */
@Configuration
public class GatewayConfig {

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

}

在这里插入图片描述

上面配置了一个 id 为 path_route 的路由,当访问地址http://localhost:8080/guonei时会自动转发到地址:http://news.baidu.com/guonei和上面的转发效果一样,只是这里转发的是以项目地址/guonei格式的请求地址。

7、开启动态创建路由

 gateway:
      discovery:
        locator:
          enabled: true   #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: payment_routh1
          #uri: http://localhost:9001
          uri: lb://provider-service #匹配后提供的路由地址(微服务名进行路由)
          predicates:
            - Path=/payment/get/**
        - id: payment_routh2
          #uri: http://localhost:9002
          uri: lb://provider-service #匹配后提供的路由地址(微服务名进行路由)
          predicates:
            - Path=/payment/consul/**

测试:
在这里插入图片描述
在这里插入图片描述

五、Gateway常用Predicate

Predicate 就是为了实现一组匹配规则,方便让请求过来找到对应的 Route 进行处理,接下来我们接下 Spring Cloud GateWay 内置几种 Predicate 的使用。

官方配置:https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/#gateway-request-predicates-factories

在这里插入图片描述
这里的配置有十多种,官方说的很明确,改一下配置文件就行了,这里小编就不演示了。

六、Gateway的Filter

全局过滤器配置:https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/#global-filters

配置类:

/**
 * @description: 全局配置Gateway的过滤器
 * @author: ydf
 * @date: 2021/1/3 19:35
 * @version: v1.0
 */
@Component
public class CustomGatewayFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("GlobalFilter***************************"+new Date());
        //模拟演示拦截---实际生产当中可以拦截验证头部是否携带token等
        String uname = exchange.getRequest().getQueryParams().getFirst("uname");
        if(uname == null){
            System.out.println("uname为null,非法用户");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

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

测试:
在这里插入图片描述
在这里插入图片描述
携带正确的参数,再次请求测试:

http://localhost:8080/payment/consul?uname=dtydf

在这里插入图片描述

总结

小总结: 实际项目中网关微服务一般都用来作为整个服务入口的鉴权操作,假设我们再对JWT的加解密过程中使用的对称加密算法,这样就会不可避免的导致一个安全隐患:如果有恶意请求利用密钥生成了JWT令牌来进行登录操作,那就会产生不可预知的后果!
解决方式:
采用非对称算法,生成一个存储着公钥和私钥的密钥库,在生成JWT的时候,使用私钥来进行加密,而解析JWT的服务使用公钥来解析JWT,这样将加密和解析的两把密钥分开来,就可以阻止恶意用户对系统产生恶意攻击了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DT辰白

你的鼓励是我创作的源泉

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值