一、概述

网关是我们服务的守门神,是所有微服务的统一入口,一切请求都要先到网关,再到微服务,它可以帮助我们统一的进行一种操作,处理一些问题。

网关的核心功能特性:

1.请求路由、负载均衡

一切请求都必须先经过gateway网关,但网关不处理业务,而是根据某种规则把请求转发到某个微服务,这个过程叫做路由。当然路由的目标服务同时部署多个时,还需要做负载均衡,也就是根据规则具体转发到某个服务。

2.身份认证和权限校验

网关作为微服务的入口,需要校验用户是否有请求资格,如果没有则进行拦截。

3.请求限流

当请求流量过高时,在网关中安装下流的微服务能够接受的速度来放行请求,避免服务压力过大。

4.跨域处理

我们可以在网关中统一处理跨域问题,而不必单独在每个项目中处理。

二、使用

1.创建gateway微服务

SpringCloudAlibaba引入Gateway统一网关_网关

2.引入依赖

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>

3.编写启动类

package com.spepc.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author qx
 * @date 2023/10/18
 * @des 启动类
 */
@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

4.在application.yml文件基础配置和路由规则

server:
  # 网关端口
  port: 10010
spring:
  application:
    # 微服务名称
    name: gateway-service
  cloud:
    nacos:
      discovery:
        # nacos地址
        server-addr: 127.0.0.1:8848
    gateway:
      # 网关配置
      routes:
        # 路由ID 自定义 需要唯一
        - id: user-service
          # 路由目标地址 lb是指负载均衡 后面是微服务名称user-service
          uri: lb://user-service
          # 路由断言 判断请求是否符合路由规则的条件
          predicates:
             # 这个是路径匹配规则 只要符合/user/开头的请求都符合要求
            - Path=/user/**
  main:
    web-application-type: reactive

路由配置包含:

路由ID:路由的唯一标识

路由目标uri:路由的目标地址,http代表固定地址,lb代表根据服务负载均衡

路由断言predicates:判断路由的规则

路由过滤器filters:对请求或响应做处理

本例中,我们将 /user/**开头的请求,代理到lb://userservice ,lb是负载均衡,根据服务名拉取服务列表,实现负载均衡。


user模块中的微服务方法具体如下所示:

SpringCloudAlibaba引入Gateway统一网关_微服务_02

5.测试

我们启动网关服务,访问http://localhost:10010/user时,符合/user/** 规则,请求转发到uri:http://userservice/user,得到了结果:

SpringCloudAlibaba引入Gateway统一网关_断言_03

我们访问http://localhost:10010/order时,不符合/user/** 规则,请求被拦截,得到了结果:

SpringCloudAlibaba引入Gateway统一网关_微服务_04

三、断言工厂

断言工厂的配置在SpringCloudGateway中有下列所示:

名称

说明

After

是某个时间点后的请求

Before

是某个时间点之前的请求

Between

是某两个时间点之间的请求

Cookie

请求必须包含某些cookie

Header

请求必须包含某些header

Host

请求必须是访问某个host域名

Method

请求方法必须是指定方式

Path

请求路径必须符合指定规则

Query

请求参数必须包含指定参数

RemoteAddr

请求者的ip必须是指定范围

Weight

权重处理

我们只需要掌握Path这种路由工程就可以了。

四、过滤器

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

自定义全局过滤器

package com.spepc.gateway.filter;

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;

/**
 * @author qx
 * @date 2023/10/18
 * @des 自定义全局拦截器
 */
@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取请求参数
        MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
        // 获取authorization参数
        String authorization = params.getFirst("authorization");
        if ("admin".equals(authorization)) {
            // 放行
            return chain.filter(exchange);
        }
        // 禁止访问 设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
        return exchange.getResponse().setComplete();
    }
}

我们重启网关服务,再次访问http://localhost:10010/user发现没有请求到支持的服务数据。

SpringCloudAlibaba引入Gateway统一网关_负载均衡_05

我们访问http://localhost:10010/user?authorizatinotallow=admin正常访问到了数据

SpringCloudAlibaba引入Gateway统一网关_负载均衡_06

可以看到我们自定义的过滤器逻辑已经成功的产生了效果。

五、解决跨域问题

浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题。

解决方案:我们可以在网关服务的application.yml文件中添加下面配置:

server:
  # 网关端口
  port: 10010
spring:
  application:
    # 微服务名称
    name: gateway-service
  cloud:
    nacos:
      discovery:
        # nacos地址
        server-addr: 127.0.0.1:8848
    gateway:
      # 跨域配置
      globalcors:
        add-to-simple-url-handler-mapping: true
        corsConfigurations:
          '[/**]':
            allowedOrigins: # 允许哪些网站的跨域请求
              - "http://localhost:9001"
            allowedMethods: # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期
      # 网关配置
      routes:
        # 路由ID 自定义 需要唯一
        - id: user-service
          # 路由目标地址 lb是指负载均衡 后面是微服务名称user-service
          uri: lb://user-service
          # 路由断言 判断请求是否符合路由规则的条件
          predicates:
            # 这个是路径匹配规则 只要符合/user/开头的请求都符合要求
            - Path=/user/**
  main:
    web-application-type: reactive


阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Spring