gateway的简单运用
官网地址
https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/#gateway-starter
官网地址大家一定要去看,上面介绍了很多东西!如果怕都是英文,可以用谷歌的插件给翻译成中文,办法总比困难多。。。
是什么
Spring Cloud Gateway 是 Spring 官方基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,Spring Cloud Gateway 旨在为微服务架构提供一种简单而有效的统一的 API 路由管理方式。
怎么玩
首先在pom文件里引入gateway的包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
注意:这里在引入gateway的时候,不需要引入:spring-boot-starter-web包,不然会报错!
创建springboot启动类:
@SpringBootApplication
@EnableEurekaClient
public class SpringBootAppGateway9527 {
public static void main(String[] args) {
SpringApplication.run(SpringBootAppGateway9527.class,args);
}
}
创建application.yml
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
routes:
- id: payment_routh #路由的ID,没有固定规则但要求唯一,建议配合服务名
# uri: http://localhost:8001 #匹配后提供服务的路由地址
uri: lb://CLOUD-PROVIDER-PAYMENT #匹配后提供服务的路由地址
predicates:
- Path=/payment/** #断言,路径相匹配的进行路由
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由
eureka:
client:
# 是否将自己注册到eureka里
register-with-eureka: true
# false代表不需要去检索服务,因为自己就是维护服务,这里设置为true,是因为网关需要检索服务
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka
这里的eureka的配置就不在说了,都是基本操作,把gateway给注入到eureka里。主要说下gateway的配置。
spring.cloud.gateway.routes: 注意这里的routes是集合,学过springboot基础的同学,就会知道,在想list注入值的时候,是需要加入“-”的。
id:路由的ID,这里尽量不要重复;
uri: 前面的lb是LoadBalanced,意思就是开启负载均衡,而且后面的跟着的就是服务名称;
predicates:这个就是断言了,会根据路径相匹配,转发到相对应的服务上面。
添加自定义全局过滤器
首先我们需要实现GlobalFilter, Ordered接口,代码如下:
@Component
@Slf4j
public class MyGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
URI uri = request.getURI();
log.info("MyGlobalFilter过滤器:请求:{}进来了!", uri);
String token = request.getQueryParams().getFirst("token");
if (token==null){
// 如果请求参数里面没有包含token,那么这里就过滤请求,不让进入业务逻辑服务里
log.info("请求:{} token为null,未登录,请求被过滤", uri);
exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
// 过滤器执行的顺序,数字越小,执行越靠前
return 1;
}
}
代码解读:这里简单的做了一个对会话的验证,判断当前请求的参数用有没有token这个参数,如果没有token,则返回404状态码:HttpStatus.NOT_FOUND
测试
之前我们访问服务的时候都是直接访问http://服务ip地址:服务端口号,现在我们配置了网关,我们可以直接访问:http://网关ip地址:网关端口号,这样我们就不用在把服务的ip地址和端口号给暴露出来了,我们只需要暴露网关的地址就行,所有的请求都是走网关,让网关统一分配,进行调用。
启动:eureka 和两个微服务CLOUD-PROVIDER-PAYMENT,加上网关
在浏览器访问:
可以看见我们访问的接口是同一个,但是端口却是在变化的:ServerPort,说明我们的负载均衡也起到了作用。
当我们参数里没有token的情况:页面直接404了,说明我们的过滤器也起到了作用。