首页 > 其他分享 >微服务-- Gateway服务网关

微服务-- Gateway服务网关

时间:2024-09-27 22:22:24浏览次数:8  
标签:网关 请求 -- gateway cloud 过滤器 Gateway 路由

Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等响应式编程和事件流技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。

为什么需要网关

在微服务架构中,网关(Gateway)作为统一入口,承担着多个关键角色。

核心功能特性

  • 请求路由:网关根据请求的路径、方法和其他参数,将请求路由到相应的微服务实例。这种集中管理的方式简化了客户端与多个微服务之间的交互。
  • 权限控制:网关可以实现用户身份验证和授权,确保只有经过授权的用户才能访问特定的服务。这提供了一个安全层,保护后端服务不受未授权访问。
  • 限流:为了防止系统过载,网关可以设置请求限制,以控制流量。例如,可以限制每秒的请求数量,确保服务的稳定性和可靠性。

架构图:

权限控制:

  • 网关负责校验用户请求的资格,确保只有经过身份验证和授权的用户才能访问特定的微服务。如果未授权,网关将拦截请求并返回相应的错误信息。

路由和负载均衡:

  • 所有请求都必须经过网关,网关根据预设的规则将请求转发到合适的微服务。这一过程称为路由。
  • 当多个服务实例可用时,网关还需要执行负载均衡,以分散流量并提高系统的可用性和响应速度。

限流:

  • 在高流量情况下,网关通过限制请求速率来保护后端服务,确保它们不会因过载而崩溃。这通常基于下游服务的处理能力进行调整,以平衡请求流量。

Spring Cloud中的网关实现

Zuul:

  • 类型:基于Servlet的阻塞式编程。
  • 特点:提供路由、负载均衡和过滤功能,但由于其阻塞特性,在高并发场景下可能会导致性能瓶颈。
  • 适用场景:适合简单的微服务应用,但在对性能要求较高的情况下可能不够理想。

Spring Cloud Gateway:

  • 类型:基于Spring 5中提供的WebFlux,响应式编程。
  • 特点:具备更好的性能,能够处理更多的并发请求,支持非阻塞IO。提供了更灵活的路由和过滤功能,并且集成了Spring生态中的其他组件。
  • 适用场景:适合需要高性能、高并发的微服务架构,是现代微服务应用的推荐选择。

gateway快速入门

第一步:添加依赖

        <!-- 不可以引入spring-boot-starter-web会有冲突 -->
        <!--网关-->
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-gateway -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <version>4.1.0</version>
        </dependency>

第二步:配置好注册中心[按照Eureka、zookeeper、nacos客户端配置即可]

第三步:编写properties

# 服务端口
server.port=8082

# 服务名称
spring.application.name=service2

# Nacos 服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

# 启用 Sentinel,并连接 Sentinel Dashboard
spring.cloud.sentinel.transport.dashboard=127.0.0.1:8080
spring.cloud.sentinel.transport.port=8720  # 本地 Sentinel 客户端的监控端口
# 启用 Sentinel
spring.cloud.sentinel.enabled=true

# 网关配置
# 定义路由的唯一标识符
spring.cloud.gateway.routes[0].id=route_to_service2
# 设置目标服务的URI
spring.cloud.gateway.routes[0].uri=http://localhost:8082
# 配置路由的断言,这里指定路径匹配规则
spring.cloud.gateway.routes[0].predicates[0]=Path=/service2/**

启动网关服务

然后可以通过访问如下 URL 来测试路由功能:

http://localhost:8082/service2/test

网关路由的流程图

整个访问的流程如下:

断言工厂

在 Spring Cloud Gateway 中,断言工厂(Predicate Factory)用于定义请求路由的条件。它们通过处理配置文件中的字符串,来决定哪些请求应该被转发到具体的服务。

常用断言工厂

名称说明示例
After匹配在某个时间点后的请求After=2037-01-20T17:42:47.789-07:00[America/Denver]
Before匹配在某个时间点之前的请求Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]
Between匹配在两个时间点之间的请求Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver]
Cookie请求必须包含某些 cookieCookie=chocolate, ch.p
Header请求必须包含某些 headerHeader=X-Request-Id, \d+
Host请求必须访问特定的 host(域名)Host=**.somehost.org,**.anotherhost.org
Method请求方式必须是指定方式Method=GET,POST
Path请求路径必须符合指定规则Path=/red/{segment},/blue/**
Query请求参数必须包含指定参数Query=name, Jack 或 Query=name
RemoteAddr请求者的 IP 必须在指定范围RemoteAddr=192.168.1.1/24
Weight权重处理

使用示例

以 Path 断言工厂为例,假设我们希望将所有访问 /user/** 的请求转发到某个服务,可以在 application.properties 文件中这样配置: 

spring.cloud.gateway.routes[0].id=user_route
spring.cloud.gateway.routes[0].uri=http://localhost:8080
spring.cloud.gateway.routes[0].predicates[0]=Path=/user/**

虽然有多种断言工厂可供使用,但熟悉 Path 断言工厂通常足以应对大多数路由需求。

过滤器工厂

GatewayFilter 是 Spring Cloud Gateway 提供的一种机制,用于处理进入网关的请求以及微服务返回的响应。

路由过滤器的种类

Spring 提供了多种路由过滤器工厂,常用的包括:

名称说明
AddRequestHeader给当前请求添加一个请求头
RemoveRequestHeader移除请求中的一个请求头
AddResponseHeader给响应结果中添加一个响应头
RemoveResponseHeader从响应结果中移除一个响应头
RequestRateLimiter限制请求流量

请求头过滤器示例

以 AddRequestHeader 为例,假设我们的需求是给所有进入 userservice 的请求添加一个请求头:Truth=Itcast is freaking awesome!。可以在 application.yml 文件中这样配置:

spring:
  cloud:
    gateway:
      routes:
      - id: user-service 
        uri: lb://userservice 
        predicates: 
        - Path=/user/** 
        filters: # 过滤器
        - AddRequestHeader=Truth, Itcast is freaking awesome! # 添加请求头

通过这种方式,该过滤器仅对访问 userservice 的请求生效。

默认过滤器

如果希望某个过滤器对所有路由都生效,可以将过滤器配置在 default-filters 下:

spring:
  cloud:
    gateway:
      routes:
      - id: user-service 
        uri: lb://userservice 
        predicates: 
        - Path=/user/**
      default-filters: # 默认过滤项
      - AddRequestHeader=Truth, Itcast is freaking awesome! 

总结

过滤器的作用是什么?

  • 对路由的请求或响应进行加工处理,例如添加请求头。
  • 配置在特定路由下的过滤器仅对该路由的请求生效。

default-filters 的作用是什么?

  • default-filters 中的过滤器会对所有路由生效。

全局过滤器

全局过滤器是 Spring Cloud Gateway 中的一种机制,用于对所有请求和响应进行统一的处理。与路由特定的过滤器不同,全局过滤器可以应用于网关中的所有路由,提供了一种集中管理请求和响应的方法。

全局过滤器作用

全局过滤器用于处理所有进入网关的请求和微服务响应,功能与GatewayFilter类似。不同之处在于GatewayFilter通过配置定义,其处理逻辑是固定的;而GlobalFilter的逻辑需要开发者自行编写代码实现。

实现方式是通过实现GlobalFilter接口:

public interface GlobalFilter {
    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

在filter方法中可以编写自定义逻辑,实现如下功能:

  • 登录状态判断
  • 权限校验
  • 请求限流等

自定义全局过滤器

需求

定义一个全局过滤器,拦截请求,判断请求参数是否符合以下条件:

  1. 参数中是否有authorization
  2. authorization参数值是否为admin
  3. 如果满足这两个条件,则放行;否则拦截请求。

实现

在网关中定义一个过滤器:

package cn.itcast.gateway.filters;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.获取请求参数
        MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
        // 2.获取authorization参数
        String auth = params.getFirst("authorization");
        // 3.校验
        if ("admin".equals(auth)) {
            // 放行
            return chain.filter(exchange);
        }
        // 4.拦截
        // 4.1.禁止访问,设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
        // 4.2.结束处理
        return exchange.getResponse().setComplete();
    }
}

过滤器执行顺序

请求进入网关后,会经过三类过滤器:

  1. 当前路由的过滤器
  2. DefaultFilter
  3. GlobalFilter

请求路由后,会将这些过滤器合并成一个过滤器链,并按照顺序依次执行。

排序规则

  • 每个过滤器必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前。
  • GlobalFilter通过实现Ordered接口或使用@Order注解来指定order值。
  • 路由过滤器和defaultFilter的order由Spring自动指定,默认按声明顺序递增。
  • 当多个过滤器的order值相同时,执行顺序为:defaultFilter > 路由过滤器 > GlobalFilter。

更多详细内容,可查看源码:

  • org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters()方法加载defaultFilters和路由的filters并进行合并。
  • org.springframework.cloud.gateway.handler.FilteringWebHandler#handle()方法加载全局过滤器,与前面的过滤器合并后根据order排序,组织过滤器链。

跨域问题

什么是跨域问题

跨域指的是在不同的域名、端口或协议之间进行请求。具体包括以下几种情况:

  • 域名不同:例如 www.taobao.com 与 www.taobao.org,以及 www.jd.com 和 miaosha.jd.com。
  • 端口不同:例如 localhost:8080 和 localhost:8081。
  • 协议不同:例如 http:// 与 https://。

跨域问题是指浏览器出于安全考虑,禁止发起来自不同域的 AJAX 请求,因此请求会被浏览器拦截。

解决方案:CORS(跨域资源共享),可以参考阮一峰的网络日志了解更多。

解决跨域问题

在 Gateway 服务的 application.yml 文件中,添加以下配置,以实现全局的跨域处理:

spring:
  cloud:
    gateway:
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 解决 OPTIONS 请求被拦截问题
        corsConfigurations:
          '[/**]': # 所有路径的跨域配置
            allowedOrigins: # 允许哪些网站的跨域请求 
              - "http://localhost:8090"
            allowedMethods: # 允许的跨域 AJAX 请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带 cookie
            maxAge: 360000 # 这次跨域检测的有效期

总结

通过配置 CORS,可以有效解决跨域请求的问题,使得不同源之间的 AJAX 请求能够顺利进行。

标签:网关,请求,--,gateway,cloud,过滤器,Gateway,路由
From: https://blog.csdn.net/m0_74293254/article/details/142543605

相关文章

  • python爬虫广州城市租房需求数据分析系统 可视化大屏分析系统xumld.
    目录项目介绍技术栈具体实现截图Scrapy爬虫框架关键技术和使用的工具环境等的说明解决的思路开发流程爬虫核心代码展示系统设计论文书写大纲详细视频演示源码获取项目介绍租房者模块账户管理:注册、登录、个人信息编辑、密码更改、账户注销。房源浏览:查看不同类型......
  • 计算机毕业设计python校园失物招领管理系统 gtvcz--vue+django pycharm
    目录python语言技术路线框架介绍具体实现截图技术栈和环境说明解决的思路性能/安全/负载方面核心代码部分展示详细视频演示源码获取方式python语言Python的扩展性也很好,其可以利用c语言编写模块,编译链接到解释器,从而使Python能够调用该c模块中的接口。反之,C语言也能......
  • Python基础04_Python字符串(下)&Python输入和输出&条件语句&循环语句&pass语句
    目录Python字符串(下)6、字符串的常用函数APIPython输入和输出1、输出 2、输入条件语句1.if2、if-else3、if-elif-else循环语句1、range函数2、for-in循环3、while循环4、循环控制break:用于 跳出 当前循环: continue:用于跳过当前迭代,继续下一次迭代:5、p......
  • MyBatis 动态语句
    一、if和where语句<!--List<Employee>selectEmployeeByCondition(Employeeemployee);--><selectid="selectEmployeeByCondition"resultType="employee">selectemp_id,emp_name,emp_salaryfromt_emp<!--where标签会......
  • 【C++基础知识——如何判断是注入依赖还是赋值?】
    问题template<typenameType,typenameEventlist,typenameEventlist,typenameRejectEventList,typenameQueuedEventHandler>classParallelProcedureQueueManager{explicitParallelProcedureQueueManager(Type&equipment,con......
  • 基于SpringBoot+Vue+uniapp的公考学习平台的详细设计和实现(源码+lw+部署文档+讲解等)
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言......
  • 自定义数据源实现读写分离
    说明:读写分离,指把数据库的操作分为读操作、写操作(更新、新增、删除),在多数据库实例(如主从结构)下,把读操作和写操作访问的数据库分开,以此缓解单数据库的压力。读写分离实现的前提,需要数据库之间能同步数据,数据不一致,读写分离没有意义。数据同步可参考下面文章:MySQL主从结构......
  • MATLAB疲劳检测系统
    MATLAB疲劳检测系统是一种基于MATLAB软件的系统,可以用于检测人体的疲劳程度。该系统利用MATLAB的信号处理工具和机器学习算法,通过分析人体生理信号(如心率、呼吸频率、皮肤电阻等)来判断一个人是否处于疲劳状态。该系统的工作流程通常包括以下几个步骤:数据采集:使用传感器等设......
  • HTML常用标签(第四课)
     清楚认识标签的语义,即标签的含义,以便在合适的地方写上合理的标签,让网页结构更加清晰目录一、标题标签二、段落标签三、换行标签​综合案例四、文本格式化标签五、div标签和span标签六、图像标签七、图片路径八、超链接标签九、注释标签十、特殊字符综合案例......
  • HTML表单相关知识(第七课)
    目录一、表单的初步认识二、组成部分1、表单域2、表单控件①input输入表单元素②select下拉表单元素③textarea文本域表单元素三、综合案例一、表单的初步认识作用:方便收集用户信息,让页面和用户实现交互组成部分:表单域、表单控件、提示信息二、组成部分1、表单......