专栏首页用户1337634的专栏Spring Cloud Gateway快速体验

Spring Cloud Gateway快速体验

使用Spring Cloud Gateway作为API网关的一种实现,可以完成统一的权限校验、耗时统计、限流、计费等功能。类似功能产品有Zuul(Nginx也有点类似)

快速体验


添加依赖

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
    <version>2.1.1.RELEASE</version>
</dependency>

配置跳转

@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                //所有url都跳转到www.baidu.com
                .route(r -> r.path("/**")
                        .uri("https://www.baidu.com")
                )
                .build();
    }
}

访问体验

浏览器访问http://localhost:8080会显示百度首页内容

GlobalFilter


GlobalFilter只要注册到Spring容器,就可以应用在所有请求,比如监控请求耗时

定义全局Filter

  • ElapsedFilter.java
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Slf4j
@Component
public class ElapsedFilter implements GlobalFilter, Ordered {
    private static final String ELAPSED_TIME_BEGIN = "elapsedTimeBegin";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        exchange.getAttributes().put(ELAPSED_TIME_BEGIN, System.currentTimeMillis());
        return chain.filter(exchange).then(
                Mono.fromRunnable(() -> {
                    Long startTime = exchange.getAttribute(ELAPSED_TIME_BEGIN);
                    if (startTime != null) {
                        log.info(exchange.getRequest().getURI().getRawPath() + ": cost " + (System.currentTimeMillis() - startTime) + "ms");
                    }
                })
        );
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}

访问http://localhost:8080/index.html可以在日志中看到所有请求的耗时情况 ps: ElapsedFilter实现了GlobalFilter接口

GatewayFilter


有的Filter并不希望应用在所有的URL上,比如权限校验,有的URL需要用户登录之后,有的不需要登录。这个时候就要会用GatewayFilter,可以配置到不同route规则上

定义网关接口

  • AuthFilter.java
import com.google.gson.JsonObject;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;


@Component
public class AuthFilter implements GatewayFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getQueryParams().getFirst("authToken");
        //返回401状态码和提示信息
        if (StringUtils.isEmpty(token)) {
            ServerHttpResponse response = exchange.getResponse();
            JsonObject message = new JsonObject();
            message.addProperty("status", -1);
            message.addProperty("data", "鉴权失败");
            byte[] bits = message.toString().getBytes(StandardCharsets.UTF_8);
            DataBuffer buffer = response.bufferFactory().wrap(bits);
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            //指定编码,否则在浏览器中会中文乱码
            response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
            return response.writeWith(Mono.just(buffer));
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -100;
    }
}
  • GatewayApplication.java
@SpringBootApplication
public class GatewayApplication {

    @Resource
    private AuthFilter authFilter;

    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(r -> r.path("/**")
                        .filters(f -> f.filter(authFilter)
                                .addRequestParameter("name", "tenmao")
                        )
                        .uri("https://www.qq.com")
                )
                .build();
    }
}

参考

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=30f2rka7np444

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 设置Spring单元测试的外部依赖

    比如单元测试中依赖redis-mock,就必须在Spring上下文下载之前就先启动Redis Server,否则就会报下面的错误

    十毛
  • Feign统一设置header

    Feign可以通过实现接口feign.RequestInterceptor,完成对feign.RequestTemplate的修改,比如添加header

    十毛
  • 数据库一个字段保存多标志位

    十毛
  • SpringCloud 2.x学习笔记:15、Spring Cloud Gateway之Filter过滤器(Greenwich版本)

    AddRequestHeaderGatewayFilterFactory的源码

    程裕强
  • SpringBoot入门建站全系列(十七)整合ActiveMq(JMS类消息队列)

    消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下扩展进程间...

    品茗IT
  • Spring Batch之批处理实践

    Spring Batch 是Spring的子项目,基于Spring的批处理的框架,通过其可以构建出批量的批处理框架。

    mySoul
  • SpringBoot中实现拦截器级别的URl访问过快拦截,并利用JPA实现IP黑名单的功能。

    今天给大家介绍一下SpringBoot中实现拦截器级别URl过快访问拦截,并利用JPA实现IP黑名单的功能。 上一节中已经将中已经介绍了在控制器层面上面的URL...

    林老师带你学编程
  • rabbitMQ实现可靠消息投递 原

        RabbitMQ消息的可靠性主要包括两方面,一方面是通过实现消费的重试机制(通过@Retryable来实现重试,可以设置重试次数和重试频率,但是要保证幂...

    chinotan
  • 由浅入深,讲解 spring 实战详细使用——spring 源码篇

    首先,这篇文章不会详细的深入底层源码,只是基于注解和配置来说说我们的 spring 的使用,别小看基础,保证有你没用过的注解和配置,走起。

    淡定的蜗牛
  • 【SpringSecurity系列01】初识SpringSecurity

    ​ 用自己的话 简单介绍一下,Spring Security基于 Servlet 过滤器链的形式,为我们的web项目提供认证与授权服务。它来自于S...

    yukong

扫码关注云+社区

领取腾讯云代金券