95-java-springcloud(08)-网关-gateway

gateway

网关是什么,网关是一切外部访问程序的入口,他控制这这个服务架构的出入,鉴权,代理,流控,监控等.
在这里插入图片描述

一.简介

1.官网

官网地址:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.3.RELEASE/reference/html/#gateway-starter

2.是什么?

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Spring Cloud Gateway 使用的Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架
在这里插入图片描述

3.作用

网关在微服务架构中的位置
在这里插入图片描述
作用:

  • 反向代理
  • 鉴权
  • 流量控制
  • 熔断
  • 日志监控
  • 等等
4.gateway于zuul的区别和特性

gateway的特性:

  • 动态路由
  • 路由断言(Predicate)和过滤(filter)
  • 继承Hystrix的断路器功能
  • 继承springcloud的服务注册与发现功能
  • 请求限流
  • 支持路劲重写

gateway和zuul的区别

  • gateway是基于NIO的,非阻塞式架构模型
  • zuul是基于阻塞IO模型的.
  • gateway还支持webSocket,并且与spring紧密集成.

二.gateway的原理分析

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

在这里插入图片描述

2.gateway的工作流程

在这里插入图片描述
步骤:

  • 请求发送到handler Mapping上,handler mapping对比predicate(断言)匹配路劲.
  • 在发送到web handler上,handler在经过一系列的过滤链.
  • 经过过滤链之后才是发送到具体的微服务上请求服务.
  • 再请求之后还会经过一系列的过滤链,回到web handler.
  • web handler再返回给handler mapping.

总结:路由转发,断言匹配,过滤,执行业务

三.gateway搭建

1.基本使用

(1) 建module

(2) 改pom

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

(3) 写yml

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

#eureka,本服务也需要注册到eureka上
eureka:
  instance:
    hostname: cloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://eureka7001.com:7001/eureka
 
 

(4) 主启动
没有特定的启动类

@SpringBootApplication
@EnableEurekaClient
public class GateWayMain9527 {
    public static void main(String[] args) {
            SpringApplication.run( GateWayMain9527.class,args);
        }
}
 

(5) 测试

  • 1)第一步,Eureka
  • 2)第二步,启动8001的服务
  • 3)第三步,启动gateway网关服务
    #查看两个服务是否已经注册到eureka上了
    在这里插入图片描述
  • 4)验证浏览器是否能够通过网关访问到8001上的服务.
    8001项目上/payment/lb接口的代码
 //自己手写轮询算法访问测试的请求路劲
    @GetMapping(value = "/payment/lb")
    public String getPaymentLB(){
        return serverPort+"";
    }

测试结果
在这里插入图片描述

2.路由
(1) 路由组成

在这里插入图片描述

  • id
    #当前路由地址的编号,或者名字
  • uri
    #当前路由地址,路由服务地址
  • predicates
    #当前路由地址的匹配断言规则
  • filters
    #当前路由地址的过滤规则.
(2) 路由的配置方法

1) yml配置(建议使用)

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启路由发现功能
      routes:
        - id: payment_routh2
          #uri: http://localhost:8001
          uri: lb://cloud-payment-service  #动态路由
          predicates: #下面的断言条件,首字母必须大写
            - Path=/payment/lb/**   #断言,路径相匹配的进行路由
            - After=2020-06-19T14:51:51.252+08:00[Asia/Shanghai] #断言 发送的时间要在这个时间之后
            #- Cookie=username,gl  #断言,携带cookie,username=gl
            #- Header=X-Request-Id, \d+ #请求头中要有X-Request-Id属性并且值为整数的正则表达式
            #- Host=**.atguigu.com #断言  主机
            #- Method=GET #断言 请求方式为GET请求
            #- Query=username, \d+ #要有参数名称并且是正整数才能路由
          filters:
            - AddRequestHeader=X-Request-red, blue


# 第二个路由地址
        - id: payment_routh #路由的ID,没有固定规则但要求唯一,建议配合服务名
          #uri: http://localhost:8001   #匹配后提供服务的路由地址
          uri: lb://cloud-payment-service  #动态路由
          predicates:  #断言,路径相匹配的进行路由
            - Path=/payment/**
            - After=2020-06-19T14:51:51.252+08:00[Asia/Shanghai]
            - Cookie=username,gl

2) 代码注入
通过代码注入RouteLocator bean的方式,配置路由

@Configuration
public class GateWayConfig {
    /**
     * 代码配置路由规则bean
     */
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        /**
         * gl_baidu_01:路由名
         * path:路由路劲
         * uri:路由转发的服务或者服务地址
         * ...
         */
        routes.route("gl_baidu_01", r -> r.path("/tiyu").uri("http://news.baidu.com")).build();
        return routes.build();
    }

}
(3) 动态路由
  • 默认情况,gateway从通过微服务名称,从注册中心获取服务地址,并且可以实现负载均衡算法.

  • uri: lb://cloud-payment-service
    #lb:表示使用负载均衡算法,必须使用
    #cloud-payment-service:表示调用的服务名称

在这里插入图片描述

(4) Predicate(断言)

参考官网: https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.3.RELEASE/reference/html/#gateway-request-predicates-factories

1) 是什么?
这是用于匹配路由路劲的规则,只有满足predicate(断言)定义的规则才可能被转发到下一级步骤.

2) 常用的predicate属性如下:

 predicates: #下面的断言条件,条件的首字母必须大写
            - Path=/payment/lb/**   #断言,路径相匹配的进行路由
            - After=2020-06-19T14:51:51.252+08:00[Asia/Shanghai] #断言 发送的时间要在这个时间之后
            - Cookie=username,gl  #断言,携带cookie,username=gl
            - Header=X-Request-Id, \d+ #请求头中要有X-Request-Id属性并且值为整数的正则表达式
            - Host=**.atguigu.com #断言  主机
            - Method=GET #断言 请求方式为GET请求
            - Query=username, \d+ #要有参数名称并且是正整数才能路由
(5) Filter(过滤器)

参考官网: https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.3.RELEASE/reference/html/#gateway-request-predicates-factories

1) 是什么?
filter(过滤器)这是过滤请求,将请求过滤,可以实现权限,日志,熔断等规则.

2) filter的种类

[1]GatewayFilter
#单一的过滤器
作用:这种方式配置的是针对单一路由路劲的过滤器规则.
配置方式:

 filters: #过滤器规则
            - AddRequestHeader=X-Request-red, blue #将所有的请求头中添加,  X-Request-red:blue
            - AddRequestParameter=red, blue #将所有的请求中添加参数,red,blue
            - name: Hystrix  #添加hystrix熔断
                      args:
                        name: fallbackcmd
                        fallbackUri: forward:/incaseoffailureusethis #熔断方法

[2] GlobalFilter
#全局的过滤器,
作用:全局日志记录/统一网关鉴权
配置方式:

/**
*GlobalFilter:全局filter顶级接口.
*Ordered :过滤器级别顶级接口
*/
@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter,Ordered {

    /**
     * 定义filter(过滤器)
     * @param exchange request相关对象
     * @param chain 过滤链
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("==================come in MyLogGateWayFilter:" + new Date());
        String username = exchange.getRequest().getQueryParams().getFirst("username");
        if(username ==  null){
            log.error("===============你没有登陆参数,无权访问");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    /**
     * 过滤器的级别
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

3) filter的作用时机

  • pre
    #请求之前,在业务逻辑之前
  • post
    #请求之后,在业务逻辑之后
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值