1.声明
当前内容用于本人学习和使用当前的Gateway这个网关,当前内容为一个极为简单的demo
前面的NewDemo例子:NewDemo,主要是基于这个开始编写的
当前本人遇到的坑:
- 使用Gateway的时候必须依赖
spring-boot-starter-webflux
,如果不用可能起不来 - Gateway所依赖的
spring-boot-starter-webflux
与spring-boot-starter-web
冲突,如果项目中具有spring-boot-starter-web
,则报一个错误:Consider defining a bean of type 'org.springframework.http.codec.ServerCodecConfigurer' in your configuration.
(注意只有将当前项目中的web依赖干掉才能启动) - Gateway注册到当前的Erueka中需要依赖:
spring-cloud-starter-netflix-eureka-client
2.创建SpringCloud-NewDemo-Gateway项目
注意当前项目的父级项目为:SpringCloud-NewDemo
1.pom依赖
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>SpringCloud-NewDemo</groupId>
<artifactId>SpringCloud-NewDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>SpringCloud-NewDemo-Gateway</groupId>
<artifactId>SpringCloud-NewDemo-Gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringCloud-NewDemo-Gateway</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- 使用gateway这个网关服务,看看这个网关和zuul有什么区别 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<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>
</exclusions>
</dependency>
</dependencies>
</project>
2.当前的配置文件application.yml
server:
# 指定Tomcat端口
port: 8002
spring:
application:
name: gateway-service-provider
cloud:
gateway:
routes:
# 集成eureka注册中心的配置示例
- id: hello_ribbon_route
uri: http://localhost:8000
predicates:
- Path=/userService/**
# 这个过滤器就是用来移除userService这个前缀的
filters:
- StripPrefix=1
# 配置当前的gateway访问其他服务的时候的日志
logging:
level:
org.springframework.cloud.gateway: TRACE
org.springframework.http.server.reactive: DEBUG
org.springframework.web.reactive: DEBUG
reactor.ipc.netty: DEBUG
reactor.netty: DEBUG
# 配置eureka的服务注册中心
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
3.创建当前的入口类
@RestController
@SpringBootApplication
public class GatewaySampleApplication {
@RequestMapping("/hi")
public String helloGateway() {
return "hello Gateway";
}
public static void main(String[] args) {
SpringApplication.run(GatewaySampleApplication.class, args);
}
}
3.测试和使用
首先启动eureka服务注册中心,然后启动当前的UserProviderApplication项目,最后启动当前的Gateway项目
结果
4.分析Gateway的操作结果(主要通过控制台分析)
1.gateway获取到请求的url,并对其进行匹配,如果匹配则创建一个代理客户端去请求匹配的uri(重写请求)
2.重写请求,并将来自的地方写入header中传递到8000端口
3.请求达到8000端口并请求/users/1,获取结果并产生响应
4.8002端口接收请求,并进行处理,获取需要输出的数据最后显示在页面
5.使用serviceId方式简化访问
由于前面的uri写的地址是写死的,所以准备一种方案使用基于ServiceId的方式(Zuul中就是这样的)
只需要修改uri为lb://userprovider-service-provider
然后测试:
成功,但是发现于Zuul中没有使用熔断器的东西(服务下线中的熔断操作)
6.为Gateway中添加网关熔断操作
当我将UserProviderApplication项目关闭时再次请求
后台直接报错
解决办法直接配置:spring-cloud-starter-netflix-hystrix
为当前的项目添加hystrix的依赖(如果出现该异常java.lang.IllegalArgumentException: Unable to find GatewayFilterFactory with name hystrix
也需要添加下面依赖)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
为当前的项目添加配置依赖
spring:
application:
name: gateway-service-provider
cloud:
gateway:
routes:
# 集成eureka注册中心的配置示例
- id: hello_ribbon_route
uri: lb://userprovider-service-provider#http://localhost:8000
predicates:
- Path=/userService/**
filters:
# 移除/userService
- StripPrefix=1
# 配置网关熔断器
- name: Hystrix
args:
name: fallbackcmd
fallbackUri: forward:/fallback
然后再GatewaySampleApplication中添加/fallback
@RequestMapping("/fallback")
public String hystrixfallback() {
return "This is a fallback";
}
重启项目然后访问
这里主要参考:SpringCloud官方hystix
通过这里发现,当前的Gateway熔断方式主要通过过滤器方式实现的,主要需要配置(Zuul主要通过实现FallbackProvider这个接口方式实现的)
7.使用配置Bean方式设置路由操作
直接使用配置bean方式实现,修改当前的application.yml
server:
# 指定Tomcat端口
port: 8002
spring:
application:
name: gateway-service-provider
# cloud:
# gateway:
# routes:
# 集成eureka注册中心的配置示例
# - id: hello_ribbon_route
# uri: lb://userprovider-service-provider#http://localhost:8000
# predicates:
# - Path=/userService/**
# filters:
# 移除/userService
# - StripPrefix=1
# 配置网关熔断器
# - name: Hystrix
# args:
# name: fallbackcmd
# fallbackUri: forward:/fallback
#- id: ingredients-fallback
# uri: lb://gateway-service-provider
# predicates:
# - Path=/fallback
logging:
level:
org.springframework.cloud.gateway: TRACE
org.springframework.http.server.reactive: DEBUG
org.springframework.web.reactive: DEBUG
reactor.ipc.netty: DEBUG
reactor.netty: DEBUG
# 配置eureka的服务注册中心
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
在当前的GatewaySampleApplication中添加@Bean
@Bean
public RouteLocator customRouteLocator2(RouteLocatorBuilder builder) {
// @formatter:off
return builder.routes().route("user_provider_route", r -> r.host("*")
.filters(f -> f.rewritePath("/userService/(?<segment>.*)", "/${segment}")
.hystrix(c -> c.setFallbackUri("forward:/fallback")))
.uri("lb://userprovider-service-provider"))
.build();
}
这一个RouteLocator中直接配置了上面的内容,并实现了所有访问的熔断
测试
操作成功,直接使用RouteLocatorBuilder这个创建感觉很简单
8.总结
1.使用gateway的时候需要特别小心依赖,需要webflux,但是不需要web依赖
2.gateway需要eureka-client才能将自己注册到Eureka中心
3.gateway实际操作就是匹配url,处理url,最后通过代理方式发送请求到达指定的uri,最后将结果响应
4.使用基于javaBean的方式创建路由地址,比配置文件更加容易
以上纯属个人见解,如有问题请联本人!