一、前言
gateway是spring cloud全家桶的一员,主要用作微服务的网关,是spring官方基于spring5.0,spring boot 2.0和project reactor等技术开发的网关服务,旨在为微服务提供一种简单有效的统一api路由管理方式,基于filter链的方式提供了网关的基本功能如安全、监控、埋点、限流等。
项目地址:https://spring.io/projects/spring-cloud-gateway
二、使用
1、依赖
spring cloud已集成gateway,只需要引入spring cloud的父pom,就能直接使用。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
2、路由配置
spring cloud gateway支持两种路由配置:yaml文件配置和代码配置。
(1)代码配置
在主程序中使用代码配置路由,官方示例如下:
@SpringBootApplication
public class DemogatewayApplication {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_route", r -> r.path("/get")
.uri("http://httpbin.org"))
.route("host_route", r -> r.host("*.myhost.org")
.uri("http://httpbin.org"))
.route("rewrite_route", r -> r.host("*.rewrite.org")
.filters(f -> f.rewritePath("/foo/(?<segment>.*)", "/${segment}"))
.uri("http://httpbin.org"))
.route("hystrix_route", r -> r.host("*.hystrix.org")
.filters(f -> f.hystrix(c -> c.setName("slowcmd")))
.uri("http://httpbin.org"))
.route("hystrix_fallback_route", r -> r.host("*.hystrixfallback.org")
.filters(f -> f.hystrix(c -> c.setName("slowcmd").setFallbackUri("forward:/hystrixfallback")))
.uri("http://httpbin.org"))
.route("limit_route", r -> r
.host("*.limited.org").and().path("/anything/**")
.filters(f -> f.requestRateLimiter(c -> c.setRateLimiter(redisRateLimiter())))
.uri("http://httpbin.org"))
.build();
}
}
(2)yaml文件配置
yaml文件是spring推荐使用的方式,使用上比较直观,以下是我们项目中的配置:
project:
name: my-gateway
# endpoint配置
management:
endpoints:
web:
exposure:
include: "*"
server:
port: 7002
# http服务器端口
server:
port: 7001
spring:
application:
name: ${project.name}
profiles:
active: testing
hsf:
group: my
version: 1.0.0.DAILY
timeout: 2000
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
# 跨域
globalcors:
corsConfigurations:
'[/**]':
allowedHeaders: "*"
allowedOrigins: "*"
allowedMethods:
- GET
POST
DELETE
PUT
OPTION
routes:
# 数据应用
- id: my-data-app
uri: lb://my-data-app
predicates:
- Path=/my-data-app/**
filters:
- StripPrefix=1
# 数据应用websocket接口
- id: my-data-app-websocket
uri: lb:ws://my-data-app
predicates:
- Path=/my-data-app/**
filters:
- StripPrefix=1
# 任务调度
- id: my-task-scheduler
uri: lb://my-task-scheduler
predicates:
- Path=/my-task-scheduler/**
filters:
- StripPrefix=1
# 流程跟踪
- id: my-process-tracking
uri: lb://my-process-tracking
predicates:
- Path=/my-process-tracking/**
filters:
- StripPrefix=1
# 软件产品质量
- id: my-app-quality
uri: lb://my-app-quality
predicates:
- Path=/my-app-quality/**
filters:
- StripPrefix=1
# 工程效率质量
- id: my-project-quality
uri: lb://my-project-quality
predicates:
- Path=/my-project-quality/**
filters:
- StripPrefix=1
# 在线产品质量
- id: my-online-quality
uri: lb://my-online-quality
predicates:
- Path=/my-online-quality/**
filters:
- StripPrefix=1
# 数据存储
- id: my-data-storage
uri: lb://my-data-storage
predicates:
- Path=/my-data-storage/**
filters:
- StripPrefix=1
# 数据收容
- id: dcpp-query
uri: lb://dcpp-query
predicates:
- Path=/dcpp-query/**
filters:
- StripPrefix=1
logging:
level:
org.springframework.cloud.gateway: DEBUG
org.springframework.http.server.reactive: DEBUG
org.springframework.web.reactive: DEBUG
id:每个route的唯一标识,如果不填写则为uuid
uri:转发的url,即最终访问的后端服务地址,如果lb开头则为服务注册中心上的服务地址
predicates:断言匹配器,根据规则进行匹配。
参考:https://cloud.spring.io/spring-cloud-gateway/spring-cloud-gateway.html#gateway-request-predicates-factories
三、实践
1、Nacos作为服务注册中心
(1)添加nacos依赖,并在启动类中开启服务发现配置
@EnableDiscoveryClient
@SpringBootApplication(scanBasePackages = {"com.amap.qinling"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
(2)路由规则按照lb://my-data-app方式进行配置,lb将会按照LoadBalancerClientFilter类进行处理,即根据my-data-app注册中心查找对应的服务host和端口并替换。
2、跨域支持
gateway跨域支持比较方便,只需要在application.yaml配置跨域相关配置即可:
spring:
cloud:
gateway:
discovery:
# 跨域
globalcors:
corsConfigurations:
'[/**]':
allowedHeaders: "*"
allowedOrigins: "*"
allowedMethods:
- GET
POST
DELETE
PUT
OPTION
3、websocket协议转发
需要转发的服务为websocket协议时,只需要在路由规则里面添加相应的配置即可:
routes:
# 数据应用
- id: my-data-app
uri: lb://my-data-app
predicates:
- Path=/my-data-app/**
filters:
- StripPrefix=1
# 数据应用websocket接口
- id: my-data-app-websocket
uri: lb:ws://my-data-app
predicates:
- Path=/my-data-app/**
filters:
- StripPrefix=1
uri:lb:ws://my-data-app,ws代表websocket协议,gateway匹配到ws开头的地址会自动匹配到这一条路由并转发。
如果gateway前面有nginx代理,或者转发的后端服务前面也有nginx,需要在每个nginx中添加websocket协议配置,如下:
location / {
# support webSocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
if ($request_uri ~ .*\.(txt|gif|jpg|jpeg|png|bmp|swf|js|css)$) {
access_log off;
}
proxy_pass http://127.0.0.1:7001;
}