SpringCloud搭建微服务之Gateway网关

1. 概述

Gateway是在Spring生态系统之上构建的API网关服务,旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能,基于WebFlux框架实现,而WebFlux框架底层又使用了高性能的Reactor模式通信框架Netty。常用功能有反向代理、鉴权、流量控制、熔断和日志监控

1.1. Gateway特性

  1. 动态路由:能够匹配任何请求属性
  2. 可以对路由指定Predicate(断言)和Filter(过滤器),且易于编写
  3. 集成Hystrix断路器功能
  4. 集成Spring Cloud服务发现功能
  5. 请求限流功能
  6. 支持路径重写

1.2. 核心概念

Route(路由)
是构建网关的基本模块,由ID、目标URI、一系列断言和过滤器组成,断言为true时匹配该路由
Predicate(断言)
请求与断言相匹配则进行路由
Filter(过滤)
可以在请求被路由前或之后对请求进行修改

1.3. Gateway网关请求流程

  1. 客户端向Gateway发出请求,然后在Gateway Handler Mapping中找到与请求相匹配的路由,将其发送到Gateway Web Handler
  2. Handler再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回
  3. 过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(pre)或之后(post)执行业务逻辑
  4. Filter在pre类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换
  5. 在post类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等

流程图如下
gateway流程图

2. 搭建Gateway网关服务

2.1. 引入核心依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

2.2. 编写application.yml配置文件

server:
  port: 8812
spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
        - id: provider_routh
          uri: http://localhost:8770
          predicates:
            - Path=/provider/getProviderInfo/**

2.3. 编写主启动类

@SpringBootApplication
public class GatewayApplication {

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

2.4. 验证

依次启动Eureka Server、Provider和Gateway三个微服务,在浏览器输入地址http://localhost:8812/provider/getProviderInfo/world
网关访问

2.5. 代码配置网关

新建一个GatewayConfig类

@Configuration
public class GatewayConfig {

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        RouteLocatorBuilder.Builder routes = builder.routes();
        routes.route("provider_routh", predicate -> predicate.path("/provider/getProviderConfigInfo/**")
                .uri("http://localhost:8770")).build();
        return routes.build();
    }
}

再次启动Gateway服务,在浏览器地址输入http://localhost:8812/provider/getProviderConfigInfo/zhangsan就可以直接跳转到百度新闻网
配置类实现跳转

3. 通过微服务名称实现动态路由

默认情况下Gateway会根据注册中心注册的服务列表, 以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能

3.1. 引入Eureka Client依赖

<dependency>
   <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

3.2. 修改application.yml

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: provider_routh
          uri: lb://CLOUD-PROVIDER #匹配后提供服务的路由地址
          predicates:
            - Path=/provider/getProviderInfo/**

3.3. 验证

在浏览器地址栏输入http://localhost:8812/provider/getProviderInfo/zhangsan
动态路由匹配

4. Route Predicate

Spring Cloud Gateway包括许多内置的Route Predicate工厂,所有这些Predicate都与HTTP请求的不同属性匹配,多个Route Predicate工厂可以进行组合,常见的如下:

4.1. After Route Predicate

指定日期(ZonedDateTime)之后才能访问请求路径

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: provider_routh
          uri: lb://CLOUD-PROVIDER #匹配后提供服务的路由地址
          predicates:
            - After=2022-09-07T17:42:47.789+08:00[Asia/Shanghai]

4.2. Before Route Predicate

指定日期(ZonedDateTime)之前才能访问请求路径

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: provider_routh
          uri: lb://CLOUD-PROVIDER #匹配后提供服务的路由地址
          predicates:
            - Before=2022-09-08T17:42:47.789+08:00[Asia/Shanghai]

4.3. Between Route Predicate

指定日期(ZonedDateTime)之间才能访问请求路径

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: provider_routh
          uri: lb://CLOUD-PROVIDER #匹配后提供服务的路由地址
          predicates:
            - Between=2022-09-07T17:42:47.789+08:00[Asia/Shanghai], 2022-09-08T17:42:47.789+08:00[Asia/Shanghai]

4.4. Cookie Route Predicate

通过获取对应的 Cookie name 值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: provider_routh
          uri: lb://CLOUD-PROVIDER #匹配后提供服务的路由地址
          predicates:
            - Cookie=username, zhangsan

4.5. Header Route Predicate

请求中必须带有消息头,且要匹配名称和值

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: provider_routh
          uri: lb://CLOUD-PROVIDER #匹配后提供服务的路由地址
          predicates:
            - Header=X-Request-Id, \d+

4.6. Host Route Predicate

一组匹配的域名列表,用.号作为分隔符,通过参数中的主机地址作为匹配规则

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: provider_routh
          uri: lb://CLOUD-PROVIDER #匹配后提供服务的路由地址
          predicates:
            - Host=**.xlhj.org,**.xlhj.com

4.7. Method Route Predicate

HTTP请求方式进行匹配POST/GET

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: provider_routh
          uri: lb://CLOUD-PROVIDER #匹配后提供服务的路由地址
          predicates:
            - Method=GET,POST

4.8. Path Route Predicate

请求路径进行匹配

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: provider_routh
          uri: lb://CLOUD-PROVIDER #匹配后提供服务的路由地址
          predicates:
            - Path=/provider/getProviderInfo/**

4.9. Query Route Predicate

查询条件匹配,一个参数时,表示请求参数中必须包含此值;两个参数时,表示请求参数中包含此值,参数值匹配第二个参数

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: provider_routh
          uri: lb://CLOUD-PROVIDER #匹配后提供服务的路由地址
          predicates:
            - Query=username, zhangsan

4.10. RemoteAddr Route Predicate

IP地址进行匹配

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: provider_routh
          uri: lb://CLOUD-PROVIDER #匹配后提供服务的路由地址
          predicates:
            - RemoteAddr=192.168.1.1/24

4.11. Weight Route Predicate

权重进行匹配

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: provider_routh
          uri: lb://CLOUD-PROVIDER #匹配后提供服务的路由地址
          predicates:
            - Weight=group1, 2
        - id: order_routh
          uri: http://localhost:8770
          predicates:
            - Weight=group1, 8

20%请求走上面服务,80%请求走下面服务

5. 过滤器Filter

用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用,主要有两类,即GatewayFilter和GlobalFilter

5.1. 常用过滤器

AddRequestHeader:请求头过滤器

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: provider_routh
          uri: lb://CLOUD-PROVIDER #匹配后提供服务的路由地址
          predicates:
            - Path=/provider/getProviderInfo/**
          filters:
            - AddRequestHeader=X-Request-Id, xlhj

AddRequestParameter:请求参数过滤器

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: provider_routh
          uri: lb://CLOUD-PROVIDER #匹配后提供服务的路由地址
          predicates:
            - Path=/provider/getProviderInfo/**
          filters:
            - AddRequestParameter=X-Request-Id, xlhj

其他过滤器用法都差不多

5.2. 自定义过滤器

自定义全局过滤器需要实现GlobalFilter和Ordered两个接口,常用语全局日志记录和统一权限认证,新建一个GatewayGlobalFilter类,代码如下:

@Component
public class GatewayGlobalFilter implements GlobalFilter, Ordered {

    private static final Logger logger = LoggerFactory.getLogger(GatewayGlobalFilter.class);

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        logger.info("执行自定义全局过滤器");
        String requestId = exchange.getRequest().getQueryParams().getFirst("X-Request-Id");
        if (StringUtils.isBlank(requestId)) {
            logger.info("请求参数为空!");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

5.3. 验证

重新启动gateway微服务,浏览器地址栏输入http://localhost:8812/provider/getProviderInfo/world?X-Request-Id=xlhj
过滤器验证

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用Spring Cloud搭建微服务登录,你可以按照以下步骤进行操作: 1. 创建认证服务:首先,你需要创建一个认证服务,用于处理用户的登录和身份验证。你可以使用Spring Security来实现用户认证和授权功能。在认证服务中,你可以定义用户账号、密码以及角色等信息。 2. 配置认证服务:在认证服务中,你需要配置Spring Security来定义登录接口、认证规则和权限控制等。可以使用基于用户名密码的登录方式,也可以使用其他方式,如OAuth2.0等。确保你的认证服务能够正确验证用户的身份,并返回相应的访问令牌。 3. 创建其他微服务:除了认证服务外,你还需要创建其他的微服务,用于提供不同的业务功能。这些微服务可以是独立的应用程序,通过Spring Cloud注册到服务注册中心,并与认证服务进行通信。 4. 集成认证服务:在其他微服务中,你需要集成认证服务,以便验证用户的访问权限。可以通过在请求头中携带访问令牌,并在微服务中进行校验来实现。使用Spring Security OAuth2或者JWT等技术来实现令牌的生成与验证。 5. 配置路由和网关:为了统一管理和保护微服务,你可以使用Spring Cloud Gateway或Zuul等网关技术来配置路由和访问控制规则。通过网关,你可以对外暴露统一的登录接口,并在用户登录成功后将请求转发到相应的微服务。 6. 前端集成:最后,你需要在前端应用中集成登录功能。前端应用可以使用Spring Boot、React、Angular或Vue等框架进行开发。通过调用登录接口获取访问令牌,并在后续的请求中携带令牌进行访问控制。 总结来说,使用Spring Cloud搭建微服务登录需要创建认证服务、配置认证规则和权限控制、集成认证服务到其他微服务、配置路由和网关以及前端集成等步骤。这样可以实现用户的登录和访问权限控制。希望以上信息对你有所帮助!如果有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值