什么是网关
网关统一服务入口,可方便实现对平台众多服务接口进行管控
网关的作用
- 网关统一所有微服务入口
- 网关可以实现请求路由转发(router dispatcher)以及请求过程负载均衡
- 访问服务的身份认证、防报文重放和防数据篡改、功能调用的业务鉴权、相应数据的脱敏、流量与并发控制,甚至基于API调用计量或者计费等。
GateWay
GateWay是Spring团队开发的网关组件。
主要的作用:动态路由,服务统一管理,请求过滤
GateWay = 路由转发(router)+请求过滤(filter)
GateWay网关使用
1、首先在父项目中创建一个SprinBoot项目
注意:因为GateWay使用的WebFlux 一步非阻塞IO模型,所以如果使用SpringMvc会发生冲突,所以不要引入SpringWeb依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
|
2、创建完一个SpringBoot应用之后我们要去配置文件(注意缩进)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| server: port: 9797 spring: application: name: GATEWAY cloud: consul: port: 8500 host: localhost gateway: routes: - id: category_router uri: http://localhost:8787 predicates: - Path=/category - id: product_router uri: http://localhost:8686 predicates: - Path=/product
|
Java代码配置网关
这个就很简单了,就是简单的写一个配置类(Java代码中代码的优先级高于配置文件)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
@Configuration public class GateWayConfig { @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder){ return builder.routes() .route("category_routor",r-> r.path("/category").uri("http://localhost:8787")) .route("proudct_route",predicateSpec -> predicateSpec.path("/product").uri("http://localhost:8686")) .build(); } }
|
GateWay解析规则
有的小伙伴可能对路径的解析比较迷惑,下面简单说一下
Gate是根据配置文件中predicates
去匹配地址栏比如
localhost:9797/category
GateWay获取配置文件匹配category
在这个我就用了一个特殊的例子,两个的地址一样咋办?这个GateWay会默认第一个,哎,就是这么随意。在实际开发中要是写出这么不规范的接口路径,个人建议:提桶跑路,我们一般在@RequestMapping("/接口标识符")
来区分接口。
网关在路由转发时实现请求负载均衡
上面说了不同服务路径重名可以用服务名来区分,那么在据集群中呢怎么分辨呢,这个可是服务名都是一样的,这样在uri中直接写死为服务的某一个节点,这样是无法实现负载均衡的。
配置负载均衡
1 2 3 4 5 6 7 8 9 10 11
| routes: - id: category_router uri: lb://CATEGORY predicates: - Path=/category/** - id: product_router uri: lb://PRODUCT predicates: - Path=/product/**
|
改写uri中路径的写法:lb://CATEGORY
lb是负载均衡的意思,后面跟着的服务在注册中心注册的服务名称
由此可以看出GateWay也是集成了Ribbon组件
网关的断言(predicate)和过滤(filter)
Gateway Handler Mapping和GateWebHandler组成了断言(predicate)下面的一系列组成了(filter)
网关 GateWay = 断言 + 过滤
断言的使用(Route Predicate Factories)
SpringCloud给我们内置了许多的Predicate
1 2 3 4 5 6 7 8
| - Path=/category/** - After=2017-01-20T17:42:47.789-07:00[America/Denver] - Before=2017-01-20T17:42:47.789-07:00[America/Denver] - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver] - Cookie=chocolate, ch.p - Cookie=chocolate,[A-Za-z0-9] - Header=X-Request-Id, \d+ - Method=GET,POST
|
搭配文档食用更香
filter的使用
同样SpringCloud内置了许多的filter,同样filter的使用是需要在配置中添加filters:
1 2 3 4 5 6 7 8 9
| filters: - AddRequestHeader=key, value - AddRequestParameter=参数名, 参数值 - AddResponseHeader=key, value - PrefixPath=/mypath -StripPrefix=n
|
这里只是比较常用的过滤器,搭配文档食用更香
自定义全局Filter
当然如果没有什么特殊要求,为了方便我们还可以自动全局filter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
@Configuration public class GlobalGateWayFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); System.out.println("经过全局Filter处理"); Mono<Void> filter = chain.filter(exchange); System.out.println("响应回来Filter处理"); return filter; }
@Override public int getOrder() { return -1; } }
|
通过web查看路由详情规则
http://localhost:7979/actuator/gateway/routes
在配置文件中配置
1 2 3 4 5
| management: endpoints: web: exposure: include: "*"
|