微服务之服务网关Gateway
B站尚硅谷P65~P73
代码Gitee地址
以上次博客的eureka集群作为注册中心来演示。
由于Zuul已经称为过去式且Zuul2前景未知,因此使用新一代服务网关GateWay已经成为主流。
1. GateWay
1.1 概述
Gateway是在Spring生态系统之上构建的API网关服务,基于Spring5,SpringBoot2和Project Reactor等技术。
Gateway旨在提供一种简单而有效的方式来对API进行路由,目标是代替Zuul。为了提升网关的性能,Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能Reactor模式通信框架Netty。
Gateway的目标提供统一路由方式且基于Filter链的方式提供了网关基本的功能,安全、监控/指标、限流等。
Gateway是基于异步非阻塞模型上开发的,性能比较高。
功能:
- 反向代理;
- 鉴权;
- 流量控制;
- 熔断;
- 日志监控。
处于项目位置
特性:
- 动态路由:能够匹配任何请求属性;
- 可以对路由指定
Predicate
(断言)和Filter
(过滤器); - 集成
Hystrix
的断路器功能; - 集成
Spring Cloud
的服务发现功能; - 易于编写
Predicate
和Filter
; - 请求限流功能;
- 支持路径重写。
zuul模型:Zuul是基于servlet之上的一个阻塞式处理模型,当请求进入
Servlet Container
时,会为当前请求绑定一个线程,在并发不高的场景下这种模型是适用的。但是一旦高并发,线程数就会上升,而线程资源的代价是昂贵的,严重影响请求的处理时间,在一些简单的业务场景下,不希望为每个请求分配一个线程,只需要一个或者几个线程就能应对极大的并发请求,这种业务场景下servlet
模型没有优势。
gateway模型:在
servlet3.1
之后有了异步非阻塞的支持,而WebFlux是一个典型的非阻塞异步的框架,它的核心是基于Reactor的相关API实现的。相对于传统的web框架来说,它可以运行在诸如netty,undertow及支持servlet3.1的容器上。非阻塞式+函数式编程。
1.2 核心概念
- Router(路由):是构建网关的基本模块,由ID和目标URI和一系列的断言和过滤器组成,如果断言为true则匹配该路由。
- Predicate(断言):可以匹配Http请求中的所有内容,如果请求与断言相匹配则进行路由。
- Filter(过滤):使用过滤器,可以在路由被请求前或者请求后对请求进行修改。
根据web请求和匹配条件,定位到真正的服务节点。并在这个转发过程的前后,进行一些精细化控制。即根据predicate的匹配条件,通过过滤器,再加上uri来实现具体的路由。
1.3 工作流程
- 客户端向Spring Cloud Gateway发出请求;
- 然后再Gateway Handler Mapping中找到与请求相匹配的路由;
- 将其发送到Gateway Web Handler;
- Handler再通过指定的过滤器链来将请求发送到实际业务执行逻辑中,返回。
- 请求前过滤器(pre):参数校验、权限校验、流量监控、日志输出、协议转换。
- 请求后过滤器(post):响应内容和响应头修改,日志输出,流量监控等。
1.4 微服务项目搭建
新建moudle:
cloud-gateway-gateway9527
;依赖:
<dependencies><dependency><groupId>org.example</groupId><artifactId>cloud-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></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>
配置文件:
server:port: 9527spring:application:name: cloud-gatewayeureka:instance:hostname: cloud-gateway-serviceclient:service-url:register-with-eureka: truefetch-registry: truedefaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
主启动类:
@EnableEurekaClient @SpringBootApplication public class GatewayMain9527 {public static void main(String[] args) {SpringApplication.run(GatewayMain9527.class,args);} }
1.5 路由配置详情
1.5.1 yml配置文件
- 配置路由,避免暴露8001端口,将8001端口路由到当前网关微服务:
spring:application:name: cloud-gatewaycloud:gateway:discovery:locator:enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由routes: # 配置路由- id: payment_routh #路由的ID,没有固定规则但要求唯一,建议配合服务名uri: http://localhost:8001 #匹配后提供服务的路由地址predicates:- Path=/payment/** # 断言,路径相匹配的进行路由- id: payment_routh2 uri: http://localhost:8001 predicates:- Path=/payment/lb/**
- 访问
9527
测试:
1.5.2 代码中注入RouteLocator的Bean
模拟案例:使用网关
9527
访问外网:CSDN个人主页新建配置类:
@Configuration public class GatewayConfig {@Beanpublic RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){// 路由集合:类似于配置文件的 routes:RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();// 指定路由唯一id 和 映射地址path 和 实际地址uriroutes.route("path_route_bli",r -> r.path("/weixin_44289860").uri("http://blog.csdn.net/")).build();return routes.build();}}
访问测试:输入
http://localhost:9527/weixin_44289860
,直接跳转到我的个人主页。
1.6 动态路由
按照先前针对路由的配置,无法实现负载均衡,仅仅只能访问一个端口。
这样就需要针对网关再来实现负载均衡的功能,比较繁琐;
可以通过微服务名来实现动态路由。
修改配置文件:
server:port: 9527spring:application:name: cloud-gatewaycloud:gateway:discovery:locator:enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由routes: # 配置路由- id: payment_routh #路由的ID,没有固定规则但要求唯一,建议配合服务名 # uri: http://localhost:8001 #匹配后提供服务的路由地址uri: lb://cloud-payment-service #匹配后根据微服务名称提供服务的路由地址predicates:- Path=/payment/** # 断言,路径相匹配的进行路由 eureka:instance:hostname: cloud-gateway-serviceclient:service-url:register-with-eureka: truefetch-registry: truedefaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
请求测试:可以看到实现了负载均衡。
1.7 Predicate(断言)
- 断言分类:
After
:在某时间之后才能访问;Before
:在某时间之前才能访问;Between
:在某时间之间才能访问;Cookie
:验证Cookie中保存的信息Header
:检查Header中是否包含了响应的属性Method
:请求类型;Path
:即指定当前网关的路径与实际路径的映射。Query
:判断QueryPrameters
列表是否存在指定值;
spring:application:name: cloud-gatewaycloud:gateway:discovery:locator:enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由routes: # 配置路由- id: payment_routh #路由的ID,没有固定规则但要求唯一,建议配合服务名
# uri: http://localhost:8001 #匹配后提供服务的路由地址uri: lb://cloud-payment-service #匹配后根据微服务名称提供服务的路由地址predicates:- Path=/payment/** # 断言,路径相匹配的进行路由- After=2022-06-12T20:59:34.102+08:00[Asia/Shanghai]- Before=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]- Between=2020-03-08T10:59:34.102+08:00[Asia/Shanghai] , 2020-03-08T10:59:34.102+08:00[Asia/Shanghai]- Cookie=username,zzyy #
1.8 Filter(过滤器)
允许进入Http请求和返回Http响应之间来进行一系列操作(修改)。
生命周期
- pre:请求前过滤;
- post:请求后过滤。
种类:
GatewayFilter
:针对某个请求的过滤器;GlobalFitler
:全局过滤器。
配置单一过滤器:
spring:application:name: cloud-gatewaycloud:gateway:discovery:locator:enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由routes: # 配置路由- id: payment_routh #路由的ID,没有固定规则但要求唯一,建议配合服务名
# uri: http://localhost:8001 #匹配后提供服务的路由地址uri: lb://cloud-payment-service #匹配后根据微服务名称提供服务的路由地址predicates: # 配置断言- Path=/payment/** # 断言,路径相匹配的进行路由- After=2022-06-12T20:59:34.102+08:00[Asia/Shanghai]- Before=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]- Between=2020-03-08T10:59:34.102+08:00[Asia/Shanghai] , 2020-03-08T10:59:34.102+08:00[Asia/Shanghai]- Cookie=username,zzyy #filters: # 配置过滤器- AddRequestHeader=test,aa #在请求头上添加:key:test,value:aa
自定义全局过滤器:继承
implements GlobalFilter, Ordered
接口。@Slf4j @Component public class MyLogGatewayFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info("进入自定义全局过滤器:MyLogGatewayFilter");// 获取请求参数String uname = exchange.getRequest().getQueryParams().getFirst("uname");if (Objects.isNull(uname)){log.error("非法用户");// 返回响应信息exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);// 退出return exchange.getResponse().setComplete();}// 携带exchange放行去下一个过滤器return chain.filter(exchange);}/*** 指定加载过滤器的顺序,数字越小,优先级越高。* @return*/@Overridepublic int getOrder() {return 0;} }
微服务之服务网关Gateway相关推荐
- 微服务学习之网关(Gateway)的搭建及使用
微服务系列 1.Nacus 服务搭建及使用 2.Nacos 配置中心 3.Nacos 服务注册与发现之OpenFeign服务间调用 4.Spring Security & Oauth2 认证授 ...
- 【微服务】—— 统一网关Gateway
文章目录 1. 概述 1.1 为什么需要网关 1.2 SpringCloud Gateway 2. gateway快速入门 搭建网关服务 1.创建新的module,引入SpringCloudGatew ...
- SpringCloud 微服务网关Gateway 动态路由配置
概述:在上一章节<SpringCloud 微服务网关Gateway介绍及简单路由配置>中我们讲述了Gateway的最简单的路由配置方式.但是其中比较明显的问题就是我们在配置路由服务的地址时 ...
- SpringCloud 微服务网关Gateway介绍及简单路由配置
概述:什么是微服务网关?为了解决用户客户端在调用微服务系统中的多个消费者工程接口时,需要维护非常多的消费者应用接口地址等信息,以及可能存在不同应用见的调用跨域等问题,微服务网关组件随即出现.网关作为用 ...
- gateway动态路由_微服务中的网关技术:Gateway
技术/杨33 一.Gateway是什么 为微服务提供一种简单有效的统一的API路由管理方式. Gateway是基于WebFlux框架实现的,而WebFlux框架底层使用了高性能的Reactor模式通讯 ...
- 【微服务技术09】统一网关Gateway
[微服务技术09]统一网关Gateway 案例代码:https://gitee.com/pikachu2333/spring-cloud-hexuan 1.网关作用 网关功能: 身份认证和权限校验 服 ...
- 微服务_服务网关(Gateway)
目录 一.为什么需要网关 二.SpringCloud网关的实现方式 三.Gateway实践 1)创建gateway服务,引入依赖 2)编写启动类 3)编写基础配置和路由规则 4)重启测试 5)网关路由 ...
- 【云原生微服务>SCG网关篇十二】Spring Cloud Gateway集成Sentinel API实现多种限流方式
文章目录 一.前言 二.Gateway集成Sentinel API 0.集成Sentinel的核心概念 1)GatewayFlowRule 和 ApiDefinition 2)GatewayFlowR ...
- 基于go-micro微服务的实战-实现网关Gateway(三)
基于go-micro微服务的实战-实现网关Gateway(三) 文章最后附带完整代码 基于go-micro实现网关层 创建好网关层目录 common: 公告模块,配置初始化等 conf: 配置文件 h ...
- Spring Cloud之(十八)微服务网关GateWay
十八.微服务网关GateWay Zuul 1.x 是一个基于阻塞 IO 的 API Gateway 以及 Servlet:直到 2018 年 5 月,Zuul 2.x(基于Netty,也是非阻塞的,支 ...
最新文章
- java9-6 内部类
- MVC 支持同名路由,不同命名空间
- select into from 与 insert into select 区别鉴赏
- grep 正则匹配
- 微软企业库连接access,web.config相对路径配置
- eclispe Springboot项目修改html,jsp 页面不能及时刷新
- 查看局域网内所有ip 和 mac
- svn里的branch、trunk、tag的用处
- 用gambit学博弈论--完全信息动态博弈-扩展式表述的博弈的纳什均衡
- JS Grid插件使用
- IOS 如何让你的应用快速兼容iPhone5
- php打印直角三角形,中考几何丨通过构造直角三角形斜边上的中线结合中位线解决问题!...
- 透明网桥(transparent bridge)
- 崩溃日志保存本地log,服务器上传
- 计算机31进制表,74ls290构成31进制计数器电路图文详解
- 小盒即时通讯IM-全套开源-开箱即用
- 初学Python画五角星
- MySQL——MySQL备份
- linux中获取系统时间的几种方法
- RDD论文翻译:基于内存的集群计算容错抽象
热门文章
- 数据湖、物联网等--南水北调中线工程的“智慧大脑”,是如何工作的?
- 游戏角色命名与游戏风格
- excel随机数_办公软件操作技巧052:如何在excel中填充随机数
- 使用easypoi导出excel设置表头样式
- linux怎么安装pcie串口卡驱动,pci串口卡驱动是什么接口 pci串口卡驱动安装方法...
- android 陀螺仪滤波_高精度MEMS陀螺仪的滤波算法研究
- mysql全量备份命令_mysql全量备份与增量备份
- python 经典图书排行榜_书榜 | 计算机书籍(9.2-9.8)销售排行榜
- 服务器多开安卓系统,安卓云服务器能多开吗
- 西南大学计算机试题答案,17秋西南大学计算机组成原理【0013】机考答案