【SpringCloud】SpringCloud Gateway详解

前言

微服务分为多个服务,有很多服务是内部人员要用的,但是现在谁都可以访问到,那我们该怎么办呢?

Spring Cloud最新面试题
Spring Cloud Nacos详解之注册中心
Spring Cloud Nacos详解之配置中心
Spring Cloud Nacos详解之集群配置
Spring Cloud Eureka详解
Spring Cloud Frign详解
Spring Cloud Ribbon详解
Spring Cloud Hystrix详解

SpringCloud Gatewy网关

一.网关功能和工作原理

在这里插入图片描述

二.网关的类型

  • Gateway
    响应式编程,具有更好的性能。

  • Zuul
    阻塞式编程。

三.搭建网关

1.创建一个新的服务

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.添加网关依赖和nacos服务发现依赖

		<!--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>

3.编写yml配置文件

server:
  port: 10086  #端口号
spring:
  application:
    name: gateway #服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: 
        - id: user-service # 路由id,必须唯一。  用户服务
          uri: lb://userservice # 路由的目标地址,lb是负载均衡。 
          # uri: http://127.0.0.1/user/1   也可以使用这种,但是这种就固定了路由地址,就不能负载均衡了。
          predicates: # 路由断言,判断请求是否符合规则,符合就转发到目的路由。可以配置多个规则
            - Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合。
       - id: order-service  # 订单服务
         uri: lb://orderservice
         predicates:
           - Path=/order/**

四.路由断言工厂(Route Predicate Factory)

官网示例

属性描述示例
After是某个时间点之后的请求-After=2023-01-01T17:42:47.789-07:00[America/Denver]
(必须在2023年1月1日17点42分47秒之后发的请求才能通过,根据美国丹佛[America/Denver]的时间算)
Before是某个时间点之前的请求-Before=2022-02-22T22:22:22.433+8:00[Asia/Shanghai]
(必须在2022年2月22日22时22分22秒之前发的请求才能通过,根据[Asia/Shanghai]上海时间算)
Between是某两个时间点之前的请求-Between=时间[时区],时间[时区]
Cookie请求必须包含某些cookie- Cookie=ikun, rap
Header请求必须包含某些header- Header=X-Request-Id,\d+
Host请求必须是访问某个host(域名)- Host=**.kunkun,**com.cn
Method请求方式必须是指定方式-Method=GETPOST
Path请求路径必须符合指定规则-path=user/**
Query请求参数必须包含指定参数Query=ikun
RemoteAddr请求者的ip必须是指定范围- RemoteAddr=192.168.1.1/24
Weight权重处理

五.路由过滤器(属于GatewayFilter)

对进入网关的请求和微服务返回的响应做处理。比如:添加请求头。
官网示例

1.配置网关服务yml文件

路由过滤器:对当前路由生效。
server:
  port: 10086  #端口号
spring:
  application:
    name: gateway #服务名称
  cloud:
    gateway:
      routes: 
        - id: user-service # 路由id,必须唯一。  用户服务
          uri: lb://userservice # 路由的目标地址,lb是负载均衡。 
          # uri: http://127.0.0.1/user/1   也可以使用这种,但是这种就固定了路由地址,就不能负载均衡了。
          predicates: # 路由断言,判断请求是否符合规则,符合就转发到目的路由。可以配置多个规则
            - Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合。
		  filters:
        	- AddRequestHeader=Ikun,ji ni tai mei!  # 添加请求头,针对某个服务生效。

2.在添加请求头的服务编写代码

	在用户服务的controller里面写
	/**
     * @param id 用户id
     * @return 用户
     */
    @GetMapping("/{id}")
    public User queryById(@PathVariable("id") Long id,
                          @RequestHeader(value = "Ikun", required = false) String ikun) {
        System.out.println("Ikun最喜欢的歌是什么:" + ikun);
        return userService.queryById(id);
    }

然后访问 localhost:10086/user/1,控制台就会打印 ikun 的值。
在这里插入图片描述

六.DefaultFilter过滤器(属于GatewayFilter)

DefaultFilter:对所有路由都生效。
server:
  port: 10086  #端口号
spring:
  application:
    name: gateway #服务名称
  cloud:
    gateway:
      routes: 
        - id: user-service # 路由id,必须唯一。  用户服务
          uri: lb://userservice # 路由的目标地址,lb是负载均衡。 
          # uri: http://127.0.0.1/user/1   也可以使用这种,但是这种就固定了路由地址,就不能负载均衡了。
          predicates: # 路由断言,判断请求是否符合规则,符合就转发到目的路由。可以配置多个规则
            - Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合。
	   default-filters:
        - AddRequestHeader=Ikun,ji ni tai mei!  #添加请求头,全局生效

七.全局过滤器(GlobalFilter)

对进入网关的请求和微服务返回的响应做处理。和GatewayFilter作用一样

因为GatewayFilter是基于配置实现,处理的逻辑是固定的,GlobalFilter基于代码逻辑实现,更加灵活一些,可以用于验证用户身份等功能。

1.实现GlobalFilter接口

验证身份信息,根据authorization的值是否是ikun
// @Order(-1) 注解方式实现,如果有多个过滤器,越小越早走。
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
    @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.判断参数值是否等于 ikun
        if ("ikun".equals(auth)) {
            // 4.是,放行
            return chain.filter(exchange);
        }
        // 5.否,拦截
        // 5.1.设置状态码,未登录
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        // 5.2.拦截请求
        return exchange.getResponse().setComplete();
    }

	/**
	* 代码方式实现,实现 Ordered 接口,多个过滤器,返回值越小,越早走。
	**/
    @Override
    public int getOrder() {
        return -1;
    }
}

2.验证身份

(1) 如果authorization 参数不等于ikun或没有都会报错。
在这里插入图片描述

(2) authorization 参数等于 ikun正常访问。
在这里插入图片描述

八.过滤器执行顺序

请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到一个过滤链(集合)中,排序后依次执行每个过滤器**(DefaultFilter -> 路由过滤器 -> GlobalFilter)**。

1.为什么不是同一个过滤器可以放在一个过滤链中呢?由下面可得这三个过滤器本质上都是GatewayFilter

DefaultFilter 和 路由过滤器的实现都是 AddRequestHeaderGatewayFilterFactory 类,最后会生成一个真正的过滤器(GatewayFilter)。
在这里插入图片描述

GlobalFilter的实现是通过 GatewayFilterAdapter 适配器类实现了GatewayFilter,然后就可以把GlobalFilter适配成GatewayFilter
在这里插入图片描述

2.路由过滤器和DefaultFilter怎么设置@Order顺序呢?

由spring指定order,按声明顺序1开始递增。

在这里插入图片描述

扩展:

  • org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters()方法是先加载defaultFilters,然后再加载某个route的filters,然后合并。
  • org.springframework.cloud.gateway.handler.FilteringlWebHandler#handle()方法会加载全局过滤器与前面的过滤器合并后根据order排序,组织过滤器链。

九.Gateway解决跨域问题

跨域: 浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题。
解决: 采用CORS方案,网关处理跨域采用的同样是CORS方案。(简单来说就是浏览器询问服务端让不让这个请求跨域,如果让会返回结果)。

在yml文件配置以下内容
spring:
  cloud:
	gateway:
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题(浏览器去询问服务端的请求就是options)
        corsConfigurations:
          '[/**]':
            allowedOrigins:  # 允许哪些网站的跨域请求
              -"http://localhost:8888"
              -"http://www.ikun.com"
            allowedMethods: # 允许的跨域ajax的请求方式          
              -"GET"
			  -"POST"
		      -"DELETE"
			  -"PUT"
			  -"OPTIONS"
			allowedHeaders: "*" # 允许请求头跨域
			allowCredentials: true # 是否允许携带cookie
			maxAge: 360000 # 这次跨域检测的有效期
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
Spring Cloud Gateway是一个基于Spring Cloud的微服务网关,用于构建高效、可靠的微服务架构。它提供了一种简单而强大的方式来路由、过滤和转换请求,帮助开发者构建弹性、可扩展的微服务应用。 Spring Cloud Gateway的功能和工作原理可以通过以下几点来详解: 1. 网关功能:Spring Cloud Gateway作为一个API网关,具有路由、过滤和转发请求的功能。它可以根据请求的URL、请求头、请求参数等信息,将请求转发到不同的微服务实例上。 2. 网关路由:Spring Cloud Gateway支持基于路由规则的请求转发。开发者可以通过配置路由规则,将特定的请求路径映射到相应的微服务实例上。这样可以实现负载均衡、服务发现等功能。 3. 网关过滤Spring Cloud Gateway支持请求过滤器,可以在请求到达网关之前或之后对请求进行一系列操作。开发者可以根据需要添加自定义的过滤器,实现请求认证、请求转换、请求限流等功能。 4. 响应式框架:Spring Cloud Gateway基于Spring WebFlux框架,采用异步非阻塞的方式处理请求。这使得网关在高并发场景下具备更好的性能和吞吐量。 总之,Spring Cloud Gateway是一个功能强大的微服务网关,可以作为微服务架构的入口,实现请求的路由、过滤和转发。它采用响应式框架来处理请求,具备高并发和可扩展性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【SpringCloudSpringCloud原理之Gateway网关](https://blog.csdn.net/twotwo22222/article/details/129428040)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [SpringCloud Gateway 详解](https://blog.csdn.net/m0_51111980/article/details/128022758)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱穿背带裤的馫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值