1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > SpringCloud实战---第十五篇:微服务网关GateWay

SpringCloud实战---第十五篇:微服务网关GateWay

时间:2023-06-15 21:49:34

相关推荐

SpringCloud实战---第十五篇:微服务网关GateWay

系列文章目录

SpringCloud快速入门到精通各组件原理

专栏传送门


文章目录

系列文章目录前言一、关于Zuul和GateWay二、GateWay简介三、GateWay三大概念1. Route(路由)2. Predicate(断言)3. Filter(过滤)4. 总体构建基础工程话不多说,立马开干四、GateWay9527模块搭建1. 创建cloud-gateway-gateway9527模块2. 配置路由3. 启动测试五、GateWay的两种配置方式1. 新建配置类2. 启动测试六、GateWay动态路由1. 修改9527配置文件2. 启动测试七、GateWay的Predicate断言八、GateWay的Filter过滤器1. 是个啥2. 周期3. 种类-局部的4. 种类-全局的5. 自定义过滤器(重点)总结

前言

我们学习的知识框架图

说起来容易做起来难,一步一步都干完!!!

学习一定要自己动手搞一搞,不能只眼会。

学习笔记是跟着尚硅谷的视频学的:/video/BV18E411x7eT?p=1


一、关于Zuul和GateWay

zuul是最早的网关组件,但是由于核心人员的离开及更新不及时,导致zuul2胎死,SpringCloud自己研发了一个GateWay网关组件来替换zuul,因此我们不再学习zuul,学习最新的GateWay。

二、GateWay简介

GateWay的目标是提供统一的路由方式,且基于Filter链的方式提供了网关的基本功能,例如:安全、监控/指标、限流。GateWay是SpringCloud自研的用于替代Zuul1.0的网关。GateWay基于WebFlux框架实现,而WebFlux框架的底层使用的是高性能的Reactor模式的通信框架Netty。

优点基于SpringBoot2.0构建,天然与SpringCloud整合。动态路由:能够匹配任何请求属性。可以对路由指定Predicate(路由)和Filter(过滤器)。集成Hystrix断路器功能。集成SpringCloud服务发现功能。请求限流功能。支持路径重写。易于编写的Predicate和Filter。GateWay官网https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/。

三、GateWay三大概念

1. Route(路由)

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

2. Predicate(断言)

开发人员可以匹配HTTP请求中的所有内容,如果请求与断言相匹配则进行路由。

3. Filter(过滤)

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

4. 总体

Predicate可以理解为是我们的匹配条件,而Filter可以无所不能的拦截器。有了这两个元素,再加上目标URI,就可以实现一个具体的路由了。GateWay的核心逻辑就是路由转发和执行过滤链。

构建基础工程

先构建好基础工程(一篇一篇看过来的不用重新构建)

构建基础父工程:/weixin_43464964/article/details/121979995

Rest风格微服务:/weixin_43464964/article/details/121980366

传统分布式方法:/weixin_43464964/article/details/121999966

改造工程,抽取公共模块:/weixin_43464964/article/details/122000586

使用Eureka:/weixin_43464964/article/details/122045319

Eureka集群: /weixin_43464964/article/details/122046056

想偷懒的请下载;gitee上我上传的代码: /xiaoZ1712/cloud

基础工程构建完成的目录结构:

启动所有模块,访问

localhost:7001

显示如下,代表基础工程没问题

话不多说,立马开干

四、GateWay9527模块搭建

1. 创建cloud-gateway-gateway9527模块

模块名

cloud-gateway-gateway9527

pom.xml

<?xml version="1.0" encoding="UTF-8"?><project xmlns="/POM/4.0.0"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd"><parent><artifactId>cloud</artifactId><groupId>com.atguigu.springcloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloud-gateway-gateway9527</artifactId><dependencies><!--gateway--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!--eureka-client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!-- 引入自己定义的api通用包,可以使用Payment支付Entity --><dependency><groupId>com.atguigu.springcloud</groupId><artifactId>cloud-api-commons</artifactId><version>${project.version}</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></project>

application.yml

server:port: 9527spring:application:name: cloud-gatewayeureka:instance:hostname: cloud-gateway-serviceclient: #服务提供者provider注册进eureka服务列表内service-url:register-with-eureka: truefetch-registry: truedefaultZone: :7001/eureka

基础包

com.atguigu.springcloud

主启动类GateWayMain9527

package com.atguigu.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.flix.eureka.EnableEurekaClient;/*** @Author: Daisen.Z* @Date: /12/28 16:26* @Version: 1.0* @Description:*/@SpringBootApplication@EnableEurekaClientpublic class GateWayMain9527 {public static void main(String[] args) {SpringApplication.run(GateWayMain9527.class,args);}}

2. 配置路由

修改Gateway9527模块配置文件,配置路由

server:port: 9527spring:application:name: cloud-gatewaycloud: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/** # 断言,路径相匹配的进行路由- id: payment_routh2 #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名uri: http://localhost:8001#匹配后提供服务的路由地址#uri: lb://cloud-payment-service #匹配后提供服务的路由地址predicates:- Path=/payment/lb/** # 断言,路径相匹配的进行路由#- After=-02-21T15:51:37.485+08:00[Asia/Shanghai]#- Cookie=username,zzyy#- Header=X-Request-Id, \d+ # 请求头要有X-Request-Id属性并且值为整数的正则表达式eureka:instance:hostname: cloud-gateway-serviceclient: #服务提供者provider注册进eureka服务列表内service-url:register-with-eureka: truefetch-registry: truedefaultZone: :7001/eureka

3. 启动测试

为了方便测试,把服务注册中心7001改成单节单的

defaultZone: :7001/eureka/

启动7001、8001和9527模块

访问注册中心,查看已注册的服务

http://localhost:7001/

8001和GateWay都注册上来了

接下来,我们访问8001的get接口

http://localhost:8001/payment/get/1

能够成功访问

接着,我们通过路由网关进行访问

http://localhost:9527/payment/get/1

哎!也能够进行访问,这说明路由已经生效了。

网关的作用也体现出来了,我们渐渐的不需要暴露服务的真实端口,而是通过统一的网关进行访问。

五、GateWay的两种配置方式

GateWay有两种配置方式,其1是上述的yml配置文件配置

第二种是通过代码中注入RouteLocator的Bean来实现,接下来我们对第二种方式做下讲解

我们自己用第二种方式写一个路由,然后实现转发到baidu

1. 新建配置类

给GateWay9527新建配置类

package com.atguigu.springcloud.config;import org.springframework.cloud.gateway.route.RouteLocator;import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.ponent;/*** @Author: Daisen.Z* @Date: /12/28 17:07* @Version: 1.0* @Description:*/@Configurationpublic class GateWayConfig {/*** 配置了一个id为route-name的路由规则,* 当访问地址 http://localhost:9527/guonei时会自动转发到地址:/guonei*/@Beanpublic RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();// path后跟的是访问9527的地址,uri后跟的是转发的地址routes.route("path_route_atguigu",r -> r.path("/guonei").uri("/guonei")).build();return routes.build();}}

2. 启动测试

重启GateWay9527工程

访问

http://localhost:9527/guonei

会发现会被转发到百度新闻,证明我们的配置生效。

六、GateWay动态路由

为了能动态的支持扩容及负载均衡,我们不能将GateWay配置的路由URI写死,而是应该以服务名去调用。

默认情况下Gateway会根据注册中心注册的服务列表,

以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能。

1. 修改9527配置文件

server:port: 9527spring:application:name: cloud-gatewaycloud: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/** # 断言,路径相匹配的进行路由- id: payment_routh2 #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名#uri: http://localhost:8001#匹配后提供服务的路由地址uri: lb://cloud-payment-service #匹配后提供服务的路由地址predicates:- Path=/payment/lb/** # 断言,路径相匹配的进行路由#- After=-02-21T15:51:37.485+08:00[Asia/Shanghai]#- Cookie=username,zzyy#- Header=X-Request-Id, \d+ # 请求头要有X-Request-Id属性并且值为整数的正则表达式eureka:instance:hostname: cloud-gateway-serviceclient: #服务提供者provider注册进eureka服务列表内service-url:register-with-eureka: truefetch-registry: truedefaultZone: :7001/eureka

2. 启动测试

将8002工程也改成只注册到单节单7001注册中心,后边的删掉

重新启动7001、9527、8001和8002工程

访问9527的路由接口

http://localhost:9527/payment/get/1

多次刷新,会发现访问的端口在8001和8002间切换,动态路由配置成功。

七、GateWay的Predicate断言

我们之前加的已经有一种断言

他代表的意思是对路径的断言,匹配到,就进行转发,GateWay还支持了其他多种方式的断言,来提高我们的匹配准确度(可以理解为and条件)。

我们查看官网第4条关于断言的配置,看都支持哪些

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#the-before-route-predicate-factory

常用的断言:

Path Route Predicate: 路径匹配After Route Predicate: 在某个时间之后的请求才开始匹配,之前的就算匹配上了也不会转发

与之相同的还有Before、Between

- After=-02-05T15:10:03.685+08:00[Asia/Shanghai]

时间格式如果获得(主要是获取末尾中括号里面的时区)?

public static void main(String[] args) {ZonedDateTime now = ZonedDateTime.now();System.out.println(now);}

修改完之后可以自行测试,看是否某个时间之后才能访问

3. Cookie Route Predicate: 带某个Cookie才能访问,前边是Cookie的name,后边是正则匹配值

- Cookie=username,zzyy

测试:

给我们的8001和8002的controller加上lb接口

@GetMapping(value = "/payment/lb")public String getPaymentLB(){return serverPort;}

启动7001,8001,8002,9527工程,使用curl进行测试(curl类似于postman的命令行模式,使用postman也可)

curl下载地址

链接:/s/1ExwK5IyvKqAzknnsQY5Qgg 提取码:7jjj

在curl的解压目录下调出cmd窗口,访问接口,注意这时没有带cookie

curl http://localhost:9527/payment/lb

访问不成功

接下来我们携带上cookie,再访问一次

curl http://localhost:9527/payment/lb --cookie "username=zzyy"

哎,访问就通过了,66的

4. Header Route Predicate: 带有某个header才能访问,前边是属性名称,后边是一个正则表达式

- Header=X-Request-Id, \d+ # 请求头要有X-Request-Id属性并且值为整数的正则表达式

重启测试

curl http://localhost:9527/payment/lb -H "X-Request-Id:123"

能够成功访问

改成负数试一下

curl http://localhost:9527/payment/lb -H "X-Request-Id:-123"

会发现访问不通过,接口已经猩猩的兄弟废废了

Host Route Predicate:带某个Host才能访问Method Route Predicate:使用某种请求方法才能访问。如Get,PostQuery Route Predicate: 要有某个参数,并且符合正则才能访问

具体的配置信息请查看官网:

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#the-before-route-predicate-factory

说白了,Predicate就是为了实现一组匹配规则,

让请求过来找到对应的Route进行处理。

八、GateWay的Filter过滤器

1. 是个啥

路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用。Spring Cloud Gateway 内置了多种路由过滤器,他们都由GatewayFilter的工厂类来产生。

2. 周期

分为前置和后置,就是请求前过滤和请求后过滤

3. 种类-局部的

官网上给出的有几十种,感兴趣可以自己查看,使用起来很简单,和断言类似,可以自行上官网上查看。

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

4. 种类-全局的

全局的也有八九种,使用的方式和断言类似,可以自行上官网上查看。

5. 自定义过滤器(重点)

自定义过滤器(重点)

主要是自定义一个过滤器,实现两个接口implements GlobalFilter,Ordered

类,有注释,自己看一下就能懂

package com.atguigu.springcloud.filter;import lombok.extern.slf4j.Slf4j;import org.springframework.cloud.gateway.filter.GatewayFilterChain;import org.springframework.cloud.gateway.filter.GlobalFilter;import org.springframework.core.Ordered;import org.springframework.http.HttpStatus;import org.ponent;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;import java.util.Date;/*** @Author: Daisen.Z* @Date: /12/31 17:50* @Version: 1.0* @Description:*/@Component@Slf4jpublic class MyLogGatewayFilter implements GlobalFilter, Ordered {// 拦截查询条件不带uname的请求@Overridepublic 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,非法用户 ");// 不通过就给一个有好的提示,这里演示给个状态码exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);return exchange.getResponse().setComplete();}// 没有被拦截就放行return chain.filter(exchange);}// 加载过滤器的顺序,顺序越小优先级越高@Overridepublic int getOrder() {return 0;}}

注意:之前的配置文件要改一下

启动8001,8002,7001,9527工程进行测试

访问

http://localhost:9527/payment/lb?uname=zs

正常

访问不带uname的:

http://localhost:9527/payment/lb


总结

GateWay官网https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/。GateWay的目标是提供统一的路由方式,且基于Filter链的方式提供了网关的基本功能,例如:安全、监控/指标、限流。说白了,Predicate就是为了实现一组匹配规则,让请求过来找到对应的Route进行处理,而Filter就是过滤器,可以在请求接口执行前或请求接口返回后做一些操作如记录入局日志等。网关作为统一入口来匹配不同的请求进行转发,方便接口的统一控制。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。