SpringCloudAlibaba之gateway网关(九)

本文详细介绍了SpringCloudGateway的工作原理,包括路由、断言(Predicate)和过滤器(Filter)的配置。展示了如何通过YAML配置路由规则,并通过全局过滤器实现权限验证,防止用户直接访问微服务。此外,还提供了微服务间通过网关进行安全交互的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

Spring Cloud Gateway旨在提供一种简单而有效的方式来路由到API,并为它们提供跨领域的关注点,例如:安全性、监控/度量和弹性。

Spring Cloud Gateway构建在Spring Boot 2.x、 Spring WebFlux和Project Reactor。因此,当您使用Spring Cloud Gateway时,许多您熟悉库(例如Spring Data and Spring Security)和模式可能不需使用。

Spring Cloud Gateway需要Spring Boot和Spring Webflux提供的Netty运行时。它不能在传统的Servlet容器中工作,也不能在构建为WAR时工作。

概念

Route(路由): 网关的基本构造块。它由一个ID、一个目标URI、一组断言和一组过滤器定义。如果断言为true,则匹配路由。

Predicate(断言): 一个Java8功能断言。 输出类型是Spring Framework ServerWebExchange。 你可以匹配任何来HTTP请求, 例如headers和参数.

Filter(过滤器):这里有很多factory构建GatewayFilter类。你可以在发送到下游请求之前或者之后修改请求和返回。

如何工作

下图对Spring Cloud Gateway工作进行了一个概述:

 Clients向Spring Cloud Gateway发出请求。如果Gateway Handler Mapping检测到一个请求匹配路由,请求将被发送给Gateway Web Handler。Handler通过Filter处理请求。Filter被虚线分隔的原因是,Filter可以在代理请求发送之前和之后运行。先执行发送之前处理,然后Proxy Filter再运行,最后执行发送之后的处理。

配置Predicate Factories和Filter Factories

有两种方法可以配置Predicate和Filter快捷方式和完全参数。下面的大多数示例都使用快捷方式。

完整参数

完整参数更显是一个标准的yaml配置包含名称和值。通常,有name键和args键。args键是键-值的map配置Predicate和Filter。

application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - name: Cookie
          args:
            name: mycookie
            regexp: mycookievalue

快捷方式

快捷方式配置由Predicate名称、等号(=)和逗号(,)分隔的参数值识别。

 application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - Cookie=mycookie,mycookievalue

RoutePredicateFactory

RoutePredicateFactories包含了11种配置,具体怎么配置不一一说明了,这里只讲述下支持那些配置。

GatewayFilterFactory

支持23种方式,由于太多,将不一一列举。

由于篇幅原因,RoutePredicateFactory和GatewayFilterFactory使用方式未一一列举,这里

链接,方便用到是查看样例。

Spring Cloud Gatewayhttps://cloud.spring.io/spring-cloud-gateway/reference/html/#gatewayfilter-factories

快速使用

创建名称为gateway的module,pom.xml配置:

<!--引入nacos client的依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- gateway 网关依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

application.yml配置

server:
  port: 7007
spring:
  application:
    name: GATEWAY
  cloud:
    nacos:
      discovery:
        namespace: ec6004af-f122-4ed1-b6d6-5d77ea5d5c94
        server-addr: 192.168.43.85:8845,192.168.43.229:8846,192.168.43.251:8847
    gateway:
      routes:
        - id: myRoute
          uri: lb://USERS
          predicates:
            - Path=/service-order/**
          filters:
            - StripPrefix=1

uri中使用lb://USERS,其中lb表示使用nacos中心注册的服务名,这样就不需知道微服务的地址和端口,只需知道其他注册到nacos的服务名称就可以了。

path对service-order路径下所有请求进行拦截访问,访问名称为USERS的微服务。即http://USERS/service-order/**。

StripPrefix表示去掉一程路径,即变成了http://USERS/**。

简单的说就是方位http://网关:7007//service-order/**,最后被反射代理去访问了http://USERS/**目标地址。其中USERS是对应微服务的访问IP+端口。

问题

这里有一个问题,也是常见的问题,就是我们所有的服务都可以访问网关,也可以直接访问目标微服务,那如何屏蔽用户直接访问目标微服务呢?

有两种办法,

1、服务器层次更改,直接屏蔽其他微服务端口,对外不提供方位,只应许内部访问,对外只提供网关端口。(推荐使用这种方式)

2、代码层次,使用网关,对所有经过网关请求进行拦截,请求头添加参数,每个微服务进度请求进行拦截,去解析请求是否存在该参数,无这是为非法入侵请求。

网关拦截代码

package com.juwusheng.gateway;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @author lhq
 * @date 2022年04月07日 下午5:37
 */
@Configuration
public class TokenFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        /**
         * 可增加令牌等相关信息进行校验
         * 这里创建一个令牌,设置有效期,缓存到redis数据库上,
         * 实际调用的微服务端去redis查看是否有相关令牌
         */
        ServerHttpRequest req = exchange.getRequest().mutate()
                .header("from", "gateway").build();
        return chain.filter(exchange.mutate().request(req.mutate().build()).build());

    }
}

每个微服务对应的拦截

package com.juwusheng.products;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author lhq
 * @date 2022年04月07日 下午5:59
 */
@EnableWebMvc
@Configuration
public class InterceptorConfigure implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(new GlobalInterceptor());
    }
}
package com.juwusheng.products;

import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

/**
 * @author lhq
 * @date 2022年04月07日 下午5:43
 */
@Component
public class GlobalInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String secretKey = request.getHeader("from");

        if(StringUtils.hasText(secretKey)||secretKey.equals("gateway")){
            response.setContentType("application/json; charset=utf-8");
            PrintWriter writer = response.getWriter();
            writer.write("error");
            return false;
        }
        return true;
    }
}

<think>嗯,用户问的是关于Spring Cloud Alibaba整合Gateway的介绍。首先,我需要确定用户对这两个组件的了解程度。可能他们有一定的Spring Cloud基础,但可能不太清楚如何将Spring Cloud Alibaba和Gateway结合起来使用。所以,我需要先简要介绍这两个组件,然后说明整合的必要性和步骤。 首先,Spring Cloud Alibaba是阿里巴巴提供的微服务解决方案,包含Nacos、Sentinel等组件,用于服务发现、配置管理、限流等。而Spring Cloud GatewaySpring官方提供的API网关,负责路由、过滤、负载均衡等。整合它们可以构建一个完整的微服务架构。 接下来,用户可能需要具体的整合步骤。我应该分步骤说明,比如创建项目、添加依赖、配置Nacos和Gateway的路由规则,以及如何集成Sentinel进行限流。要注意依赖版本之间的兼容性,比如Spring Boot、Spring CloudSpring Cloud Alibaba的版本对应,这是容易出错的地方,需要提醒用户注意。 然后,考虑用户可能的实际应用场景,比如动态路由配置,这时候需要提到Nacos作为配置中心,动态更新路由规则。另外,整合Sentinel做网关限流也是一个常见需求,应该给出示例配置。 还要注意可能的常见问题,比如依赖冲突、配置错误等,可以给出一些排查建议,比如检查版本是否匹配,配置文件是否正确,以及如何通过日志调试。 用户可能有不同的使用场景,比如是否需要服务注册发现,或者只是用配置中心。因此,在整合步骤中需要明确说明如何注册到Nacos,并确保服务发现的功能正常。 最后,是否需要代码示例?可能需要提供一个简单的application.yml配置示例,说明路由规则和Nacos的配置,以及Sentinel的集成部分。这样用户可以直接参考示例进行配置,减少出错的可能。 总结下来,回答的结构应该是先介绍两者,再说明整合的好处,然后详细步骤,包括依赖配置、路由设置、动态配置和限流整合,最后给出注意事项和常见问题解决方法。同时,确保语言简洁明了,避免过于技术化的术语,让不同层次的用户都能理解。</think>Spring Cloud Alibaba 与 Spring Cloud Gateway 整合可以构建一个功能完善的微服务网关,结合阿里巴巴生态组件(如 Nacos、Sentinel)实现动态路由、流量控制和服务治理。以下是整合的核心要点和步骤: --- ### **1. 核心组件作用** - **Spring Cloud Gateway**:API 网关,负责路由转发、鉴权、限流、熔断等。 - **Nacos**:服务注册与配置中心,实现服务发现和动态路由配置。 - **Sentinel**:流量控制与熔断降级,保护网关和后端服务。 --- ### **2. 整合步骤** #### **2.1 创建项目并添加依赖** 在 `pom.xml` 中添加关键依赖: ```xml <!-- Spring Cloud Alibaba 基础依赖 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!-- Spring Cloud Gateway --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> ``` #### **2.2 配置文件(application.yml)** 配置 Nacos 服务发现和 Gateway 路由: ```yaml server: port: 8080 spring: application: name: api-gateway cloud: nacos: discovery: server-addr: localhost:8848 # Nacos 地址 gateway: discovery: locator: enabled: true # 开启服务发现路由 routes: - id: user-service uri: lb://user-service # 负载均衡到 user-service predicates: - Path=/user/** # 匹配路径 filters: - StripPrefix=1 # 去掉前缀 /user sentinel: transport: dashboard: localhost:8080 # Sentinel 控制台地址 ``` --- ### **3. 动态路由与 Nacos 整合** 通过 Nacos 配置中心动态更新路由规则: 1. 在 Nacos 控制台创建 `Data ID` 为 `gateway-routes.json` 的配置文件。 2. 配置内容示例: ```json [ { "id": "order-service", "predicates": [{"name": "Path", "args": {"pattern": "/order/**"}}], "filters": [{"name": "StripPrefix", "args": {"parts": 1}}], "uri": "lb://order-service", "order": 0 } ] ``` 3. 在 Gateway 中启用 Nacos 动态路由: ```java @Bean public NacosRouteDefinitionRepository nacosRouteDefinitionRepository() { return new NacosRouteDefinitionRepository(); } ``` --- ### **4. 整合 Sentinel 实现网关限流** 配置 Sentinel 对网关流量进行控制: 1. **添加依赖**: ```xml <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId> </dependency> ``` 2. **在 Sentinel 控制台配置流控规则**: - 针对路由 ID(如 `user-service`)设置 QPS 阈值。 3. **自定义限流异常响应**: ```java @Bean public GatewayCallbackManager sentinelGatewayCallbackManager() { GatewayCallbackManager.setBlockHandler((exchange, ex) -> { return ServerResponse.status(429) .body(BodyInserters.fromValue("Too many requests!")); }); return new GatewayCallbackManager(); } ``` --- ### **5. 注意事项** 1. **版本兼容性**:确保 Spring Boot、Spring CloudSpring Cloud Alibaba 版本匹配(例如:Spring Boot 2.6.x + Spring Cloud 2021.x + Spring Cloud Alibaba 2021.0.5.0)。 2. **路由优先级**:通过 `order` 字段控制路由匹配顺序。 3. **过滤器链**:可自定义全局过滤器(GlobalFilter)实现鉴权、日志等逻辑。 --- ### **6. 总结** 通过整合 Spring Cloud Alibaba 和 Gateway,可以实现: - **动态路由**:基于 Nacos 实时更新路由规则。 - **流量治理**:通过 Sentinel 实现网关级限流和熔断。 - **服务发现**:自动发现后端微服务实例。 此方案适合需要高可用、动态扩展的微服务架构,典型场景如电商秒杀、API 开放平台等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值