springcloud06-服务网关

zuul路由网关(已经废弃)

Gateway网关(最新技术spring社区研发)

1、概述简介

zuul官网:https://github.com/Netflix/zuul/wiki

getway官网:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/

1、是什么?

springcloud gateway 是zuul1.x版本的替代

image-20210217075102016.png

Gateway是在Spring生态系统之上构建的API网关服务基于Spring 5, Spring Boot 2和Project Reactor等技术。

Gateway旨在提供-种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能, 例如: 熔断、限流、重试等

SpringCloud Gateway是Spring Cloud的一个全新项目,基纡Spring 5.0+ Spring Boot 2.0和Project Reactor等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一 的API路由管理方式。

SpringCloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 1.x非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。

Spring Cloud Gateway的目标提供统-的路由方式且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。

2、可以做什么

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

正向代理:就是客户端请求一个服务端A告诉这个服务A我要请求服务B。服务端A再去请求服务端B,服务端B把数据返回给服务端A,服务端A再把数据返回给客户端

反向代理:客户端去请求服务A想要获取数据,服务A请求其他的服务器获取数据后把数据返回给客户端。

image-20210217075511373.png

3、有了zuul为什么还有出gateway

为什么选gateway:

image-20210217075657350.png
image-20210217075723940.png

4、zuul1.x模型

在SpringCloud Finchley正式版之前,Spring Cloud推荐的网关是Netflix 提供的Zuul:

1、Zuul1.x, 是一个基于阻塞I/ 0的API Gateway

2、Zuul 1.x基于Servlet 2.5使用阻塞架构它不支持任何长连接(如WebSocket) Zuul的设计模式和Nginx较像,每次|/ 0操作都是从工作线程中选择一个执行, 请求线程被阻塞到工作线程完成,但是差别是Nginx用C++实现,Zuul 用Java实现,而JVM本身会有第一次加载较慢的情况,使得Zuul的性能相对较差。

3、Zuul 2.x理念更先进,想基于Netty非阻塞和支持长连接,但SpringCloud目前还没有整合。 Zuul 2.x的性能较Zuul 1.x有较大提升。在性能方面,根据官方提供的基准测试,Spring Cloud Gateway的RPS (每秒请求数)是Zuul的1.6倍。

4、Spring Cloud Gateway建立在Spring Framework 5、Project Reactor和Spring Boot2之上,使用非阻塞API。

5、Spring Cloud Gateway还支持WebSocket,姐与Spring紧密集 成拥有更好的开发体验

image-20210217080019329.png
image-20210217080118228.png

5、gateway模型

传统的Web框架,比如说: struts2, springmvc等都是 基于Servlet API与Servlet容器基础之上运行的。

但是

在Servlet3.1之后有了异步非阻塞的支持。而WebFlux是一个典型非阻塞 异步的框架,它的核心是基于Reactor的相关API实现的。相对于传统的web框架来说,它可以运行在诸如Netty, Undertow及 支持Servlet3.1的容器上。非阻塞式+函数式编程(Spring5必须让你使用java8)

Spring WebFlux是Spring 5.0引入的新的响应式框架,区别于Spring MVC,不要依赖Servlet API,它是完全异步非阻塞的,并且基盱Reactor来实现响应式流规范。

2、三大核心概念

Route(路由)

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

Predicate(断言)

参考的是Java8的java.util.function.Predicate

开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路釉

Filter(过滤)

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

总体

image-20210217080836333.png

3、gateway工作流程

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

image-20210217080954630.png

Clients make requests to Spring Cloud Gateway. If the Gateway Handler Mapping determines that a request matches a Route, it is sent to the Gateway Web Handler.This handler runs sends the request through a filter chain that is specific to the request. The reason the filters are divided by the dotted line, is that filters may executelogic before the proxy request is sent or after. All “pre” filter logic is executed, then the proxy request is made. After the proxy request is made, the “post” filter logic isexecuted.

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

Handler再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前( “pre” )或之后( “post” )执行业务逻辑。

Filter在"pre” 类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等,在"post"类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等有着非常重要的作用。

4、gateway入门配置

1、新建一个gateway微服务并且注册到eureak中

这里有个坑,starter-web是我之前做common的时候引入进去的。从这里排除的话可以排除但是后面确实出现了很多问题,直接从common中去start-web比较好用

添加maven依赖

    <dependencies>
		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-webflux</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>com.dkf.cloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </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>

添加yml依赖

server:
  port: 9527
spring:
  application:
    name: cloud-gateway

eureka:
  instance:
    hostname: cloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://eureka7001.com:7001/eureka

配置启动类

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

2、之后在application.yml中进行网关配置

spring: 
  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/**                #断言,路径相匹配的进行路由

使用gateway的时候记得排除spring-boot-starter-web,spring-boot-starter-webflux两个组件

配置路由的两种方式

第一种使用yml文件进行配置,和上面的最后一步一样的格式配置就好

第二种使用配置文件:

@Configuration
public class GateConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        routes.route("path_route_atguigu", r -> r.path("/guonei").uri("http://news.baidu.com/guonei")).build();
        routes.route("path_route_guoji", r -> r.path("/guoji").uri("http://news.baidu.com/guonji")).build();
        return routes.build();
    }
}

动态配置路由

默认情况下Gateway会根据注册中心注册的服务列表,以注册中心微服务名为路径动态创建动态路由进行转发,从而实现动态路由的功能

1、启动:一个7001和两个8001/8002

2、pom添加依赖

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

3、配置开启动态路由

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
        - id: payment_routh 
#          uri: http://localhost:8001        
          uri: lb://CLOUD-PAYMENT-SERVICE #动态路由指向服务名称
          predicates:
            - Path=/payment/get/**                   
        - id: payment_routh2
#          uri: http://localhost:8001             
          uri: lb://CLOUD-PAYMENT-SERVICE #动态路由指向服务名称
          predicates:
            - Path=/payment/lb/**      
      #开启动态路由
      discovery:
        locator:
          enabled: true

完成配置后就可以使用负载均衡功能(某人竟然因为忘记启动8002在网上找了半天错误。o(╥﹏╥)o)

5、Predicate的使用

1、是个啥玩意

启动的时候后台启动中的信息
image-20210217184522971.png

这些都是用于判断指定的访问是否符合某种格式

获取指定时间的方法:

@Test
public static void main(String[] args){
    ZonedDateTime zbj = ZonedDateTime.now();
    System.out.println(zbj);
}
// 2021-02-17T20:27:46.141+08:00[Asia/Shanghai]

2、怎么用这个玩意

curl的使用

在cmd下使用curl发送get请求

curl http://localhost:9527/payment/lb --cookie "name=caochen"  # 携带cookie
 
curl http://localhost:9527/pyament/lb   # 正常访问没有cookie

curl http://localhost:9527/pyament/lb -H "X-Request-Id:1234" #携带请求头

curl http://localhost:9527/pyament/lb -H "Host: www.atguigu.com" #携带请求头

(1)、after

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
          predicates:
            - Path=/payment/get/**                    #断言,路径相匹配的进行路由
            - After=2021-02-17T20:27:46.141+08:00[Asia/Shanghai] #在这个时间之前的时间内都不能完成调度

(2)、Before

- Before=2021-02-17T20:27:46.141+08:00[Asia/Shanghai] #在这个时间之后的时间内都不能完成调度

(3)、Between

- Between=2021-02-17T20:27:46.141+08:00[Asia/Shanghai],2021-02-17T22:27:46.141+08:00[Asia/Shanghai] #在这个时间之中的时间内都不能完成调度

(4)、Cookie

- Cookie=chocolate, ch.p #携带这个cookie的才可以通过

(5)、Header

- Header=X-Request-Id, \d+ #携带头的并且为正整数

(6)、Host

- Host=**.somehost.org,**.anotherhost.org #路径包含这些部分可以请求

(7)、Method

- Method=GET,POST #get或者post方法可以请求

(8)、Path

- Path=/red/{segment},/blue/{segment} #这个路径可以请求

(9)、Query

- Query=green

6、Filter的使用

过滤器工厂(31个)

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gatewayfilter-factories

全局过滤器(10个)

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#global-filters

自定义过滤器

@Component
@Slf4j
public class GateWayFilter implements GlobalFilter, Ordered {

    @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,非法用户,o(╥﹏╥)o");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值