首页 > 其他分享 >Gateway网关

Gateway网关

时间:2023-12-28 16:47:18浏览次数:30  
标签:网关 服务 请求 gateway 过滤器 Gateway 路由

目录


1、微服务网关的基本介绍

不同的微服务一般会有不同的网络地址,客户端在访问这些微服务时必须记住几十甚至几百个地址,这对于客户端方来说太复杂也难以维护,如果让客户端直接与各个微服务通讯,可能会有很多问题:

  1. 客户端会请求多个不同的服务,需要维护不同的请求地址,增加开发难度
  2. 在某些场景下存在跨域请求的问题
  3. 加大身份认证的难度,每个微服务需要独立认证

因此,我们需要一个微服务网关,介于客户端与服务器之间的中间层。所有的外部请求都会先经过微服务网关,客户端只需要与网关交互,只知道一个网关地址即可。

网关是介于客户端和服务器端之间的中间层,所有的外部请求都会先经过网关这一层。也就是说,API 的实现方更多地只需要考虑业务逻辑,而安全、性能、监控可以交由网关来完成,这样既提高业务灵活性又不缺安全性。

微服务网关是一个服务器,是系统对外的唯一入口。网关封装了系统内部架构,为外部客户端提供一个定制的 API。API 网关方式的核心要点是,所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。通常,网关也是提供REST/HTTP 的访问 API。服务端通过 API-GW 注册和管理服务。

1.1、使用微服务网关的优点

网关具有的职责,如身份验证、监控、负载均衡、缓存、请求分片与管理、静态响应处理。当然,最主要的职责还是与“外界联系”。

使用网关的优点:

  1. 安全 。只有网关系统对外进行暴露,微服务可以隐藏在内网,通过防火墙保护。
  2. 易于监控。可以在网关收集监控数据并将其推送到外部系统进行分析。
  3. 易于认证。可以在网关上进行认证,然后再将请求转发到后端的微服务,而无须在每个微服务中进行认证。
  4. 减少了客户端与各个微服务之间的交互次数。
  5. 易于统一授权。

微服务网关就是一个系统,通过暴露该微服务网关系统,方便我们进行相关的鉴权,安全控制,日志统一处理,易于监控的相关功能。

1.2、常见的网关实现方式

常见的实现微服务网关的技术有以下:

  1. Nginx。 使用Nginx的反向代理和负载均衡可实现对api服务器的负载均衡及高可用。
  2. zuul。Zuul 是 Netflix 出品的一个基于 JVM 路由和服务端的负载均衡器。Netflix开源,功能丰富,使用JAVA开发,易于二次开发;需要运行在web容器中,如Tomcat。但是缺乏管控,无法动态配置;依赖组件较多;处理Http请求依赖的是Web容器,性能不如Nginx;
  3. spring cloud gateway。gateway 是spring 出品的 基于spring 的网关项目,集成断路器,路径重写,性能比Zuul好。

2、搭建gateway网关服务

创建一个以 springboot 作为模板的 gateway 模块,引入nacos服务发现和gateway依赖,如下:

<!--nacos服务注册发现依赖-->
<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 中配置服务基本信息、nacos地址、路由等即可。

路由配置包括:

  1. 路由id:路由的唯一标示
  2. 路由目标(uri):路由的目标地址,http代表固定地址,lb代表根据服务名负载均衡
  3. 路由断言(predicates):判断路由的规则
  4. 路由过滤器(filters):对请求或响应做处理

如下:

server:
  port: 10010
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # Nacos地址
    gateway:
      routes:
        - id: user-service   # 路由标示,必须唯一
          # uri: http://127.0.0.1:8081 # 路由的目标地址。也可以通过http的写成固定地址,但不推荐使用
          uri: lb://userservice # 路由的目标地址。lb就是负载均衡的意思,后面跟服务名称
          predicates: # 路由断言,判断请求是否符合规则
            - Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合
        - id: order-service
          uri: lb://orderservice
          predicates:
            - Path=/order/**

启动该服务,可以在 nacos 注册中心中查看到该服务,如下:

然后外部服务即可直接通过访问网关来访问微服务,而无需直接访问微服务的地址,如下通过直接访问 http://localhost:10010/order/101 即可访问到 order-service 的服务,网关会自动将匹配到的路由转发至对应的服务中,并且会自动实现负载均衡。

2.1、路由断言工厂(Route Predicate Factory)

我们在配置文件中写的断言规则只是字符串,这些字符串会被 Predicate Factory(断言工厂) 读取并处理,转变为路由判断的条件。例如 Path=/user/** 是按照路径匹配,这个规则是由rg.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory 类来处理的,像这样的断言工厂在SpringCloudGateway还有十几个。

Spring提供了11种基本的Predicate工厂,如下:

示例:

spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # Nacos地址
    gateway:
      routes:
        - id: order-service
          uri: lb://orderservice
          predicates:
            - Path=/order/**
            - After=2022-04-20T15:35:08.721398+08:00[Asia/Shanghai]

上面的路由断言意思是必须匹配 /order/ 路径,并且只有在 2022-04-20 日期后才能匹配成功正常访问,必须同时满足条件才能正常访问到服务,否则无法访问,接口会报 404。

可参考官网:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

2.2、路由过滤器工厂(GatewayFilter)

GatewayFilter 是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理。

Spring提供了31种不同的路由过滤器工厂。例如:

示例,比如我们通过路由过滤器来配置所有进入某个服务,比如 userservice 服务的请求都自动添加一个请求头:X-Request-red=blue。只需在配置 gateway 服务的配置文件中添加以下配置即可,如下:

spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # Nacos地址
    gateway:
      routes:
        - id: user-service 
          uri: lb://userservice 
          predicates: 
            - Path=/user/** 
          filters: # 过滤器
            - AddRequestHeader=X-Request-red, blue # 添加请求头

由此,所有通过 gateway 网关发往 userservice 的请求都会自动添加 X-Request-red=blue 请求头,在 userservice 服务中可以通过参数获取到该请求头数据。

上面的过滤器配置是针对了某个具体的服务,如果要对所有的路由都生效,则可以将过滤器工厂写到 default 下。格式如下:

spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # Nacos地址
    gateway:
      routes:
        - id: user-service 
          uri: lb://userservice 
          predicates: 
            - Path=/user/** default-filters: # 默认过滤器,会对所有的路由请求都生效
        - AddRequestHeader=X-Request-red, blue # 添加请求头

可参考官网:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

2.3、全局过滤器(GlobalFilter)

全局过滤器(GlobalFilter)与 GatewayFilter 的 default-filters 的作用类似,也是处理一切进入网关的请求和微服务响应,对所有路由都生效。区别在于 GatewayFilter 通过配置定义,只能处理一些比较简单的逻辑,而 GlobalFilter 的逻辑通过代码实现,可以自定义复杂逻辑。

要想实现全局过滤器需要实现 GlobalFilter 接口:

public interface GlobalFilter {
   /**
    *  处理当前请求,有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理
    *
    * @param exchange 请求上下文,里面可以获取Request、Response等信息 
    * @param chain 用来把请求委托给下一个过滤器 
    * @return {@code Mono<Void>} 返回标示当前过滤器业务结束   
   */
   Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

示例,我们定义一个全局过滤器,拦截所有的请求,判断请求的参数中是否有 authorization,并且参数值是否为admin,如果是则放行,否则拦截该请求。

我们在 gateway 服务中创建一个类,通过该类实现 GlobalFilter 接口即可,如下:

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Order(0)
@Component
public class AuthorizeFilter implements GlobalFilter{
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap<String, String> params = request.getQueryParams();
        // 2.获取参数中的 authorization 参数
        String auth = params.getFirst("authorization");
        // 3.判断参数值是否等于 admin
        if ("admin".equals(auth)) {
            // 4.是,放行
            return chain.filter(exchange);
        }
        // 5.否,拦截
        // 5.1.设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);   //这里设置了HttpStatus.UNAUTHORIZED状态码,即401,如果请求的参数不满足时将会返回401
        // 5.2.拦截请求
        return exchange.getResponse().setComplete();
    }
}

2.4、过滤器的执行顺序(defaultFilter、路由过滤器、GlobalFilter)

请求在进入网关后会碰到三类过滤器:当前路由的过滤器、DefaultFilter、GlobalFilter。在请求匹配到路由后,会将 当前路由过滤器、DefaultFilter、GlobalFilter,合并到同一个过滤器链(集合)中,通过比较它们之间的 order 值大小进行排序,值越小越先执行,以此来依次执行每个过滤器。

  • 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前。
  • GlobalFilter 通过实现 Ordered 接口,或者添加 @Order 注解来指定 order 值;但是路由过滤器和 defaultFilter 的 order 则由 Spring 自动指定,默认是按照声明顺序从1递增,比如 defaultFilter 下有多个过滤器,则从上至下默认从1开始递增,如果 filters 下定义了多个过滤器,同样从上至下默认从1开始递增
  • 当不同类型之间的过滤器的 order 值大小一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter 的顺序执行。

3、服务网关解决跨域问题

跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题。网关处理跨域采用的是 CORS 方案,只需要简单配置即可实现,如下:

spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848 # Nacos地址
    gateway:
      # gateway的全局跨域请求配置
      globalcors:
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
        corsConfigurations:
          '[/**]':  # 匹配的路由
            allowedHeaders: "*"  # 允许在请求中携带的头信息
            allowedOrigins: "*"  # 允许哪些网站的跨域请求。也可以通过数组的方式来只指定一些特定的网站
            allowCredentials: true  # 是否允许携带cookie
            allowedMethods: "*"  # 允许的跨域ajax的请求方式。也可以通过数组的方式来只指定一些特定的请求方式
            maxAge: 360000 # 跨域检测的有效期

本文转自 https://www.cnblogs.com/wenxuehai/p/16262799.html,如有侵权,请联系删除。

标签:网关,服务,请求,gateway,过滤器,Gateway,路由
From: https://www.cnblogs.com/firsthelloworld/p/17932998.html

相关文章

  • TSINGSEE青犀智能分析网关V4人体行为检测算法在视频监控中的应用
    旭帆科技智能分析网关的算法十分繁多,其中可分为人体事件、车辆事件、环境事件、行为检测、着装检测等等,可覆盖绝大多数场景,如智慧校园、智慧工地、智慧景区等,今天小编就TSINGSEE青犀智能分析网关的行为检测算法和大家进行研讨。在智能视频监控行业中,人体行为检测算法可以应用于......
  • 【方案】智能分析网关V4如何助力乡村环境智能监管,共筑美好乡村
    近期全国多地饱受雾霾伤害,严重影响了大家的日常生活与出行活动,不少乡村也受到了波及。随着乡村经济建设步伐的加快,农村城市化也越来越明显,乡村环境的监管与治理也成了一大难题,面对亟需改革的农村环境,环境智能视频监控方案应运而生。一、方案概述通过对农村各地进行监控部署,并接......
  • gateway Failed to bind on [0.0.0.0:443]
    1.问题背景项目在做非docker容器部署,直接在宿主机上部署,gateway出现端口绑定失败的问题Causedby:reactor.netty.ChannelBindException:Failedtobindon[0.0.0.0:443]Suppressed:java.lang.Exception:#blockterminatedwithanerrorat......
  • 在Spring Cloud中使用Zuul网关实现一个案例
    本篇依旧是在SpringCloud系列的博主已经搭建的SpringCloud微服务模块上进行的,注意,本文依旧适合初学者和或者在SpringCloud框架了解不是很深入的基础的开发者,本系列说不上有多高大上,博主坚持通过简单的案例,让开发者可以对SpringCloud的组件进行了解和使用,并在一定程度上介绍这些......
  • 基于Spring Boot2.x 集成 Spring Cloud Gateway
    参考https://blog.csdn.net/DCTANT/article/details/108125229(boot与cloud的版本关系)https://blog.csdn.net/yuanchangliang/article/details/109579705https://blog.csdn.net/qq_38380025/article/details/102968559本文代码下载环境环境版本说明windows1......
  • 批量设置默认网关和DNS
    环境:VS2022配置:使用Release版本输出的exe,否则在使用时会提示少dll代码:#ifndefCMDEXC_H#defineCMDEXC_H#include<cstring>#include<cstdio>#include<iostream>#include<regex>#include<iostream>usingnamespacestd;classCmdExc{public:......
  • 亿级并发,API网关等核心组件,如何设计?
    文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录博客园版为您奉上珍贵的学习资源:免费赠送:《尼恩Java面试宝典》持续更新+史上最全+面试必备2000页+面试必备+大厂必备+涨薪必备免费赠送:《尼恩技术圣经+高并发系列PDF》,帮你实现技术自由,完成职业升级,薪......
  • [网关] 网关之(1)基础概念
    1基础概念1.1网关(gateway)网关其实是一个服务器,扮演着代表其他服务器为客户端提供服务的中间者。与代理(proxy)不同,网关接收请求,仿佛它就是请求资源的源服务器。请求的客户端可能觉察不到它正在同网关通信。1.2上游(upstream)=>网关=>下游(downstream)=>Client所有......
  • Modbus转Profinet网关解决设备通讯不稳的问题
    Modbus转Profinet网关解决设备通讯不稳的问题通讯不稳定:表现为数据断断续续,多半是由于线路干扰、接口不匹配、程序不稳定、等原因造成。解决方案:在原配电柜添加Modbus转Profinet网关(XD-MDPN100/2000)即可解决通迅该问题,Modbus转Profinet网关(XD-MDPN100/2000)具有抗干扰功能,采用映射......
  • 如何配置双网关/双网卡
    #1.前期准备1)两个网卡都需要正确设置,包括各自默认网关(注意,两个网卡都需要设定网关)  网卡配置文件在/etc/sysconfig/network-scripts/目录下,需要正确设置两个网卡的配置文件,然后重新启用新配置。2)两个网卡都已正确接入到两路线路,并且两路网络的服务供应商都已正常提供服务#2.......