gatewawy网关
发表于2023-07-13|更新于2023-07-22
|阅读量:
Gateway网关组件
作用:解耦(解除客户端与微服务的耦合),方便微服务访问地址的维护,服务路由、负载均衡;身份认证和权限校验;请求限流;
网关也会被当成一个微服务注册在nacos上,网关会作为一个与客户端与各种服务的中间人,为客户端提供中转服务。在中转服务时可以做一些与本身业务功能无关的逻辑,比如认证、鉴权、监控、路由转发等等。
相同作用的一些技术对比:
●Nginx+lua脚本:使用nginx的反向代理和负载均衡可以实现对api服务器的负载均衡和高可用;lua脚本语言可以编写一些简单逻辑,具有原子性,完成某些操作。
●Kong : 基于Nginx+Lua开发,性能高,稳定,有多个可用的插件(限流、鉴权等等)可以开箱即用。
问题:只支持Http协议;二次开发,自由扩展困难;提供管理API,缺乏更易用的管控、配置方式。
●Zuul : Netflix开源的网关,功能丰富,使用JAVA开发,易于二次开发
问题:缺乏管控,无法动态配置;依赖组件较多;处理Http请求依赖的是Web容器,性能不如NginxSpring Cloud Gateway
●Gateway : Spring公司为了替换Zuul而开发的网关服务;设计优雅,容易扩展—–spring就是牛逼哈~
Getway配置详解:
1、引入依赖
1 2 3 4 5 6 7 8
| <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>
|
2、编写网关启动类
1 2 3 4 5 6 7
| @SpringBootApplication public class GatewayApplication {
public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); } }
|
3、编写路由配置及nacos地址的yml文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| spring: cloud: nacos: server-addr: localhost:80 gateway: routes: - id: user-service # 路由id 必填 不重复即可 uri: lb://userService # 路由目标地址 predicates: # 路由断言,判断请求是否符合规则 - 'Path=/user/**' # 判断路径是否以/user开头,如果是则符合 - id: order-service uri: lb://orderService predicates: - 'Path=/order/**' application: name: gateway
server: port: 10010
|
路由断言工厂
配置的路由断言是由断言工厂解析的,我们配置的是字符串,路由工厂则取解析
eg
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| spring: cloud: nacos: server-addr: localhost:80 gateway: routes: - id: user-service # 路由id 必填 不重复即可 uri: lb://userService # 路由目标地址 predicates: # 路由断言,判断请求是否符合规则 - 'Path=/user/**' # 判断路径是否以/user开头,如果是则符合 - id: order-service uri: lb://orderService predicates: - 'Path=/order/**' - After=2023-01-14T23:38:47.789+08:00[Asia/Shanghai] application: name: gateway
server: port: 10010
|
过滤器工厂
作用:可以对进入网关的请求和服务的响应作处理。
spring大哥到目前位置提供了37中不同的路由器过滤器工厂,不明白可以去读文档
编写配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| spring: cloud: nacos: server-addr: localhost:80 gateway: routes: - id: user-service # 路由id 必填 不重复即可 uri: lb://userService # 路由目标地址 predicates: # 路由断言,判断请求是否符合规则 - 'Path=/user/**' # 判断路径是否以/user开头,如果是则符合 filters: - AddRequestHeader=IHeader,this is filter - id: order-service uri: lb://orderService predicates: - 'Path=/order/**' - After=2023-01-14T23:40:00+08:00[Asia/Shanghai] application: name: gateway
server: port: 10010
|
修改代码,演示展现
1 2 3 4 5 6 7
| @GetMapping("/{id}") public User queryById(@PathVariable("id") Long id, @RequestHeader(value = "IHeader", required = false) String IHeader) { System.out.println(IHeader); return userService.queryById(id);
}
|
访问user-service的接口即可看到打印 this is filter
这里展示的是默认过滤器,默认过滤器对所有请求都生效
●全局配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| spring: cloud: nacos: server-addr: localhost:80 gateway: routes: - id: user-service # 路由id 必填 不重复即可 uri: lb://userService # 路由目标地址 predicates: # 路由断言,判断请求是否符合规则 - 'Path=/user/**' # 判断路径是否以/user开头,如果是则符合 - id: order-service uri: lb://orderService predicates: - 'Path=/order/**' - After=2023-01-14T23:40:00+08:00[Asia/Shanghai] default-filters: - AddRequestHeader=IHeader,this is filter application: name: gateway
server: port: 10010
|
访问user-service的接口即可看到打印 this is filter
全局过滤
实现:实现GlobalFilter接口即可
区别:和全局配置过滤器作用相同,GatewayFilter通过配置定义,处理逻辑是固定的。而GlobalFiter的逻辑需要自己写代码实现。
1 2 3 4 5 6
| public class IFilter implements GlobalFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { return null; } }
|
eg
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| // 过滤器链上的优先级 越低优先级越高 @Order(-1) @Component public class IFilter implements GlobalFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 1.获取请求参数 ServerHttpRequest request = exchange.getRequest(); MultiValueMap<String, String> queryParams = request.getQueryParams(); // 2.获取某个参数 String auth = queryParams.getFirst("username"); // 3.业务 if ("admin".equals(auth)) { // 放行 return chain.filter(exchange); } // 修改返回状态码 exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); // 拦截 return exchange.getResponse().setComplete(); } }
|
注解@Order(-1)指明过滤器的执行顺序
@Component导入ioc容器
过滤器执行顺序
不管是yml中配置的filters、default-filters还是GlobalFilter,其本质都是GatewayFilter。所以他们的执行顺序是由他们的order值决定,他们的order值有以下规则:路由过滤器和默认过滤器的order由spring指定,默认是按照声明顺序从1递增。GlobalFilter的Order值由我们决定
当过滤器的order值相同时,会按照defaultFilter > 路由过滤器 > GlobalFliter的顺序执行