Gateway
网关其实可以理解成一个转发器,请求和响应都需要经过网关的处理
搭建
创建新模块并且引入依赖,创建启动类
注意引入依赖需要引入Feign和gateway两个依赖,因为gateway本身也是要被nacos托管的服务
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
增加配置文件,注意配置文件的/斜杠都是坑,这里需要好好看
server:
port: 10010
spring:
application:
name: gateway
cloud:
nacos:
server-addr: localhost:80
gateway:
routes: #网关路由
- id: userservice
# uri: lb://userservice //这里服务名不需要增加
uri: http://192.168.79.1:8081/ # //端口号后必须加
predicates:
- Path=/user/** #路径的前面必须加/
- id: orderservice
uri: lb://orderservice
predicates:
- Path=/order/** #路径的前面必须加/
此外如果遇到403或者503,可以去考虑是否是过滤器或者负载均衡的问题,新版本可能需要去引入负载均衡的依赖
断言工厂
实际上就是predicate工厂
直接选择直接在类似-id的类似的操作,功能路由的判断很齐全
作用就是路由工厂读取用户配置的断言规则,然后解析成条件将来用条件进行路由进行判断
网关过滤器
Filter
这个不仅对微服务的请求和相应都会进行处理
作用其实就是FilterFactory的添加,那么去spring官网直接找就行了,相比网关,它过滤的操作反而能够添加减少请求头请求体参数等操作,过滤器更像是一个加工厂,修改网关配置文件
routes: #网关路由
- id: userservice
uri: lb://userservice
predicates:
- Path=/user/**
filters:
- AddRequestHeader=Say,fuck! #用,表示属性和值
后面在里面验证
@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id,
@RequestHeader(value = "Say",required = false) String s) {
System.out.println(s);
return userService.queryById(id);
}
在分别用端口和网关的访问
GlobalFilter
全局过滤器,只需要去是实现GlobalFilter接口
@Order(-1) //过滤器的优先级,越小越优选,-1最小,话可以实现ordered接口
@Component //过滤类组件化
public class AuthorizeFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 这里面的exhange就是上下文,可以求获取请求和响应,chain是过滤链,通过这个可以给传递给下个过滤器
// 设置请求参数的role=admin成立
ServerHttpRequest request = exchange.getRequest();
//获取参数map
MultiValueMap<String, String> queryParams = request.getQueryParams();
//获取map如果是kv那就获取GetFirst,如果list就get
String auth = queryParams.getFirst("role");
if(auth != null||auth.equals("admin")){
//把exchange传给下一个
return chain.filter(exchange);
}
//获取响应并且设置响应码
exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
//结束响应
return exchange.getResponse().setComplete();
}
}
只有正确输入才能进去
路由过滤器和defaultFilter的order都是由spring指定,按照声明顺序从1开始递增,当过滤器的order一样,优先级:
defaultFilter > 路由过滤器 > GlobalFilter
原理在底层spring会先去加载defaultFilters,然后再去加载路由配置的filters,按照order进行第一次合并,然后加载全局过滤器,与前面的过滤器第二次按照order进行排序,从而组织过滤器链。
网关跨域
解决跨域问题不再赘述就是去解决CORS的问题,网关在底层已经做好,只需要直接进行配置文件继续,当然也可以去写配置类@Crossorgin
spring:
cloud:
gateway:
globalcors: # 全局的跨域处理
add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
corsConfigurations:
'[/**]':
allowedOrigins: # 允许哪些网站的跨域请求
- "http://localhost:8090"
- "http://www.leyou.com"
allowedMethods: # 允许的跨域ajax的请求方式
- "GET"
- "POST"
- "DELETE"
- "PUT"
- "OPTIONS"
allowedHeaders: "*" # 允许在请求中携带的头信息
allowCredentials: true # 是否允许携带cookie
maxAge: 360000 # 这次跨域检测的有效期
踩坑:
如果配置文件写的和前端发送数据的请求的url需要一样,无论localhost和127.0.0.1
如果nginx端口是80就直接写http://localhost不加端口号,后面需要再去找相应方法