SpringCloudGateway基于WebFlux框架实现,WebFlux框架底层采用高性能Reactor模式通信框架Netty。Cloud全家桶中一个非常重要的组件就是网关,在1.x版本的Zuul网关中就用到了;但是在2.x版本中,zuul的升级被跳过了,SpringCloud终于开发了一个gateway来替代Zuul,也就是SpringCloudGateway——一句话:gateway是原来zuul1.x版本的替代品。Gateway是构建在Spring生态系统之上的API网关服务,基于Spring5、SpringBoot2和ProjectReactor等技术。Gateway旨在提供一种简单有效的API路由方式,并提供一些强大的过滤功能,如:熔断、限流、重试等。SpringCloudGateway是SpringCloud的一个全新项目,基于Spring5.0+SpringBoot2.0和ProjectReactor等技术,旨在为微服务架构提供简单有效的统一API路由管理方式。SpringCloudGateway作为SpringCloud生态中的网关,旨在替代Zuul。在SpringCloud2.0及以上,没有集成Zul2.0及以上最新的高性能版本,仍然使用Zuul1.x非Reactor模式老版本。为了提高网关的性能,SpringCloudGateway基于WebFlux框架实现,WebFlux框架底层采用高性能Reactor模式通信框架Netty。SpringCloudGateway的目标是提供统一的路由方式,提供基于Filter链的网关基本功能,如:安全、监控/指标、限流等。3.为什么选择网关?Gateway的特性基于SpringFramework5、ProjectReactor和SpringBoot2.0构建;动态路由:可以匹配任何请求属性;可以指定Predicate(断言)和Filter(过滤器)进行路由;集成Hystrix的断路器功能;集成SpringCloud服务发现功能;易于编写的Predicate(断言)和Filter(过滤器);请求限流功能;支持路径重写。SpringCloudGateway和Zuul的区别在SpringCloudFinchley正式版之前,SpringCloud推荐的网关是Netflix提供的Zuul。Zuul1.x,是一个基于阻塞I/O的API网关。Zuul1.x基于Servlet2.5,采用阻塞式架构。它不支持任何长连接(例如WebSocket)。Zuul的设计模式与Nginx类似。每个I/О操作都从工作线程中选择执行,请求线程被阻塞。工作线程完成,但是不同的是Nginx是用C++实现的,Zuul是用Java实现的,JVM本身第一次加载会比较慢,使得Zuul的性能比较差。Zuul2.x有更高级的概念,想基于Netty非阻塞,支持长连接,但是SpringCloud还没有集成。Zuul.x的性能相比Zuul1.x有了很大的提升。在性能方面,根据官方的benchmark测试,SpringCloudGateway的RPS(requestspersecond)是Zuul的1.6倍。SpringCloudGateway建立在SpringFramework5、ProjectReactor和SpringBoot2之上,使用非阻塞API。SpringCloudGateway同样支持WebSocket,与Spring紧密结合,开发体验更好http://www.bilibili.com/media...http://www.bilibili.com/media...http://www.bilibili.com/media...http://www.bilibili.com/media...http://www.bilibili.com/media...http://www.thinksaas.cn/user/。..2.三个核心概念1.三个概念Route(路由):路由是构建网关的基本模块。它由ID、目标URI、一系列断言和过滤器组成。如果断言为真,则匹配路由;Predicate(断言):参考Java8的java.util.function.Predicate。开发者可以匹配HTTP请求中的所有内容(如请求头或请求参数),如果请求匹配断言则进行路由;过滤器(Filter):指Spring框架中GatewayFilter的实例。使用过滤器,可以在路由之前或之后修改请求。2.Gateway的工作流客户端向SpringCloudGateway发送请求。然后在GatewayHandlerMapping中找到符合请求的路由,发送给GatewayWebHandler。Handler然后通过指定的过滤器链将请求发送给我们实际的服务执行业务逻辑,然后返回。过滤器由虚线分隔,因为过滤器可能在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。三、网关配置1、环境新建模块:cloud-gateway-gateway9527pom:cloud2021com.atguigu1.0.0-SNAPSHOT4.0.0com.atguigu.springcloudcloud-gateway-gateway9527org.springframework.cloudspring-cloud-starter-gatewayorg.springframework.cloudspring-cloud-starter-netflix-eureka-clientcom.atguigu.springcloudcloud-api-commons${project.version}org.springframework.bootspring-boot-devtoolsruntimetrueorg.projectlomboklomboktrueorg.springframework.bootspring-boot-starter-testtest复制代码yaml:server:port:9527spring:application:name:cloud-gatewayeureka:instance:hostname:cloud-gateway-serviceclient:#服务提供者provider注册在eureka服务列表service-url:register-with-eureka:truefetch-registry:truedefaultZone:http://eureka7001.com:7001/eureka复制代码主启动类:@SpringBootApplication@EnableEurekaClientpublicclassGateWayMain9527{publicstaticvoidmain(String[]args){SpringApplication.run(GateWayMain9527.class,args);}}复制代码业务类:无2.网关配置为了保证路由和跳转,添加如下代码:server:port:9527spring:application:name:cloud-gateway###############################新网关配置#############################cloud:gateway:routes:-id:payment_routh#payment_route#路由的ID没有固定规则但是重新要求是独一无二的。建议配合服务名uri:http://localhost:8001#匹配后提供服务的路由地址#uri:lb://cloud-payment-service#匹配谓词后提供的服务的路由地址:-Path=/payment/get/**#断言路由匹配路径-id:payment_routh2#payment_route#路由的ID,没有固定的rule但要求唯一,建议配合服务名uri:http://localhost:8001#匹配后提供服务的路由地址#uri:lb://cloud-payment-service#路由地址匹配谓词后提供服务:-Path=/payment/lb/**#断言路径匹配路由eureka:instance:hostname:cloud-gateway-serviceclient:#服务提供者provider在eureka服务列表中注册service-url:register-with-eureka:truefetch-registry:truedefaultZone:http://eureka7001.com:7001/eureka复制代码开始测试这次访问http://localhost:9527/payment...和就是这样。3.编码方式配置上面使用yaml方式进行配置,现在可以使用编码方式进行配置。@ConfigurationpublicclassGateWayConfig{@BeanpublicRouteLocatorcustomRouteLocator(RouteLocatorBuilderrouteLocatorBuilder){RouteLocatorBuilder.Builderroutes=routeLocatorBuilder.routes();routes.route("path_route_atgueigu",r->r.path("/guonei(http").uri://news.baidu.com/guonei")).build();returnroutes.build();}}复制代码,直接访问http://localhost:9527/guonei4.根据微服务名实现动态路由这里需要模拟使用gateway实现动态路由,而不是ribbon。9527模块的yaml文件修改如下:server:port:9527spring:application:name:cloud-gateway新建网关配置cloud:gateway:discovery:locator:enabled:true#开启动态创建路由功能注册中心,路由路由使用微服务名:-id:payment_routh#payment_route#路由的ID,没有固定规则但要求唯一,建议配合服务名#uri:http://localhost:8001#路由地址uri:lb://cloud-payment-service#匹配谓词后提供的服务的路由地址:-Path=/payment/get/**#断言路由匹配路径-id:payment_routh2#payment_route#路由的ID,没有固定的规则,但是要求是唯一的,建议配合服务名#uri:http://localhost:8001#路由地址为匹配uri后提供服务:lb://cloud-payment-service#路由广告dressforprovideservicesaftermatchingpredicates:-Path=/payment/lb/**#Assertthepathmatchestheroutingeureka:instance:hostname:cloud-gateway-serviceclient:#服务提供者provider在eureka服务列表服务中注册-url:register-with-eureka:truefetch-registry:truedefaultZone:http://eureka7001.com:7001/eureka复制代码开始测试:localhost:9527/payment/lb,发现轮询操作确实已经实现了。这些进入网关官网后(上面有),总共发现11个谓词什么是谓词?SpringCloudGateway匹配路由作为SpringWebFluxHandlerMapping基础设施的一部分。SpringCloudGateway包括许多内置的RoutePredicate工厂。所有这些Predicates都匹配HTTP请求的不同属性。可以组合多个RoutePredicate工厂。SpringCloudGateway在创建Route对象时,使用RoutePredicateFactory创建Predicate对象,Predicate对象可以赋值给Route。SpringCloudGateway包括许多内置的路由谓词工厂。所有这些谓词都匹配HTTP请求的不同属性。可以组合各种谓词工厂并通过逻辑与。AfterRoutePredicateFactory的使用是按照官网:在yaml文件下加一行即可,但是需要修改为Chinatime:test,发现可以通过这种方式获取到上述格式的时间:publicclassT2{publicstaticvoidmain(String[]args){ZonedDateTimezbj=ZonedDateTime.now();System.out.println(zbj);}}//Output//2021-11-23T10:44:35.485+08:00[Asia/Shanghai]复制代码然后修改:routes:-id:payment_routh#payment_route#The路由的ID,没有固定规则但要求唯一,建议配合服务名#uri:http://localhost:8001#匹配uri:lb:/后提供的服务的路由地址/cloud-payment-service#匹配谓词后提供服务的路由地址:-Path=/payment/lb/**-After=2021-11-23T10:44:35.485+08:00[Asia/Shanghai]复制代码那么这意味着上述路由只能在一定时间后才能使用。现在修改上面的after时间,然后开始测试,发现报错,说明确实生效了。这个有点类似于秒杀场景,或者项目可以定时上线。采用这种方法。CookieRoutePredicate的使用就是询问是否带cookie,或者带什么样的cookie。CookieRoutePredicate需要两个参数,一个是cookie名称,一个是正则表达式。路由规则会将cookie与正则表达式匹配。id:payment_routh2#payment_route#路由的ID,没有固定规则但要求唯一,建议配合服务名uri:http://localhost:8001#提供服务的路由地址uriaftermatching:lb://cloud-payment-service#匹配后提供的服务的路由地址predicates:Path=/payment/lb/**#断言路径匹配路由After=2021-11-23T10:44:35.485+08:00[Asia/Shanghai]Cookie=username,James复制这里的代码,通过curl发送请求:其他的可以按照官网写。6.过滤器的使用路由过滤器可用于修改传入的HTTP请求和返回的HTTP响应。路由过滤器只能通过指定路由来使用。SpringCloudGateway内置了多种路由过滤器,它们都是由GatewayFilter工厂类生成的。过滤器一般只有两种:GatewayFilterGlobalFilter自定义的全局过滤器过滤器太多,学习起来很麻烦。下面是一个实现自定义过滤器的例子,也比较通用。如果需要的话,可以自己配置:创建一个包过滤器,然后创建一个需要实现两个接口的过滤器类:ServerWebExchange交换,GatewayFilterChain链){log.info("***********进来MyLogGateWayFilter:"+newDate());Stringuname=exchange.getRequest().getQueryParams().getFirst("uname");if(uname==null){log.info("*******用户名为null,非法用户,o(╥﹏╥)o");exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);返回exchange.getResponse()。设置完成();}返回链。过滤器(交换);}@OverridepublicintgetOrder(){返回0;}}