搭建网关
导入maven包:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
他们的版本由父项目中的管理依赖提供:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR10</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.8.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
配置文件:
spring:
application:
name: gateway-api
cloud:
nacos:
server-addr: localhost:8848
gateway:
routes:
- id: user-service
uri: lb://userservice
predicates:
- Path=/user/**
server:
port: 9000
路由断言工厂 Route Predict Factory
名称 | 说明 | 示例 |
---|
After | 是某个时间点后的请求 | - After=2037-01-20T17:42:47.789-07:00[America/Denver] | Before | 是某个时间点之前的请求 | - Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai] | Between | 是某两个时间点之前的请求 | - Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver] | Cookie | 请求必须包含某些cookie | - Cookie=chocolate, ch.p | Header | 请求必须包含某些header | - Header=X-Request-Id, \d+ | Host | 请求必须是访问某个host(域名) | - Host=**.somehost.org,**.anotherhost.org | Method | 请求方式必须是指定方式 | - Method=GET,POST | Path | 请求路径必须符合指定规则 | - Path=/red/{segment},/blue/** | Query | 请求参数必须包含指定参数 | - Query=name, Jack或者- Query=name | RemoteAddr | 请求者的ip必须是指定范围 | - RemoteAddr=192.168.1.1/24 | Weight | 权重处理 | `` |
路由过滤器 GatewayFilter
有31中不同的路由过滤器工厂(GatewayFilterFactory)。 Spring Cloud 提供了多种网关过滤器工厂(GatewayFilterFactory):网关过滤器工厂。 常见的过滤器工厂如下:
名称 | 说明 |
---|
AddRequestHeader | 给当前请求添加一个请求头 | AddRequestParameter | 给当前请求添加一个参数 | RemoveRequestHeader | 移除请求中的一个请求头 | RemoveRequestParameter | 移除请求中的一个参数 | AddResponseHeader | 给响应结果中添加一个响应头 | RemoveResponseHeader | 从响应结果中移除有一个响应头 | RequestRateLimiter | 限制请求的流量 |
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
- AddRequestHeader=X-Request-red, blue
默认过滤器
对所有路由生效,需要写到 default-filters 中。
spring:
application:
name: gateway-api
cloud:
nacos:
server-addr: localhost:8848
gateway:
routes:
- id: user-service
uri: lb://userservice
predicates:
- Path=/user/**
filters:
- AddRequestParameter=name, tom
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
default-filters:
- AddRequestParameter=age,20
全局过滤器
GlobalFilter 的逻辑需要自己写代码实现,需要实现 GlobalFilter 接口。 使用 @Order 或者 Ordered 接口制定过滤器的优先级。(Order越小,优先级越高,越先执行)
- 路由过滤器和
defaultFilter 的order 由Spring 指定,默认是按照声明顺序从1递增 - 当过滤器的order值一样时,会按照
defaultFilter > 路由过滤器 > GlobalFilter 的顺序执行
@Component
public class GatewayGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
MultiValueMap<String, String> queryParams = request.getQueryParams();
String username = queryParams.getFirst("username");
if("admin".equals(username)){
return chain.filter(exchange);
}
response.setStatusCode(HttpStatus.UNAUTHORIZED);
return response.setComplete();
}
@Override
public int getOrder() {
return -1;
}
}
跨域问题处理
域名不同、端口不同时会发生跨域问题。需要是浏览器发起的请求,如果是各个服务之间的互相转发并不会涉及到跨域问题。
添加以下配置开放针对某些网站的跨域请求:
spring:
application:
name: gateway-api
cloud:
nacos:
server-addr: localhost:8848
gateway:
globalcors:
add-to-simple-url-handler-mapping: true
cors-configurations:
'[/**]':
allowed-origins:
- "http://localhost:8090"
allowed-methods:
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowed-headers: "*"
allow-credentials : true
maxAge: 360000
服务发现
可以通过spring.cloud.gateway.discovery.locator.enabled=true 将网关上已经注册的服务添加到路由中。默认的路由是: http://localhost:port/service_name/path 。
例如:http://localhost:9000/user/1 -> http://localhost:9000/userservice/user/1
spring:
application:
name: gateway-api
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
总结
- 使用
@LoadBalanced 注解访问服务时,nacos 和 eureka 可以通用。 - 使用
Feign 的方式访问服务时,nacos 和 eureka 可以通用。 nacos 的自动配置并不是针对所有包都生效,有时需要手动重新定义bean。- 网关的配置针对
eureka 和 nacos 采用同一套代码,只需要将服务注册到 eureka 或者 nacos 上即可(所有服务、网关都要注册) - 使用网关后,可以不在使用
feign-api ,因为网关已经有了负载均衡的功能。
|