- 成立时间
- 1985年
- 公司名称
- 捷威
- 总部地点
- 美国南加利福尼亚州
- 公司类型
- 股份公司
- 外文名称
- Gateway
- 经营范围
- IT产品
-
Gateway
2020-03-04 18:14:58Gateway核心概念 Gateway入门和实战 网关统一限流 网关服务核心业务功能剖析 ------------------------------------- Gateway核心概念 一:什么是SpringCloud gateWay Spring Cloud Gateway是Spring Cloud...目录:
Gateway 核心概念
Gateway 入门和实战
网关统一限流(下次补)
网关服务核心业务功能剖析(下次补)
-------------------------------------
Gateway 核心概念
一:什么是SpringCloud gateWaySpring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,取代Zuul网关。网关作为流量的,在微服务系统中有着非常作用。据说性能是第一代网关zuul的1.5倍。(基于Netty,WebFlux),注意点:由于不是Sevlet容器,所以他不能打成war包, 只支持SpringBoot2.X不支持1.x1.1)网关作用:网关常见的功能有路由转发、权限校验、限流控制等作用。Gateway 入门和实战
1.加入Maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐starter‐gateway</artifactId>
</dependency>
<!‐‐加入nacos的依赖‐‐>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring‐cloud‐alibaba‐nacos‐discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐actuator</artifactId>
</dependency>2.相关配置
#规划GateWay的服务端口
server:
port: 8888
#规划gateWay注册到到nacos上的服务应用名称
spring:
application:
name: api‐gateway
cloud:
nacos:
discovery:
#gateway工程注册到nacos上的地址
server‐addr: localhost:8848
gateway:
discovery:
locator:
#开启gateway从nacos上获取服务列表
enabled: true
#开启acutor端点
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
#打开端点详情
show‐details: always3.启动程序
@SpringBootApplication
@SpringBootApplication @EnableDiscoveryClient public class Tulingvip08MsCloudGatewayApplication { public static void main(String[] args) { SpringApplication.run(Tulingvip08MsCloudGatewayApplication.class, args); } }
-
SpringCloud之服务网关Gateway
2019-06-30 22:02:38Spring Cloud Gateway 是 Spring Cloud 新推出的网关框架,之前是Netflix Zuul。网关通常在项目中为了简化 前端的调用逻辑,同时也简化内部服务之间互相调用的复杂度;具体作用就是转发服务,接收并转发所有内外 ...前言
SpringCloud 是微服务中的翘楚,最佳的落地方案。
Spring Cloud Gateway 是 Spring Cloud 新推出的网关框架,之前是 Netflix Zuul。网关通常在项目中为了简化
前端的调用逻辑,同时也简化内部服务之间互相调用的复杂度;具体作用就是转发服务,接收并转发所有内外
部的客户端调用;其他常见的功能还有权限认证,限流控制等等。
本博客会提到网关的基本转发功能,熔断功能,限流功能以及功能的综合使用。
源码
GitHub地址:https://github.com/intomylife/SpringCloud
环境
- JDK 1.8.0 +
- Maven 3.0 +
- SpringBoot 2.0.3
- SpringCloud Finchley.RELEASE
- Redis 3.0 +
开发工具
- IntelliJ IDEA
正文
commons 工程
commons 工程 - POM 文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!-- 三坐标 --> <groupId>com.zwc</groupId> <artifactId>springcloud-gateway-commons</artifactId> <version>1.0</version> <!-- 工程名称和描述 --> <name>springcloud-gateway-commons</name> <description>公用工程</description> <!-- 打包方式 --> <packaging>jar</packaging> <!-- 在 properties 下声明相应的版本信息,然后在 dependency 下引用的时候用 ${} 就可以引入该版本 jar 包了 --> <properties> <!-- 编码 --> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- jdk --> <java.version>1.8</java.version> <!-- SpringBoot --> <platform-bom.version>Cairo-SR3</platform-bom.version> <!-- SpringCloud --> <spring-cloud-dependencies.version>Finchley.RELEASE</spring-cloud-dependencies.version> </properties> <!-- 加入依赖 --> <dependencies> </dependencies> <!-- 依赖 jar 包版本管理的管理器 --> <!-- 如果 dependencies 里的 dependency 自己没有声明 version 元素,那么 maven 就此处来找版本声明。 --> <!-- 如果有,就会继承它;如果没有就会报错,告诉你没有版本信息 --> <!-- 优先级:如果 dependencies 里的 dependency 已经声明了版本信息,就不会生效此处的版本信息了 --> <dependencyManagement> <dependencies> <!-- SpringBoot --> <dependency> <groupId>io.spring.platform</groupId> <artifactId>platform-bom</artifactId> <version>${platform-bom.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- SpringCloud --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud-dependencies.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!-- 插件依赖 --> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
- 配置一些共用依赖
commons 工程 - 项目结构
service 工程
① 此工程下有四个模块:一个注册中心,一个网关以及两个提供者
② 两个提供者除端口不一致以外,其他代码基本一致
registry-service(注册中心)
registry-service - POM 文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!-- 继承父 --> <parent> <groupId>com.zwc</groupId> <artifactId>springcloud-gateway-service</artifactId> <version>1.0</version> </parent> <!-- 三坐标 --> <groupId>com.zwc</groupId> <artifactId>springcloud-gateway-registry-service</artifactId> <version>1.0</version> <!-- 工程名称描述 --> <name>springcloud-gateway-registry-service</name> <description>注册中心</description> <!-- 打包方式 --> <packaging>jar</packaging> <!-- 在 properties下声明相应的版本信息,然后在dependency下引用的时候用 ${} 就可以引入该版本jar包了 --> <properties> </properties> <!-- 加入依赖 --> <dependencies> <!-- 服务注册中心 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies> <!-- 插件依赖 --> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
- 主要加入 spring-cloud-starter-netflix-eureka-server 依赖
registry-service - application.yml 配置文件
# 端口 server: port: 8761 # 应用名称 spring: application: name: eureka-server eureka: instance: # 使用 ip 代替实例名 prefer-ip-address: true # 实例的主机名 hostname: ${spring.cloud.client.ip-address} # 实例的 ID 规则 instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} client: # 是否向注册中心注册自己 registerWithEureka: false # 是否向注册中心获取注册信息 fetchRegistry: false serviceUrl: # 注册中心地址 defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
- 这里使用了默认的 8761 端口,当然也可以更改,不过在发现调用服务端的注册中心地址端口要与它一致
registry-service - 启动类
package com.zwc; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer public class SpringcloudGatewayRegistryServiceApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudGatewayRegistryServiceApplication.class, args); } }
- 在启动类中添加 @EnableEurekaServer 注解表示此工程是注册中心
registry-service - 启动项目
1. 项目启动成功后访问 http://localhost:8761/ 即可看到 eureka-server 主页面
注:由于服务工程 A 和服务工程 B 除端口不一致以外,其他代码基本一致,所以服务工程 B 不再赘述
a-service(服务工程 A)
a-service - POM 文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!-- 继承父 --> <parent> <groupId>com.zwc</groupId> <artifactId>springcloud-gateway-a-service</artifactId> <version>1.0</version> </parent> <!-- 三坐标 --> <groupId>com.zwc</groupId> <artifactId>springcloud-gateway-a-service-core</artifactId> <version>1.0</version> <!-- 工程名称描述 --> <name>springcloud-gateway-a-service-core</name> <description>服务工程 - A 核心</description> <!-- 打包方式 --> <packaging>jar</packaging> <!-- 在 properties下声明相应的版本信息,然后在dependency下引用的时候用 ${} 就可以引入该版本jar包了 --> <properties> </properties> <!-- 加入依赖 --> <dependencies> <!-- commons工程 依赖 --> <dependency> <groupId>com.zwc</groupId> <artifactId>springcloud-gateway-commons</artifactId> <version>1.0</version> </dependency> <!-- api工程 依赖 --> <dependency> <groupId>com.zwc</groupId> <artifactId>springcloud-gateway-a-service-api</artifactId> <version>1.0</version> </dependency> <!-- springboot web 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 提供者消费者 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies> <!-- 插件依赖 --> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
- 加入 spring-cloud-starter-netflix-eureka-client 依赖
a-service - application.yml 配置文件
# 端口 server: port: 9000 # 应用名称 spring: application: name: gateway-service eureka: instance: # 使用 ip 代替实例名 prefer-ip-address: true # 实例的主机名 hostname: ${spring.cloud.client.ip-address} # 实例的 ID 规则 instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} client: serviceUrl: # 注册中心地址 defaultZone: http://${eureka.instance.hostname}:8761/eureka/
- 注意此处配置注册中心地址的端口为 8761 也就是上面注册中心工程配置的端口
a-service - controller 前端控制器(提供服务)
package com.zwc.a.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /* * @ClassName ASayHelloController * @Desc TODO Say Hello * @Date 2019/5/20 23:24 * @Version 1.0 */ @RestController public class ASayHelloController { /* * @ClassName ASayHelloController * @Desc TODO 读取配置文件中的端口 * @Date 2019/5/20 23:24 * @Version 1.0 */ @Value("${server.port}") private String port; /* * @ClassName ASayHelloController * @Desc TODO Say Hello * @Date 2019/5/20 23:24 * @Version 1.0 */ @RequestMapping("/hello") public String hello(){ return "Hello!I'm a. port:" + port; } /* * @ClassName ASayHelloController * @Desc TODO 接收从网关传入的参数 * @Date 2019/6/23 16:28 * @Version 1.0 */ @RequestMapping("/name") public String name(String name){ return "My name is " + name + ". aaa"; } /* * @ClassName ASayHelloController * @Desc TODO 接收从网关传入的参数 * @Date 2019/6/23 16:52 * @Version 1.0 */ @RequestMapping("/age") public String age(String age){ return "I am " + age + " years old this year. aaa"; } /* * @ClassName ASayHelloController * @Desc TODO 接收从网关传入的参数 * @Date 2019/6/29 22:00 * @Version 1.0 */ @RequestMapping("/routeAll") public String routeAll(String pass) { return "Can I pass? " + pass + "! port:" + port; } }
- 提供输出字符串服务,供网关调用
a-service - 启动类
package com.zwc; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication @EnableEurekaClient public class SpringcloudGatewayAServiceCoreApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudGatewayAServiceCoreApplication.class, args); } }
- 添加 @EnableEurekaClient 注解表示此工程可以向注册中心提供服务
a-service - 启动项目
1. 刷新 http://localhost:8761/(注册中心)可以看到服务已经被注册进来了
2. 项目启动成功后访问:http://localhost:9000/hello
3. 输出内容:'Hello!I'm a. port:9000'
4. 同样启动服务工程 B后,刷新 http://localhost:8761/(注册中心)
5. 项目启动成功后访问:http://localhost:9001/hello
6. 输出内容:'Hello!I'm b. port:9001'
7. 其他接口是下面网关服务启动后转发调用的,也是本博客的重头戏
master-service(网关)
master-service - POM 文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!-- 继承父 --> <parent> <groupId>com.zwc</groupId> <artifactId>springcloud-gateway-service</artifactId> <version>1.0</version> </parent> <!-- 三坐标 --> <groupId>com.zwc</groupId> <artifactId>springcloud-gateway-master-service</artifactId> <version>1.0</version> <!-- 工程名称描述 --> <name>springcloud-gateway-master-service</name> <description>Spring Cloud Gateway 服务网关</description> <!-- 打包方式 --> <packaging>jar</packaging> <!-- 在 properties下声明相应的版本信息,然后在 dependency 下引用的时候用 ${} 就可以引入该版本 jar 包了 --> <properties> <!-- ali json --> <fastjson.version>1.2.47</fastjson.version> </properties> <!-- 加入依赖 --> <dependencies> <!-- 提供者消费者 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- gateway --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis-reactive</artifactId> </dependency> <!-- hystrix --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <!-- ali json依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> </dependencies> <!-- 插件依赖 --> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
- 加入 spring-cloud-starter-netflix-eureka-client 依赖:提供和注册服务
- 加入 spring-cloud-starter-gateway 依赖:gateway
- 加入 spring-boot-starter-data-redis-reactive 依赖:结合 Redis 限流
- 加入 spring-cloud-starter-netflix-hystrix 依赖:熔断器
master-service - application.yml 配置文件
# 端口 server: port: 8000 spring: profiles: # 指定配置 # route_simple:简单尝试 # route_stripPrefix:截取请求 # route_uri:转发指定地址并传入参数 # route_addRequestParameter:转发指定服务并传入参数 # route_hystrix:熔断 # route_requestRateLimiter:限流 # route_all:综合 active: route_simple --- spring: # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。 ## 简单尝试 profiles: route_simple application: # 应用名称 name: gateway-master cloud: gateway: discovery: locator: # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务 enabled: true # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。) routes: # 路由标识(id:标识,具有唯一性) 简单尝试 - id: route_simple # 目标服务地址(uri:地址,请求转发后的地址) uri: https://www.zouwencong.com # 路由条件(predicates:断言,匹配 HTTP 请求内容) predicates: ## 转发地址格式为 uri/archive - Path=/archive eureka: instance: # 使用 ip 代替实例名 prefer-ip-address: true # 实例的主机名 hostname: ${spring.cloud.client.ip-address} # 实例的 ID 规则 instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} client: serviceUrl: # 注册中心地址 defaultZone: http://${eureka.instance.hostname}:8761/eureka/ logging: level: # log 级别 org.springframework.cloud.gateway: debug --- spring: # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。 ## 截取请求 profiles: route_stripPrefix application: # 应用名称 name: gateway-master cloud: gateway: discovery: locator: # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务 enabled: true # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。) routes: # 路由标识(id:标识,具有唯一性) 截取请求 - id: route_simple # 目标服务地址(uri:地址,请求转发后的地址) uri: https://www.zouwencong.com # 路由条件(predicates:断言,匹配 HTTP 请求内容) predicates: ## 转发地址格式为 uri/archive,/str 部分会被下面的过滤器给截取掉 - Path=/str/archive filters: ## 截取路径位数 - StripPrefix=1 eureka: instance: # 使用 ip 代替实例名 prefer-ip-address: true # 实例的主机名 hostname: ${spring.cloud.client.ip-address} # 实例的 ID 规则 instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} client: serviceUrl: # 注册中心地址 defaultZone: http://${eureka.instance.hostname}:8761/eureka/ logging: level: # log 级别 org.springframework.cloud.gateway: debug --- spring: # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。 ## 转发指定地址并传入参数 profiles: route_uri application: # 应用名称 name: gateway-master cloud: gateway: discovery: locator: # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务 enabled: true # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。) routes: # 路由标识(id:标识,具有唯一性) 转发指定地址并传入参数 - id: route_uri # 目标服务地址(uri:地址,请求转发后的地址) uri: http://localhost:9000 # 路由条件(predicates:断言,匹配 HTTP 请求内容) predicates: ## 匹配 GET 请求 - Method=GET # 过滤器(filters:过滤器,过滤规则) filters: ## 添加指定参数 - AddRequestParameter=name, zwc eureka: instance: # 使用 ip 代替实例名 prefer-ip-address: true # 实例的主机名 hostname: ${spring.cloud.client.ip-address} # 实例的 ID 规则 instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} client: serviceUrl: # 注册中心地址 defaultZone: http://${eureka.instance.hostname}:8761/eureka/ logging: level: # log 级别 org.springframework.cloud.gateway: debug --- spring: # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。 ## 转发指定服务并传入参数 profiles: route_addRequestParameter application: # 应用名称 name: gateway-master cloud: gateway: discovery: locator: # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务 enabled: true # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。) routes: # 路由标识(id:标识,具有唯一性) 转发指定服务并传入参数 - id: route_addRequestParameter # 目标服务地址(uri:地址,请求转发后的地址) uri: lb://gateway-service # 路由条件(predicates:断言,匹配 HTTP 请求内容) predicates: ## 匹配 GET 请求 - Method=GET # 过滤器(filters:过滤器,过滤规则) filters: ## 添加指定参数 - AddRequestParameter=age, three eureka: instance: # 使用 ip 代替实例名 prefer-ip-address: true # 实例的主机名 hostname: ${spring.cloud.client.ip-address} # 实例的 ID 规则 instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} client: serviceUrl: # 注册中心地址 defaultZone: http://${eureka.instance.hostname}:8761/eureka/ logging: level: # log 级别 org.springframework.cloud.gateway: debug --- spring: # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。 ## 熔断 profiles: route_hystrix application: # 应用名称 name: gateway-master cloud: gateway: discovery: locator: # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务 enabled: true # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。) routes: # 路由标识(id:标识,具有唯一性) 熔断 - id: route_hystrix # 目标服务地址(uri:地址,请求转发后的地址) uri: lb://gateway-service # 路由条件(predicates:断言,匹配 HTTP 请求内容) predicates: ## 匹配 GET 请求 - Method=GET # 过滤器(filters:过滤器,过滤规则) filters: ## 添加指定参数 - AddRequestParameter=age, three ## 熔断 - name: Hystrix args: name: fallbackcmd ### fallback 时调用的方法 http://localhost:8000/fallback fallbackUri: forward:/fallback eureka: instance: # 使用 ip 代替实例名 prefer-ip-address: true # 实例的主机名 hostname: ${spring.cloud.client.ip-address} # 实例的 ID 规则 instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} client: serviceUrl: # 注册中心地址 defaultZone: http://${eureka.instance.hostname}:8761/eureka/ logging: level: # log 级别 org.springframework.cloud.gateway: debug --- spring: # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。 ## 限流 profiles: route_requestRateLimiter redis: host: localhost port: 6379 database: 0 application: # 应用名称 name: gateway-master cloud: gateway: discovery: locator: # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务 enabled: true # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。) routes: # 路由标识(id:标识,具有唯一性) 限流 - id: route_requestRateLimiter # 目标服务地址(uri:地址,请求转发后的地址) uri: lb://gateway-service # 路由条件(predicates:断言,匹配 HTTP 请求内容) predicates: ## 匹配 GET 请求 - Method=GET # 过滤器(filters:过滤器,过滤规则) filters: ## 添加指定参数 - AddRequestParameter=age, three ## 限流 - name: RequestRateLimiter args: ### 限流过滤器的 Bean 名称 key-resolver: '#{@uriKeyResolver}' ### 希望允许用户每秒处理多少个请求 redis-rate-limiter.replenishRate: 1 ### 用户允许在一秒钟内完成的最大请求数 redis-rate-limiter.burstCapacity: 3 eureka: instance: # 使用 ip 代替实例名 prefer-ip-address: true # 实例的主机名 hostname: ${spring.cloud.client.ip-address} # 实例的 ID 规则 instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} client: serviceUrl: # 注册中心地址 defaultZone: http://${eureka.instance.hostname}:8761/eureka/ logging: level: # log 级别 org.springframework.cloud.gateway: debug --- spring: # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。 ## 综合 profiles: route_all redis: host: localhost port: 6379 database: 0 application: # 应用名称 name: gateway-master cloud: gateway: discovery: locator: # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务 enabled: true # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。) routes: # 路由标识(id:标识,具有唯一性) 综合 - id: route_all # 目标服务地址(uri:地址,请求转发后的地址) uri: lb://gateway-service # 路由条件(predicates:断言,匹配 HTTP 请求内容) predicates: ## 转发地址格式为 uri/routeAll,/all 部分会被下面的过滤器给截取掉 - Path=/all/routeAll ## 匹配 GET 请求 - Method=GET # 过滤器(filters:过滤器,过滤规则) filters: ## 截取路径位数 - StripPrefix=1 ## 添加指定参数 - AddRequestParameter=pass, yes ## 熔断 - name: Hystrix args: name: fallbackcmd ### fallback 时调用的方法 http://localhost:8000/fallback fallbackUri: forward:/fallback ## 限流 - name: RequestRateLimiter args: ### 限流过滤器的 Bean 名称 key-resolver: '#{@uriKeyResolver}' ### 希望允许用户每秒处理多少个请求 redis-rate-limiter.replenishRate: 1 ### 用户允许在一秒钟内完成的最大请求数 redis-rate-limiter.burstCapacity: 3 eureka: instance: # 使用 ip 代替实例名 prefer-ip-address: true # 实例的主机名 hostname: ${spring.cloud.client.ip-address} # 实例的 ID 规则 instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} client: serviceUrl: # 注册中心地址 defaultZone: http://${eureka.instance.hostname}:8761/eureka/ logging: level: # log 级别 org.springframework.cloud.gateway: debug
- 注意配置注册中心地址的端口都为 8761 也就是上面注册中心工程配置的端口
- 每一对 '---' 符号中的配置文件都是单独的,使用 spring.profiles.active 指定
- 每一对 '---' 符号中的配置文件都只配置了一个 route(路由)
- route(路由)由四部分组成,其中 filters 不是必须参数
- 唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)
master-service - 简单尝试
spring: # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。 ## 简单尝试 profiles: route_simple application: # 应用名称 name: gateway-master cloud: gateway: discovery: locator: # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务 enabled: true # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。) routes: # 路由标识(id:标识,具有唯一性) 简单尝试 - id: route_simple # 目标服务地址(uri:地址,请求转发后的地址) uri: https://www.zouwencong.com # 路由条件(predicates:断言,匹配 HTTP 请求内容) predicates: ## 转发地址格式为 uri/archive - Path=/archive
1. 停止注册中心工程(registry-service)、服务工程 A 和服务工程 B
2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改为 route_simple
3. 上面配置文件内容意思是当访问 http://localhost:8000/archive (网关地址/archive)
会被转发到 https://www.zouwencong.com/archive/ (uri/archive)
4. 启动注册中心工程(registry-service)和网关工程(master-service)
5. 项目启动成功后访问:http://localhost:8000/archive
6. 发现页面会自动被跳转到:https://www.zouwencong.com/archive/
7. 证明服务转发成功
master-service - 截取请求
spring: # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。 ## 截取请求 profiles: route_stripPrefix application: # 应用名称 name: gateway-master cloud: gateway: discovery: locator: # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务 enabled: true # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。) routes: # 路由标识(id:标识,具有唯一性) 截取请求 - id: route_simple # 目标服务地址(uri:地址,请求转发后的地址) uri: https://www.zouwencong.com # 路由条件(predicates:断言,匹配 HTTP 请求内容) predicates: ## 转发地址格式为 uri/archive,/str 部分会被下面的过滤器给截取掉 - Path=/str/archive filters: ## 截取路径位数 - StripPrefix=1 eureka: instance: # 使用 ip 代替实例名 prefer-ip-address: true # 实例的主机名 hostname: ${spring.cloud.client.ip-address} # 实例的 ID 规则 instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} client: serviceUrl: # 注册中心地址 defaultZone: http://${eureka.instance.hostname}:8761/eureka/ logging: level: # log 级别 org.springframework.cloud.gateway: debug
1. 停止注册中心工程(registry-service)和网关工程(master-service)
2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改为 route_stripPrefix
3. 上面配置文件内容意思是访问的路径 http://localhost:8000/str/archive (网关地址/str/archive)截取 /str 部分,
截取后被转发到 https://www.zouwencong.com/archive/ (uri/archive)
4. 启动注册中心工程(registry-service)和网关工程(master-service)
5. 项目启动成功后访问:http://localhost:8000/str/archive
6. 发现页面会自动被跳转到:https://www.zouwencong.com/archive/
7. 证明路径被截取并服务转发成功
master-service - 转发指定地址并传入参数
spring: # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。 ## 转发指定地址并传入参数 profiles: route_uri application: # 应用名称 name: gateway-master cloud: gateway: discovery: locator: # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务 enabled: true # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。) routes: # 路由标识(id:标识,具有唯一性) 转发指定地址并传入参数 - id: route_uri # 目标服务地址(uri:地址,请求转发后的地址) uri: http://localhost:9000 # 路由条件(predicates:断言,匹配 HTTP 请求内容) predicates: ## 匹配 GET 请求 - Method=GET # 过滤器(filters:过滤器,过滤规则) filters: ## 添加指定参数 - AddRequestParameter=name, zwc eureka: instance: # 使用 ip 代替实例名 prefer-ip-address: true # 实例的主机名 hostname: ${spring.cloud.client.ip-address} # 实例的 ID 规则 instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} client: serviceUrl: # 注册中心地址 defaultZone: http://${eureka.instance.hostname}:8761/eureka/ logging: level: # log 级别 org.springframework.cloud.gateway: debug
1. 停止注册中心工程(registry-service)和网关工程(master-service)
2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改为 route_uri
3. 上面配置文件内容意思是访问的路径 http://localhost:8000/name (网关地址/name)
会被转发到 http://localhost:9000/name(uri/name),并传入 'name=zwc' 参数(注意为 Get 请求)
4. 启动注册中心工程(registry-service),网关工程(master-service)和服务工程 A(a-service)
5. 项目启动成功后访问:http://localhost:8000/name
6. 输出内容:'My name is zwc. aaa'(通过网关转发 - 参数有值)
7. 打开新页面访问:http://localhost:9000/name
8. 输出内容:'My name is null. aaa'(直接访问 - 参数没有值)
9. 证明转发指定地址并传入参数成功
master-service - 转发指定服务并传入参数
spring: # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。 ## 转发指定服务并传入参数 profiles: route_addRequestParameter application: # 应用名称 name: gateway-master cloud: gateway: discovery: locator: # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务 enabled: true # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。) routes: # 路由标识(id:标识,具有唯一性) 转发指定服务并传入参数 - id: route_addRequestParameter # 目标服务地址(uri:地址,请求转发后的地址) uri: lb://gateway-service # 路由条件(predicates:断言,匹配 HTTP 请求内容) predicates: ## 匹配 GET 请求 - Method=GET # 过滤器(filters:过滤器,过滤规则) filters: ## 添加指定参数 - AddRequestParameter=age, three eureka: instance: # 使用 ip 代替实例名 prefer-ip-address: true # 实例的主机名 hostname: ${spring.cloud.client.ip-address} # 实例的 ID 规则 instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} client: serviceUrl: # 注册中心地址 defaultZone: http://${eureka.instance.hostname}:8761/eureka/ logging: level: # log 级别 org.springframework.cloud.gateway: debug
1. 停止注册中心工程(registry-service),网关工程(master-service)和服务工程 A(a-service)
2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值
更改为 route_addRequestParameter
3. 上面配置文件内容意思是访问的路径 http://localhost:8000/age (网关地址/age)
会被转发到 http://gateway-service/age(uri/age),并传入 'age=three' 参数(注意为 Get 请求)
4. 注意此处的配置 uri: lb://gateway-service 与之前都有所不同,之前都是指定了明确的转发地址,可以满足
单个服务转发的需求,但是一般情况都会有多个服务,所以这里是指定的服务名称,格式为:lb://应用注册
服务名。
5. 启动注册中心工程(registry-service),网关工程(master-service)和服务工程 A/B(a-service、b-service)
6. 项目启动成功后访问:http://localhost:8000/age
7. 这时可能会报错 500.错误信息为 'Unable to find instance for gateway-service'
8. 这种情况不要慌张,只是服务还没有被注册到注册中心,稍等片刻再访问
9. 多次访问:http://localhost:8000/age
10. 轮流输出内容:'I am three years old this year. aaa' 和 'I am three years old this year. bbb'
11. 此时还通过网关达到了负载均衡的效果
12. 证明转发指定服务并传入参数成功
master-service - 熔断
spring: # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。 ## 熔断 profiles: route_hystrix application: # 应用名称 name: gateway-master cloud: gateway: discovery: locator: # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务 enabled: true # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。) routes: # 路由标识(id:标识,具有唯一性) 熔断 - id: route_hystrix # 目标服务地址(uri:地址,请求转发后的地址) uri: lb://gateway-service # 路由条件(predicates:断言,匹配 HTTP 请求内容) predicates: ## 匹配 GET 请求 - Method=GET # 过滤器(filters:过滤器,过滤规则) filters: ## 添加指定参数 - AddRequestParameter=age, three ## 熔断 - name: Hystrix args: name: fallbackcmd ### fallback 时调用的方法 http://localhost:8000/fallback fallbackUri: forward:/fallback eureka: instance: # 使用 ip 代替实例名 prefer-ip-address: true # 实例的主机名 hostname: ${spring.cloud.client.ip-address} # 实例的 ID 规则 instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} client: serviceUrl: # 注册中心地址 defaultZone: http://${eureka.instance.hostname}:8761/eureka/ logging: level: # log 级别 org.springframework.cloud.gateway: debug
1. 停止注册中心工程(registry-service),网关工程(master-service)和服务工程 A/B(a-service、b-service)
2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改为 route_hystrix
3. 上面配置文件内容意思是访问的路径 http://localhost:8000/age (网关地址/age)
会被转发到 http://gateway-service/age(uri/age),并传入 'age=three' 参数(注意为 Get 请求)
4. 注意此处的配置 uri: lb://gateway-service 与之前都有所不同,之前都是指定了明确的转发地址,可以满足
单个服务转发的需求,但是一般情况都会有多个服务,所以这里是指定的服务名称,格式为:lb://应用注册
服务名。
5. 此处还多配置了一个过滤器 '- name: Hystrix'(熔断)
6. 当请求服务出错时,会调用 fallback,路径为:http://localhost:8000/fallback (网关地址/fallback)
7. 此时就需要如下前端控制器
master-service - 熔断 - controller
package com.zwc.gateway.hystrix; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @ClassName FallbackController * @Desc TODO 网关断路器 * @Date 2019/6/23 19:33 * @Version 1.0 */ @RestController public class FallbackController { /* * @ClassName FallbackController * @Desc TODO 网关断路器 * @Date 2019/6/23 19:35 * @Version 1.0 */ @RequestMapping("/fallback") public String fallback() { return "I'm Spring Cloud Gateway fallback."; } }
8. 启动注册中心工程(registry-service),网关工程(master-service)和服务工程 A/B(a-service、b-service)
9. 项目启动成功后访问:http://localhost:8000/age
10. 输出内容:'I'm Spring Cloud Gateway fallback.'
11. 证明熔断成功
master-service - 限流(重点,解决不生效问题)
spring: # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。 ## 限流 profiles: route_requestRateLimiter redis: host: localhost port: 6379 database: 0 application: # 应用名称 name: gateway-master cloud: gateway: discovery: locator: # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务 enabled: true # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。) routes: # 路由标识(id:标识,具有唯一性) 限流 - id: route_requestRateLimiter # 目标服务地址(uri:地址,请求转发后的地址) uri: lb://gateway-service # 路由条件(predicates:断言,匹配 HTTP 请求内容) predicates: ## 匹配 GET 请求 - Method=GET # 过滤器(filters:过滤器,过滤规则) filters: ## 添加指定参数 - AddRequestParameter=age, three ## 限流 - name: RequestRateLimiter args: ### 限流过滤器的 Bean 名称 key-resolver: '#{@uriKeyResolver}' ### 希望允许用户每秒处理多少个请求 redis-rate-limiter.replenishRate: 1 ### 用户允许在一秒钟内完成的最大请求数 redis-rate-limiter.burstCapacity: 3 eureka: instance: # 使用 ip 代替实例名 prefer-ip-address: true # 实例的主机名 hostname: ${spring.cloud.client.ip-address} # 实例的 ID 规则 instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} client: serviceUrl: # 注册中心地址 defaultZone: http://${eureka.instance.hostname}:8761/eureka/ logging: level: # log 级别 org.springframework.cloud.gateway: debug
1. 停止注册中心工程(registry-service),网关工程(master-service)和服务工程 A/B(a-service、b-service)
2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值
更改为 route_requestRateLimiter
3. 上面配置文件内容意思是访问的路径 http://localhost:8000/age (网关地址/age)
会被转发到 http://gateway-service/age(uri/age),并传入 'age=three' 参数(注意为 Get 请求)
4. 注意此处还需要配置 redis 的连接信息
5. 注意此处是结合 redis 实现的限流,所以 filter 过滤器的 name 必须为 RequestRateLimiter
6. 并且通过实现 KeyResolver 类来自定义限流策略,如下
master-service - 限流 - 策略
package com.zwc.gateway.config.filters; import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; /** * @ClassName UriKeyResolver * @Desc TODO Spring Cloud Gateway 网关限流过滤器 * @Date 2019/6/23 17:59 * @Version 1.0 */ public class UriKeyResolver implements KeyResolver { /* * @ClassName UriKeyResolver * @Desc TODO 根据请求的 uri 限流 * @Date 2019/6/29 17:25 * @Version 1.0 */ @Override public Mono<String> resolve(ServerWebExchange exchange) { return Mono.just(exchange.getRequest().getURI().getPath()); } }
7. 启动本地 redis(redis-server.exe) 服务
8. 启动注册中心工程(registry-service),网关工程(master-service)和服务工程 A/B(a-service、b-service)
9. 项目启动成功后访问:http://localhost:8000/age
10. 此时限流却无论如何都不生效,原因有如下两点
① redis-server 版本过低!我 Windows 本地是 redis-2.4.2 版本的,要用 3 以上的版本!!!
② 数据在 redis 中存储的时间只有几秒,所以得使用 monitor 指令来动态的观察!!!
11. 打开 redis-cli.exe,输入命令 monitor
12. 快速刷新地址:http://localhost:8000/age
13. 页面上会出现 429,redis-cli.exe 中会出现很多数据交互(request_rate_limiter.xxx 开头的 key)
14. 证明限流成功
master-service - 综合
spring: # 配置文件名称,用来标识不同环境的配置。由 spring.profiles.active 的值来决定使用哪组配置。 ## 综合 profiles: route_all redis: host: localhost port: 6379 database: 0 application: # 应用名称 name: gateway-master cloud: gateway: discovery: locator: # 是否和服务注册与发现组件结合,设置为 true 后可以直接使用应用名称调用服务 enabled: true # 路由(routes:路由,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。) routes: # 路由标识(id:标识,具有唯一性) 综合 - id: route_all # 目标服务地址(uri:地址,请求转发后的地址) uri: lb://gateway-service # 路由条件(predicates:断言,匹配 HTTP 请求内容) predicates: ## 转发地址格式为 uri/routeAll,/all 部分会被下面的过滤器给截取掉 - Path=/all/routeAll ## 匹配 GET 请求 - Method=GET # 过滤器(filters:过滤器,过滤规则) filters: ## 截取路径位数 - StripPrefix=1 ## 添加指定参数 - AddRequestParameter=pass, yes ## 熔断 - name: Hystrix args: name: fallbackcmd ### fallback 时调用的方法 http://localhost:8000/fallback fallbackUri: forward:/fallback ## 限流 - name: RequestRateLimiter args: ### 限流过滤器的 Bean 名称 key-resolver: '#{@uriKeyResolver}' ### 希望允许用户每秒处理多少个请求 redis-rate-limiter.replenishRate: 1 ### 用户允许在一秒钟内完成的最大请求数 redis-rate-limiter.burstCapacity: 3 eureka: instance: # 使用 ip 代替实例名 prefer-ip-address: true # 实例的主机名 hostname: ${spring.cloud.client.ip-address} # 实例的 ID 规则 instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} client: serviceUrl: # 注册中心地址 defaultZone: http://${eureka.instance.hostname}:8761/eureka/ logging: level: # log 级别 org.springframework.cloud.gateway: debug
1. 停止注册中心工程(registry-service),网关工程(master-service)和服务工程 A/B(a-service、b-service)
2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改为 route_all
3. 上面配置文件内容意思是访问的路径 http://localhost:8000/all/routeAll (网关地址/all/routeAll)截取 /all 部分,
会被转发到 http://gateway-service/routeAll(uri/routeAll),并传入 'pass=yes' 参数(注意为 Get 请求)
4. 启动注册中心工程(registry-service),网关工程(master-service)和服务工程 A/B(a-service、b-service)
5. 项目启动成功后访问:http://localhost:8000/all/routeAll
6. 首先会返回 'I'm Spring Cloud Gateway fallback.',因为服务还未被注册到注册中心
7. 然后会返回 '{"msg":"缺少凭证","code":-1}',因为配置了全局过滤器,如下
package com.zwc.gateway.config.filters; import com.alibaba.fastjson.JSONObject; 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.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import org.springframework.core.io.buffer.DataBuffer; import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; /** * @ClassName TokenFilter * @Desc TODO 请求认证过滤器 * @Date 2019/6/29 17:49 * @Version 1.0 */ public class TokenFilter implements GlobalFilter{ @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 请求对象 ServerHttpRequest request = exchange.getRequest(); // 响应对象 ServerHttpResponse response = exchange.getResponse(); // 只有综合路由才添加这个全局过滤器(routesId:route_all) // 如果请求路径中不存在 routeAll 字符串 if(request.getURI().toString().indexOf("routeAll") == -1){ System.out.println("filter -> return"); // 直接跳出 return chain.filter(exchange); } // 从请求中获取 token 参数 String token = exchange.getRequest().getQueryParams().getFirst("token"); // 如果为空,那么将返回 401 if (token == null || token.isEmpty()) { // 响应消息内容对象 JSONObject message = new JSONObject(); // 响应状态 message.put("code", -1); // 响应内容 message.put("msg", "缺少凭证"); // 转换响应消息内容对象为字节 byte[] bits = message.toJSONString().getBytes(StandardCharsets.UTF_8); DataBuffer buffer = response.bufferFactory().wrap(bits); // 设置响应对象状态码 401 response.setStatusCode(HttpStatus.UNAUTHORIZED); // 设置响应对象内容并且指定编码,否则在浏览器中会中文乱码 response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8"); // 返回响应对象 return response.writeWith(Mono.just(buffer)); } // 获取请求地址 String beforePath = request.getPath().pathWithinApplication().value(); // 获取响应状态码 HttpStatus beforeStatusCode = response.getStatusCode(); System.out.println("响应码:" + beforeStatusCode + ",请求路径:" + beforePath); // 请求前 System.out.println("filter -> before"); // 如果不为空,就通过 return chain.filter(exchange).then(Mono.fromRunnable(() -> { // 获取请求地址 String afterPath = request.getPath().pathWithinApplication().value(); // 获取响应状态码 HttpStatus afterStatusCode = response.getStatusCode(); System.out.println("响应码:" + afterStatusCode + ",请求路径:" + afterPath); // 响应后 System.out.println("filter -> after"); })); } }
8. 全局过滤器,不需要配置在配置文件中,作用于所有路由;只是这里在处理前做了判断,只有路径中存在
routeAll 字符串才到后续处理;并且处理分为请求前的处理,和响应后的处理
9. 此时在地址:http://localhost:8000/all/routeAll 中添加 token 参数
10. 访问:http://localhost:8000/all/routeAll?token=123
11. 轮流输出内容:'Can I pass? yes! port:9000' 和 'Can I pass? yes! port:9001'
12. 观察 gateway 工程的控制台,会有如下内容输出
响应码:null,请求路径:/routeAll filter -> before 响应码:200,请求路径:/routeAll filter -> after
13. 证明全局过滤器过滤成功
service 工程 - 项目结构
把多工程项目使用 IntelliJ IDEA 打开
- 把项目从 GitHub 中下载到你的本地
- 打开 IntelliJ IDEA
- 点击 File -> Open
- 打开你下载到本地的项目目录
- springcloud-gateway -> springcloud-gateway-service(选择打开此工程)
- 打开 service 工程后
- 再次点击 File -> Project Structrue
- 选择 Modules,点击 '+' 符号
- 点击 Import Module
- 还是打开你下载到本地的项目目录
- springcloud-gateway -> springcloud-gateway-commons -> pom.xml
- 点击 OK
- 点击 Next,Finish
- 点击 Apply,OK
希望能够帮助到你
over
-
Spring Cloud Gateway初体验
2018-11-06 18:55:37https://www.fangzhipeng.com/springcloud/2018/11/06/sc-f-gateway1/ 本文出自方志朋的博客 这篇文章讲述了如何简单地使用Spring Cloud Gateway,来源于Spring Cloud官方案例,地址...转载请标明出处:
http://blog.csdn.net/forezp/article/details/83792388
本文出自方志朋的博客点击获取SpringCloud 、Spring Boot视频
这篇文章讲述了如何简单地使用Spring Cloud Gateway,来源于Spring Cloud官方案例,地址https://spring.io/guides/gs/gateway 。
简介
Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,取代Zuul网关。网关作为流量的,在微服务系统中有着非常作用,网关常见的功能有路由转发、权限校验、限流控制等作用。本文首先用官方的案例带领大家来体验下Spring Cloud的一些简单的功能,在后续文章我会使用详细的案例和源码解析来详细讲解Spring Cloud Gateway.
创建工程
本案例的的源码下载于官方案例,也可以在我的Github上下载。工程使用的Spring Boot版本为2.0.5.RELEASE,Spring Cloud版本为Finchley.SR1。
新建一个工程,取名为sc-f-gateway-first-sight在工程的pom文件引用工程所需的依赖,包括spring boot和spring cloud,以及gateway的起步依赖spring-cloud-starter-gateway,代码如下:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> </parent> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Finchley.SR1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
** 注:详细的pom文件依赖,可以见源码。**
创建一个简单的路由
在spring cloud gateway中使用RouteLocator的Bean进行路由转发,将请求进行处理,最后转发到目标的下游服务。在本案例中,会将请求转发到http://httpbin.org:80这个地址上。代码如下:
@SpringBootApplication @RestController public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean public RouteLocator myRoutes(RouteLocatorBuilder builder) { return builder.routes() .route(p -> p .path("/get") .filters(f -> f.addRequestHeader("Hello", "World")) .uri("http://httpbin.org:80")) .build(); } }
在上面的myRoutes方法中,使用了一个RouteLocatorBuilder的bean去创建路由,除了创建路由RouteLocatorBuilder可以让你添加各种predicates和filters,predicates断言的意思,顾名思义就是根据具体的请求的规则,由具体的route去处理,filters是各种过滤器,用来对请求做各种判断和修改。
上面创建的route可以让请求“/get”请求都转发到“http://httpbin.org/get”。在route配置上,我们添加了一个filter,该filter会将请求添加一个header,key为hello,value为world。
启动springboot项目,在浏览器上http://localhost:8080/get,浏览器显示如下:
{ "args": {}, "headers": { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", "Cache-Control": "max-age=0", "Connection": "close", "Cookie": "_ga=GA1.1.412536205.1526967566; JSESSIONID.667921df=node01oc1cdl4mcjdx1mku2ef1l440q1.node0; screenResolution=1920x1200", "Forwarded": "proto=http;host=\"localhost:8080\";for=\"0:0:0:0:0:0:0:1:60036\"", "Hello": "World", "Host": "httpbin.org", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36", "X-Forwarded-Host": "localhost:8080" }, "origin": "0:0:0:0:0:0:0:1, 210.22.21.66", "url": "http://localhost:8080/get" }
可见当我们向gateway工程请求“/get”,gateway会将工程的请求转发到“http://httpbin.org/get”,并且在转发之前,加上一个filter,该filter会将请求添加一个header,key为hello,value为world。
注意HTTPBin展示了请求的header hello和值world。
使用Hystrix
在spring cloud gateway中可以使用Hystrix。Hystrix是 spring cloud中一个服务熔断降级的组件,在微服务系统有着十分重要的作用。
Hystrix是 spring cloud gateway中是以filter的形式使用的,代码如下:@Bean public RouteLocator myRoutes(RouteLocatorBuilder builder) { String httpUri = "http://httpbin.org:80"; return builder.routes() .route(p -> p .path("/get") .filters(f -> f.addRequestHeader("Hello", "World")) .uri(httpUri)) .route(p -> p .host("*.hystrix.com") .filters(f -> f .hystrix(config -> config .setName("mycmd") .setFallbackUri("forward:/fallback"))) .uri(httpUri)) .build(); }
在上面的代码中,我们使用了另外一个router,该router使用host去断言请求是否进入该路由,当请求的host有“*.hystrix.com”,都会进入该router,该router中有一个hystrix的filter,该filter可以配置名称、和指向性fallback的逻辑的地址,比如本案例中重定向到了“/fallback”。
现在写的一个“/fallback”的l逻辑:
@RequestMapping("/fallback") public Mono<String> fallback() { return Mono.just("fallback"); }
Mono是一个Reactive stream,对外输出一个“fallback”字符串。
使用curl执行以下命令:
curl --dump-header - --header 'Host: www.hystrix.com' http://localhost:8080/delay/3
返回的响应为:
fallback
可见,带hostwww.hystrix.com的请求执行了hystrix的fallback的逻辑。
总结
本文通过官方的一个简单的案例,来讲解了spring cloud gateway的简单用法,在spring cloud gateway中有2个重要的概念predicates和filters,它们个将会在后续文章讲解。敬请期待。
源码下载
https://github.com/forezp/SpringCloudLearning/tree/master/sc-f-gateway-first-sight
更多阅读
- 史上最简单的SpringCloud教程 | 第十四篇: Spring Cloud Gateway初体验
- 史上最简单的SpringCloud教程 | 第十五篇: Spring Cloud Gateway 之Predict篇
- 史上最简单的SpringCloud教程 | 第十六篇: Spring Cloud Gateway 之filter篇
- 史上最简单的SpringCloud教程 | 第十七篇: Spring Cloud Gateway 之限流篇
- 史上最简单的SpringCloud教程 | 第十八篇: spring cloud gateway之服务注册与发现
扫码关注公众号有惊喜(转载本站文章请注明作者和出处 方志朋的博客)
-
spring cloud gateway之filter篇
2018-12-17 21:45:21在上一篇文章详细的介绍了Gateway的Predict,Predict决定了请求由哪一个路由处理,在路由处理之前,需要经过“pre”类型的过滤器处理,处理返回响应之后,可以由“post”类型的过滤器处理。 filter的作用和生命周期 ...转载请标明出处:
http://blog.csdn.net/forezp/article/details/85057268
本文出自方志朋的博客个人博客纯净版https://www.fangzhipeng.com/springcloud/2018/12/21/sc-f-gatway3.html
在上一篇文章详细的介绍了Gateway的Predict,Predict决定了请求由哪一个路由处理,在路由处理之前,需要经过“pre”类型的过滤器处理,处理返回响应之后,可以由“post”类型的过滤器处理。
filter的作用和生命周期
由filter工作流程点,可以知道filter有着非常重要的作用,在“pre”类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等,在“post”类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等。首先需要弄清一点为什么需要网关这一层,这就不得不说下filter的作用了。
作用
当我们有很多个服务时,比如下图中的user-service、goods-service、sales-service等服务,客户端请求各个服务的Api时,每个服务都需要做相同的事情,比如鉴权、限流、日志输出等。
对于这样重复的工作,有没有办法做的更好,答案是肯定的。在微服务的上一层加一个全局的权限控制、限流、日志输出的Api Gatewat服务,然后再将请求转发到具体的业务服务层。这个Api Gateway服务就是起到一个服务边界的作用,外接的请求访问系统,必须先通过网关层。
生命周期
Spring Cloud Gateway同zuul类似,有“pre”和“post”两种方式的filter。客户端的请求先经过“pre”类型的filter,然后将请求转发到具体的业务服务,比如上图中的user-service,收到业务服务的响应之后,再经过“post”类型的filter处理,最后返回响应到客户端。
与zuul不同的是,filter除了分为“pre”和“post”两种方式的filter外,在Spring Cloud Gateway中,filter从作用范围可分为另外两种,一种是针对于单个路由的gateway filter,它在配置文件中的写法同predict类似;另外一种是针对于所有路由的global gateway filer。现在从作用范围划分的维度来讲解这两种filter。
gateway filter
过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。过滤器可以限定作用在某些特定请求路径上。 Spring Cloud Gateway包含许多内置的GatewayFilter工厂。
GatewayFilter工厂同上一篇介绍的Predicate工厂类似,都是在配置文件application.yml中配置,遵循了约定大于配置的思想,只需要在配置文件配置GatewayFilter Factory的名称,而不需要写全部的类名,比如AddRequestHeaderGatewayFilterFactory只需要在配置文件中写AddRequestHeader,而不是全部类名。在配置文件中配置的GatewayFilter Factory最终都会相应的过滤器工厂类处理。
Spring Cloud Gateway 内置的过滤器工厂一览表如下:
现在挑几个常见的过滤器工厂来讲解,每一个过滤器工厂在官方文档都给出了详细的使用案例,如果不清楚的还可以在org.springframework.cloud.gateway.filter.factory看每一个过滤器工厂的源码。
AddRequestHeader GatewayFilter Factory
创建工程,引入相关的依赖,包括spring boot 版本2.0.5,spring Cloud版本Finchley,gateway依赖如下:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
在工程的配置文件中,加入以下的配置:
server: port: 8081 spring: profiles: active: add_request_header_route --- spring: cloud: gateway: routes: - id: add_request_header_route uri: http://httpbin.org:80/get filters: - AddRequestHeader=X-Request-Foo, Bar predicates: - After=2017-01-20T17:42:47.789-07:00[America/Denver] profiles: add_request_header_route
在上述的配置中,工程的启动端口为8081,配置文件为add_request_header_route,在add_request_header_route配置中,配置了roter的id为add_request_header_route,路由地址为http://httpbin.org:80/get,该router有AfterPredictFactory,有一个filter为AddRequestHeaderGatewayFilterFactory(约定写成AddRequestHeader),AddRequestHeader过滤器工厂会在请求头加上一对请求头,名称为X-Request-Foo,值为Bar。为了验证AddRequestHeaderGatewayFilterFactory是怎么样工作的,查看它的源码,AddRequestHeaderGatewayFilterFactory的源码如下:
public class AddRequestHeaderGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory { @Override public GatewayFilter apply(NameValueConfig config) { return (exchange, chain) -> { ServerHttpRequest request = exchange.getRequest().mutate() .header(config.getName(), config.getValue()) .build(); return chain.filter(exchange.mutate().request(request).build()); }; } }
由上面的代码可知,根据旧的ServerHttpRequest创建新的 ServerHttpRequest ,在新的ServerHttpRequest加了一个请求头,然后创建新的 ServerWebExchange ,提交过滤器链继续过滤。
启动工程,通过curl命令来模拟请求:
curl localhost:8081
最终显示了从 http://httpbin.org:80/get得到了请求,响应如下:
{ "args": {}, "headers": { "Accept": "*/*", "Connection": "close", "Forwarded": "proto=http;host=\"localhost:8081\";for=\"0:0:0:0:0:0:0:1:56248\"", "Host": "httpbin.org", "User-Agent": "curl/7.58.0", "X-Forwarded-Host": "localhost:8081", "X-Request-Foo": "Bar" }, "origin": "0:0:0:0:0:0:0:1, 210.22.21.66", "url": "http://localhost:8081/get" }
可以上面的响应可知,确实在请求头中加入了X-Request-Foo这样的一个请求头,在配置文件中配置的AddRequestHeader过滤器工厂生效。
跟AddRequestHeader过滤器工厂类似的还有AddResponseHeader过滤器工厂,在此就不再重复。
RewritePath GatewayFilter Factory
在Nginx服务启中有一个非常强大的功能就是重写路径,Spring Cloud Gateway默认也提供了这样的功能,这个功能是Zuul没有的。在配置文件中加上以下的配置:
spring: profiles: active: rewritepath_route --- spring: cloud: gateway: routes: - id: rewritepath_route uri: https://blog.csdn.net predicates: - Path=/foo/** filters: - RewritePath=/foo/(?<segment>.*), /$\{segment} profiles: rewritepath_route
上面的配置中,所有的/foo/**开始的路径都会命中配置的router,并执行过滤器的逻辑,在本案例中配置了RewritePath过滤器工厂,此工厂将/foo/(?.*)重写为{segment},然后转发到https://blog.csdn.net。比如在网页上请求localhost:8081/foo/forezp,此时会将请求转发到https://blog.csdn.net/forezp的页面,比如在网页上请求localhost:8081/foo/forezp/1,页面显示404,就是因为不存在https://blog.csdn.net/forezp/1这个页面。
自定义过滤器
Spring Cloud Gateway内置了19种强大的过滤器工厂,能够满足很多场景的需求,那么能不能自定义自己的过滤器呢,当然是可以的。在spring Cloud Gateway中,过滤器需要实现GatewayFilter和Ordered2个接口。写一个RequestTimeFilter,代码如下:
public class RequestTimeFilter implements GatewayFilter, Ordered { private static final Log log = LogFactory.getLog(GatewayFilter.class); private static final String REQUEST_TIME_BEGIN = "requestTimeBegin"; @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { exchange.getAttributes().put(REQUEST_TIME_BEGIN, System.currentTimeMillis()); return chain.filter(exchange).then( Mono.fromRunnable(() -> { Long startTime = exchange.getAttribute(REQUEST_TIME_BEGIN); if (startTime != null) { log.info(exchange.getRequest().getURI().getRawPath() + ": " + (System.currentTimeMillis() - startTime) + "ms"); } }) ); } @Override public int getOrder() { return 0; } }
在上面的代码中,Ordered中的int getOrder()方法是来给过滤器设定优先级别的,值越大则优先级越低。还有有一个filterI(exchange,chain)方法,在该方法中,先记录了请求的开始时间,并保存在ServerWebExchange中,此处是一个“pre”类型的过滤器,然后再chain.filter的内部类中的run()方法中相当于"post"过滤器,在此处打印了请求所消耗的时间。然后将该过滤器注册到router中,代码如下:
@Bean public RouteLocator customerRouteLocator(RouteLocatorBuilder builder) { // @formatter:off return builder.routes() .route(r -> r.path("/customer/**") .filters(f -> f.filter(new RequestTimeFilter()) .addResponseHeader("X-Response-Default-Foo", "Default-Bar")) .uri("http://httpbin.org:80/get") .order(0) .id("customer_filter_router") ) .build(); // @formatter:on }
重启程序,通过curl命令模拟请求:
curl localhost:8081/customer/123
在程序的控制台输出一下的请求信息的日志:
2018-11-16 15:02:20.177 INFO 20488 --- [ctor-http-nio-3] o.s.cloud.gateway.filter.GatewayFilter : /customer/123: 152ms
自定义过滤器工厂
在上面的自定义过滤器中,有没有办法自定义过滤器工厂类呢?这样就可以在配置文件中配置过滤器了。现在需要实现一个过滤器工厂,在打印时间的时候,可以设置参数来决定是否打印请参数。查看GatewayFilterFactory的源码,可以发现GatewayFilterfactory的层级如下:
过滤器工厂的顶级接口是GatewayFilterFactory,我们可以直接继承它的两个抽象类来简化开发AbstractGatewayFilterFactory和AbstractNameValueGatewayFilterFactory,这两个抽象类的区别就是前者接收一个参数(像StripPrefix和我们创建的这种),后者接收两个参数(像AddResponseHeader)。
过滤器工厂的顶级接口是GatewayFilterFactory,有2个两个较接近具体实现的抽象类,分别为AbstractGatewayFilterFactory和AbstractNameValueGatewayFilterFactory,这2个类前者接收一个参数,比如它的实现类RedirectToGatewayFilterFactory;后者接收2个参数,比如它的实现类AddRequestHeaderGatewayFilterFactory类。现在需要将请求的日志打印出来,需要使用一个参数,这时可以参照RedirectToGatewayFilterFactory的写法。
public class RequestTimeGatewayFilterFactory extends AbstractGatewayFilterFactory<RequestTimeGatewayFilterFactory.Config> { private static final Log log = LogFactory.getLog(GatewayFilter.class); private static final String REQUEST_TIME_BEGIN = "requestTimeBegin"; private static final String KEY = "withParams"; @Override public List<String> shortcutFieldOrder() { return Arrays.asList(KEY); } public RequestTimeGatewayFilterFactory() { super(Config.class); } @Override public GatewayFilter apply(Config config) { return (exchange, chain) -> { exchange.getAttributes().put(REQUEST_TIME_BEGIN, System.currentTimeMillis()); return chain.filter(exchange).then( Mono.fromRunnable(() -> { Long startTime = exchange.getAttribute(REQUEST_TIME_BEGIN); if (startTime != null) { StringBuilder sb = new StringBuilder(exchange.getRequest().getURI().getRawPath()) .append(": ") .append(System.currentTimeMillis() - startTime) .append("ms"); if (config.isWithParams()) { sb.append(" params:").append(exchange.getRequest().getQueryParams()); } log.info(sb.toString()); } }) ); }; } public static class Config { private boolean withParams; public boolean isWithParams() { return withParams; } public void setWithParams(boolean withParams) { this.withParams = withParams; } } }
在上面的代码中 apply(Config config)方法内创建了一个GatewayFilter的匿名类,具体的实现逻辑跟之前一样,只不过加了是否打印请求参数的逻辑,而这个逻辑的开关是config.isWithParams()。静态内部类类Config就是为了接收那个boolean类型的参数服务的,里边的变量名可以随意写,但是要重写List shortcutFieldOrder()这个方法。
。需要注意的是,在类的构造器中一定要调用下父类的构造器把Config类型传过去,否则会报ClassCastException
最后,需要在工程的启动文件Application类中,向Srping Ioc容器注册RequestTimeGatewayFilterFactory类的Bean。
@Bean public RequestTimeGatewayFilterFactory elapsedGatewayFilterFactory() { return new RequestTimeGatewayFilterFactory(); }
然后可以在配置文件中配置如下:
spring: profiles: active: elapse_route --- spring: cloud: gateway: routes: - id: elapse_route uri: http://httpbin.org:80/get filters: - RequestTime=false predicates: - After=2017-01-20T17:42:47.789-07:00[America/Denver] profiles: elapse_route
启动工程,在浏览器上访问localhost:8081?name=forezp,可以在控制台上看到,日志输出了请求消耗的时间和请求参数。
global filter
Spring Cloud Gateway根据作用范围划分为GatewayFilter和GlobalFilter,二者区别如下:
-
GatewayFilter : 需要通过spring.cloud.routes.filters 配置在具体路由下,只作用在当前路由上或通过spring.cloud.default-filters配置在全局,作用在所有路由上
-
GlobalFilter : 全局过滤器,不需要在配置文件中配置,作用在所有的路由上,最终通过GatewayFilterAdapter包装成GatewayFilterChain可识别的过滤器,它为请求业务以及路由的URI转换为真实业务服务的请求地址的核心过滤器,不需要配置,系统初始化时加载,并作用在每个路由上。
Spring Cloud Gateway框架内置的GlobalFilter如下:
上图中每一个GlobalFilter都作用在每一个router上,能够满足大多数的需求。但是如果遇到业务上的定制,可能需要编写满足自己需求的GlobalFilter。在下面的案例中将讲述如何编写自己GlobalFilter,该GlobalFilter会校验请求中是否包含了请求参数“token”,如何不包含请求参数“token”则不转发路由,否则执行正常的逻辑。代码如下:
public class TokenFilter implements GlobalFilter, Ordered { Logger logger=LoggerFactory.getLogger( TokenFilter.class ); @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { String token = exchange.getRequest().getQueryParams().getFirst("token"); if (token == null || token.isEmpty()) { logger.info( "token is empty..." ); exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } return chain.filter(exchange); } @Override public int getOrder() { return -100; } }
在上面的TokenFilter需要实现GlobalFilter和Ordered接口,这和实现GatewayFilter很类似。然后根据ServerWebExchange获取ServerHttpRequest,然后根据ServerHttpRequest中是否含有参数token,如果没有则完成请求,终止转发,否则执行正常的逻辑。
然后需要将TokenFilter在工程的启动类中注入到Spring Ioc容器中,代码如下:
@Bean public TokenFilter tokenFilter(){ return new TokenFilter(); }
启动工程,使用curl命令请求:
curl localhost:8081/customer/123
可以看到请没有被转发,请求被终止,并在控制台打印了如下日志:
2018-11-16 15:30:13.543 INFO 19372 --- [ctor-http-nio-2] gateway.TokenFilter : token is empty...
上面的日志显示了请求进入了没有传“token”的逻辑。
总结
本篇文章讲述了Spring Cloud Gateway中的过滤器,包括GatewayFilter和GlobalFilter。从官方文档的内置过滤器讲起,然后讲解自定义GatewayFilter、GatewayFilterFactory以及自定义的GlobalFilter。有很多内置的过滤器并没有讲述到,比如限流过滤器,这个我觉得是比较重要和大家关注的过滤器,将在之后的文章讲述。
更多阅读
参考资料
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.1.0.M1/single/spring-cloud-gateway.html
https://www.jianshu.com/p/eb3a67291050
https://blog.csdn.net/qq_36236890/article/details/80822051
https://windmt.com/2018/05/08/spring-cloud-14-spring-cloud-gateway-filter
源码下载
https://github.com/forezp/SpringCloudLearning/tree/master/sc-f-gateway-predicate
扫一扫,支持下作者吧(转载本站文章请注明作者和出处 方志朋的博客)
-
-
Gateway网关简介及使用
2019-10-09 20:54:12Gateway网关简介及使用 1. 什么是 API 网关(API Gateway) 分布式服务架构、微服务架构与 API 网关 在微服务架构里,服务的粒度被进一步细分,各个业务服务可以被独立的设计、开发、测试、部署和管理。这时,各个... -
Spring Cloud Gateway 之Predict篇
2018-12-09 12:53:44Spring Cloud gateway工作流程 在之前的文章的Spring Cloud Gateway初体验中,大家已经对Spring Cloud Gateway的功能有一个初步的认识,网关作为一个系统的流量的入口,有着举足轻重的作用,通常的作用如下: 协议... -
spring cloud gateway之服务注册与发现
2018-12-22 16:08:40在之前的文章介绍了Spring Cloud Gateway的Predict(断言)、Filter(过滤器),大家对Spring Cloud Gateway有初步的认识,其中在对服务路由转发的这一块,在之前的文章是采用硬编码的方式进行路由转发。这篇文章以... -
SpringCloud实战十三:Gateway之 Spring Cloud Gateway 动态路由
2019-01-19 23:13:30前面分别对 Spring Cloud Zuul 与 Spring Cloud Gateway 进行了简单的说明,它门是API网关,API网关负责服务请求路由、组合及协议转换,客户端的所有请求都首先经过API网关,然后由它将匹配的请求路由到合适的微服务... -
微服务网关实战——Spring Cloud Gateway
2019-05-24 16:02:31作为Netflix Zuul的替代者,Spring Cloud Gateway是一款非常实用的微服务网关,在Spring Cloud微服务架构体系中发挥非常大的作用。本文对Spring Cloud Gateway常见使用场景进行了梳理,希望对微服务开发人员提供一些... -
Dubbo结合Gateway实现微服务网关
2020-09-07 01:42:18Dubbo结合Gateway实现微服务网关 前言 最近,我发布了Dubbo Demo项目以及Gateway网关的博客,于是奇思妙想到能不能将两者结合起来呢?首先我们可以在Dubbo的官网中看了开发者文档,它推荐使用的网关只有三种Kong、... -
spring cloud gateway源码级讲解
2019-07-20 20:00:49本课程系统的讲解spring cloud gateway 1、spring cloud gateway的原理 2、spring cloud gateway的功能,会带着大家把官方文档过一遍 3、spring cloud gateway的搭建 4、spring cloud gateway结合注册... -
GateWay配置
2020-05-01 15:01:50Gateway配置 new module pom <dependencies> <dependency><!-- 引用自己定义的api通用包,可以使用Payment支付Entity --> <groupId>org.example</groupId> <... -
八、网关Gateway
2020-04-17 13:55:42SpringCloud推出的新一代网关Gateway..... -
gateway服务网关
2020-04-08 17:23:14gateway服务网关 -
gateway资源详解
2020-08-31 12:01:12学习目标 什么是gateway 在Kubernetes环境中,...gateway 分为两种,分别是ingress-gateway和egress-gateway,分别用来处理入口流量和出口流量。gateway本质也是一个envoy pod。 资源详解 selector 1.7.0/gat -
GatewayWorker流程
2019-12-20 13:45:55GatewayWorker流程 手里的项目遇到个需求,就了解了一下GatewayWorker。本来打算用这个了,但是最后还是选择了workerman。简单说一下GatewayWorker流程吧 因为项目需求用的php做设备通信。设备客户端使用tcp进行长... -
API Gateway
2017-08-13 22:31:25API Gateway 转自:http://www.cnblogs.com/Leo_wl/p/4934036.html 原文地址:http://microservices.io/patterns/apigateway.html,以下是使用google翻译对原文的翻译。 让我们想象一下你正在建立一个使用... -
Spring Cloud Gateway(一):认识Spring Cloud Gateway
2018-11-11 16:19:431、Spring Cloud Gateway 简介 Spring Cloud Gateway 系列目录 Spring Cloud Gateway(一):认识Spring Cloud Gateway 1.1、Spring Cloud Gateway 是什么 Spring Cloud Gateway 基于 Spring Boot 2, 是 Spring... -
Spring Cloud Gateway
2019-01-21 17:03:28Spring Cloud Gateway Gateway是Spring Cloud 第二代网关,第一代是Zuul。 Spring Cloud Gateway 简介 Spring Cloud Gateway 是什么 Spring Cloud Gateway是Spring官网基于Spring 5.0、 Spring Boot 2.0、Project ... -
gateway的作用
2020-09-14 15:14:56gateway介绍 gateway相当于所有服务的门户,将客户端请求与服务端应用相分离,客户端请求通过gateway后由定义的路由和断言进行转发,路由代表需要转发请求的地址,断言相当于请求这些地址时所满足的条件,只有同时... -
spring cloud zookeeper gateway
2019-04-28 14:14:15适用最新的spring cloud稳定版,微服务注册中心适用最新稳定版zookeeper。适用spring cloud gateway作为网关服务的demo -
spring cloud gateway配置多个路由规则+gateway retry
2019-05-06 20:31:52server: port: 9010 spring: application: name: micro-sdn-gateway cloud: gateway: discovery: locator: enabled: true#是否适用默认路由(通过gatewayUri:port/服务名/path直接访问服务接口) ... -
Thingsboard Gateway
2019-08-27 19:41:07Gateway是什么? gateway在thingsboard平台定义为一种特殊的设备,通过图形化配置的方式,解析OPC UA、modbus、MQTT、Http协议; 通过定时任务,拿到数据解析和转换数据,然后通过MQTT协议传输到thingsboard云端,... -
grpc-gateway
2020-02-22 18:59:46第三方库 https://github.com/grpc-ecosystem/grpc-gateway ...go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-s... -
APIGateway简介
2019-03-06 22:13:24综合了一下网上的APIGateway教学,总结了一下(所有图片来源于网络): 目录 1.什么是APIGateway 2.APIGateway的作用 3.APIGateway的重要功能 1.什么是APIGateway APIGateway 即API网关是一个服务器,所有请求... -
Spring Cloud Alibaba 05_使用微服务网关 Gateway 实现路由映射和API限流
2020-10-30 14:59:11Spring Cloud Alibaba 05_使用微服务网关 Gateway 实现路由映射和API限流 注:Gateway 是 SpringCloud 官方提供的新一代网关组件,是基于Netty 的,与 Servlet 不兼容 所以在 gateway 中不能出现 Servlet 相关的... -
GateWay负载均衡
2019-05-06 11:20:42之前说过GateWay是一个zuul的路由替代品,但GateWay也可以实现负载均衡的能力,与ribbon不一样,他通过服务注册中心的服务名/接口实现负载均衡的能力 我们把之前的代码复制一下,项目结构如下 我们需要用的是,...
-
Hadoop平台基准性能测试研究_张新玲.pdf
-
bat批处理获取正在使用的网卡名称
-
基于安卓Android音乐播放器
-
商业操盘手培养计划(完结)
-
seq2seq 对话,翻译
-
工作党福利来了!Python实现钉钉/企业微信自动打卡
-
(新)备战2021软考系统集成学习套餐
-
C/C++编程全家桶(Daozy极限编程)
-
学习html5骷髅跳舞.rar
-
Swift - 进度条工具
-
ArcGIS Pro2.6和ArcGIS Enterprise学习
-
vue 中页面中使用多个echarts图表并实现自适应
-
第一个Mybatis程序
-
OpenStack学习思维导图.xmind
-
常用的git命令
-
欧拉计划
-
Hadoop容错能力测试平台的设计与实现_赵志龙.caj
-
新手引导.unitypackage
-
GPIO端口输入模式
-
MockProject.rar