在SpringCloud的网关的实现包含如下两种
zuul是基于Servlet的实现,属于阻塞时编程。而Gateway则是基于Sprng5中提供的WebFlux,属于响应式编程的实现,具有更好的性能。
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
dependency>
切记如下,如果具体的服务的地址是/orders开头。则下面要注释掉,否则访问http://127.0.0.1:8888/orders/1显示404
#default-filters: #全局用于配置所有路由共享过滤器
# - StripPrefix=1 #去掉- Path=/auth 前缀
# - PreserveHostHeader #发送原主机头
server:
port: 8888
spring:
application:
name: edevp-gateway
profiles:
active: dev
cloud:
nacos:
discovery: #服务注册与发现
server-addr: ${NACOS_HOST:nacos-host}:${NACOS_PORT:7102} #nacos地址
username: dev
password: xxxx
namespace: edevp-demo #指定命名空间 可以删掉namespace不写默认public
#配置文件组成 : 通俗点 服务名称-指定环境.后缀名称 name-active.file-extension
config: #动态配置
server-addr: ${spring.cloud.nacos.discovery.server-addr} #nacos地址
username: dev
password: xxxx
file-extension: yml #配置文件类型 非常重要后缀一定要一致 xxx.yml
namespace: edevp-demo #指定命名空间 可以删掉namespace不写默认public
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
gateway:
discovery:
locator:
# 是否可以通过其他服务的serviceId来转发到具体的服务实例。默认为false
# 为true,自动创建路由,路由访问方式:http://Gateway_HOST:Gateway_PORT/大写的serviceId/**,其中微服务应用名默认大写访问
# 让gateway通过服务发现组件找到其他的微服务,如果是true则自动,false才可以配置routes属性生效
enabled: false
# 服务名默认必须大写,否则会抛404错误,如果服务名要用小写,可在属性配置文件中添加spring.cloud.gateway.discovery.locator.lowerCaseServiceId=true配置解决
lower-case-service-id: true
#default-filters: #全局用于配置所有路由共享过滤器
# - StripPrefix=1 #去掉- Path=/auth 前缀
# - PreserveHostHeader #发送原主机头
routes: # 网关路由配置
- id: edevp-user # 路由id,自定义,只要唯一即可
# uri: http://127.0.0.1:8202 # 路由的目标地址,http就是固定地址
uri: lb://edevp-user # 路由的目的地址,lb就是负载均衡,后面跟服务名称
predicates: # 路由断言,也就是判断请求是否符合路由规则的调价
- Path=/users/** # 这个是按照规则匹配,只要以/user/开头就符合要求
- id: edevp-order
uri: lb://edevp-order
predicates: # 路由断言,也就是判断请求是否符合路由规则的调价
- Path=/orders/** # 这个是按照规则匹配,只要以/user/开头就符合要求
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
有多达31中不通的工厂,开参考官网文档https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories
spring:
cloud:
gateway:
routes:
- id: edevp-user # 路由id,自定义,只要唯一即可
# uri: http://127.0.0.1:8202 # 路由的目标地址,http就是固定地址
uri: lb://edevp-user # 路由的目的地址,lb就是负载均衡,后面跟服务名称
predicates: # 路由断言,也就是判断请求是否符合路由规则的调价
- Path=/users/** # 这个是按照规则匹配,只要以/user/开头就符合要求
filters:
- AddRequestHeader=X-Request-red, blue
default-filters:
- AddRequestHeader=X-Request-red, green
如果是给全局增加请求头default-filters:
在user-service中的controller中添加如下
@GetMapping("/info/{id}")
public R<UserInfoDTO> get(@PathVariable("id") String id, @RequestHeader(value = "X-Request-red", required = true) String header) {
UserInfoDTO data = new UserInfoDTO();
data.setName(properties.getValue()+"-"+id+"-"+header);
return R.ok(data);
}
浏览器访问{{gateway-host}}/users/info/1发现两个header都被设置
{
"code": 0,
"data": {
"name": "李四-1-true,green,blue"
}
}
## 1. 通过全局过滤器校验权限
拦截请求参数中Authorization的值是否等于admin,如果是则放行
order最好设置
-200
,否则遇到Unable to find instance
会直接先跳到ErrorWebExceptionHandler
/**
* @author lean
* //Order 顺序,值越小,优先级越高
*/
@Order(-200)
@Component
public class AuthorizeFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1. 获取请求参数
ServerHttpRequest request = exchange.getRequest();
MultiValueMap<String, String> params = request.getQueryParams();
// 2.获取参数中的authorization 参数
String auth = params.getFirst("authorization");
// 3.判断参数值是否等于admin
if("admin".equals(auth)){
// 4.放行
return chain.filter(exchange);
}
// 5. 否拦截
// 5.1 设置状态码
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
// 5.2 拦截请求
return exchange.getResponse().setComplete();
}
}
从下图可以知道网关中的所有服务器最终都是GatewayFilter,因为是可以合并到一个集合排序的
'[/]'*表示检测所有请求
allowCredentials: true 是否允许携带cookie
spring:
cloud:
gateway:
# 允许跨域请求配置
globalcors:
add-to-simple-url-handler-mapping: true # 允许来自所有域名(allowedOrigins)的所有请求方式(allowedMethods)发出CORS请求
cors-configurations:
'[/**]': # 拦截所有请求
# 允许任何域名使用
allowedOrigins: "*"
# 允许任何头
allowedHeaders: "*"
# 允许任何方法(post、get等)
allowedMethods: "*"
# sessionid 多次访问一致
allowCredentials: true
# 允许来自所有域名(allowedOrigins)的所有请求方式(allowedMethods)发出CORS请求
允许指定ip端口访问
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
# 允许携带认证信息
# 允许跨域的源(网站域名/ip),设置*为全部
# 允许跨域请求里的head字段,设置*为全部
# 允许跨域的method, 默认为GET和OPTIONS,设置*为全部
# 跨域允许的有效期
allow-credentials: true
allowed-origins:
- "http://localhost:13009"
- "http://localhost:13010"
allowed-headers: "*"
allowed-methods:
- OPTIONS
- GET
- POST
- PUT
max-age: 3600
只支持配置的方式,不支持如下代码
@Slf4j
@Component
@Order(-100)
public class AuthGatewayFilter implements GatewayFilter