本文介绍: 大家都都知道在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端如何调用这么多的微服务呢?如果没有网关存在我们只能在客户端记录每个服务地址然后分别去用。每个业务都会需要鉴权、限流权限校验跨域逻辑,如果每个业务都各自为战。自己造轮子实现一遍,会很蛋疼,完全可以抽出来,放到一个统一的地方去做。
Java之SpringCloud Alibaba【一】【Nacos一篇文章精通系列 跳转
Java之SpringCloud Alibaba【二】【微服务调用组件Feign】 跳转
Java之SpringCloud Alibaba【三】【微服务Nacosconfig配置中心】 跳转
Java之SpringCloud Alibaba【四】【微服务 Sentinel服务熔断 跳转
Java之SpringCloud Alibaba【五】【微服务 Sentinel整合openfeign进行降级 跳转
Java之SpringCloud Alibaba【六】【Alibaba微服务分布式事务组件—Seata】 跳转
Java之SpringCloud Alibaba【七】【Spring Cloud微服务网关Gateway组件 跳转
Java之SpringCloud Alibaba【八】【Spring Cloud微服务Gateway整合sentinel限流 跳转
Java之SpringCloud Alibaba【九】【Spring Cloud微服务Skywalking】 跳转

一、网关简介

大家都都知道在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端如何去调用这么多的微服务呢?如果没有网关的存在我们只能在客户端记录每个微服务的地址然后分别去用。
在这里插入图片描述
这样的架构,会存在着诸多的问题:

上面的这些问题可以借助API网关解决

在这里插入图片描述
所谓的API网关,就是指系统统一入口,它封装应用程序内部结构,为客户说提供统一服务,一些与业务本身功能天关的公共逻辑可以这里实现。诸如认证、鉴权、监控路由转发等等,添加上API网关之后,系统的架构图变成了如下所示:
在这里插入图片描述
在这里插入图片描述

1、什么是Spring Cloud Gateway

网关作为流量的入口,常用的功能包括路由转发权限校验限流等。

Sping Cloud cGateway是Sping Clou官方推出的第二代网关框架定位于取代NeificZul

相比Zul来说,Spring Cloud Gateway提供更优秀的性能,更强大的有功能

Spring Cloud Gateway是由WebFlux + Netty + Reactor实现的响应式的API网关。它不能在传统的servlet器中工作,也不能构建war包。

Sping Cloud Gateway旨在为微服务架构提供一种简单且有效的API路由管理方式,并基于Fiter的方式提供网关的基本功能,例如说安全认证监控限流等等。
在这里插入图片描述官网文档: https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

在这里插入图片描述
Spring Cloud Gateway 功能特征

2、核心概念

3、工作原理

Spring Cloud Gateway的工作原理跟Zuul的差不多,最大区别就是Gateway的Filter只有prepost 两种。
在这里插入图片描述
客户端向Spring Cloud Gateway发出请求,如果请求与网关程序定义的路由匹配,则该请求就会被发送到网关Web处理程序,此时处理程序运行特定的请求过滤器链。过滤器之间用虚线分开的原因是过滤器可能会在发送代理请求的前后执行逻辑。所有pre过滤逻辑执行然后执行代理请求;代理请求完成后,执行post过滤逻辑

二、Spring Cloud Gateway快速开始

1、环境搭建基本环境搭建-实现路由】

注意:会和springwebmvc依赖冲突需要排除springwebmvc
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

<dependencies>
        <!--gateway依赖 springcloud 开发-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>

在这里插入图片描述
在这里插入图片描述
设置配置文件
在这里插入图片描述

server:
  port: 8088
spring:
  application:
    name: api-gateway
# gateway配置
  cloud:
    gateway:
      routes:
        - id: order_route #路由的唯一标识,路由到order
          uri: http://localhost:8020 #需要转发地址
          #断言规则 用于路由规则匹配
          predicates:
            - Path=//
              # http://localhost:8088/order-serve/order/add  路由到↓
              # http://localhost:8020/order-serve/order/add
          filters:
            - StripPrefix=1 # 转发之前,去掉一次的路径
            # http://localhost:8020/order/add
        #- id: stock_route

在这里插入图片描述
访问http://localhost:8088/order-serve/order/add
在这里插入图片描述

2、集成Nacos

<!-- nacos服务注册发现 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

在这里插入图片描述

server:
  port: 8088
spring:
  application:
    name: api-gateway
# gateway配置
  cloud:
    gateway:
      routes:
        - id: order_route #路由的唯一标识,路由到order
          uri: lb://order-service # 需要转发的地址  lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略 order-service服务名
          #断言规则 用于路由规则匹配
          predicates:
            - Path=/order-serve/**
              # http://localhost:8088/order-serve/order/add  路由到↓
              # http://localhost:8020/order-serve/order/add
          filters:
            - StripPrefix=1 # 转发之前,去掉第一次的路径
            # http://localhost:8020/order/add
        #- id: stock_route
    # 配置Nacos
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        username: nacos
        password: nacos

在这里插入图片描述

重新运行访问
http://localhost:8088/order-service/order/add
在这里插入图片描述
设置约定集成nacos
在这里插入图片描述

server:
  port: 8088
spring:
  application:
    name: api-gateway
  cloud:
    # gateway的配置
    gateway:
      discovery:
        locator:
          enabled: true  #是否启动自动识别nacos服务
    #配置Nacos
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        username: nacos
        password: nacos

重新启动项目
访问服务名对应的地址:http://localhost:8088/order-service/order/add

在这里插入图片描述
重新启动项目
访问http://localhost:8088/order/add

在这里插入图片描述
调整时间
在这里插入图片描述
重新运行项目
在这里插入图片描述

http://localhost:8088/order/add

在这里插入图片描述

3、路由断言工厂(Route Predicate Factories)配置

https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

作用:当请求gateway的时候, 使用断言对请求进行匹配, 如果匹配成功就路由转发,如果匹配失败返回404

类型:内置,自定义

SpringCloud Gateway包括许多内置的断言工厂,所有这些断言都与HTTP请求的不同属性匹配。具体如下:

类型的断言根据时间判断,主要有三个:
AfterRoutePredicateFactory:接收一个日期参数, 判断请求日期是否晚于指定日期
BeforeRoutePredicateFactory:接收– 个日期参数,判断请求日期是否早于指定日期
BetweenRoutePredicateFactory:接收两个日期参数,判断请求日期是否在指定时间段内

- After=2023-10-19T09:07:00.660+08:00[Asia/Shanghai]

在这里插入图片描述

- RemoteAddr=192.168.1.1/24
-Cookie=chocolate, ch.

HeaderRoutePredicateFactory:接收两个参数,标题名称和正则表达式。判断请求Header是否具有给定名称且值与正则表达式匹配。

- Header=X-Request-Id, d+

在这里插入图片描述

重新启动项目
利用API工具发送请求
在这里插入图片描述
把Headers当中的请求参数取消重新发起请求,会报错
在这里插入图片描述

HostRoutePredicateFactory:接收一个参数, 主机名模式。判断请求的Host是否满足匹配规则

-Host=**.testhost.org

MethodRoutePredicateFactory:接收一个参数, 判断请求类型是否跟指定的类型匹配。
在这里插入图片描述
重新启动测试
通过GET发送请求
在这里插入图片描述
通过POST发起请求
在这里插入图片描述

  • 基于Query请求参数的断言工厂
    在这里插入图片描述
    设置必须传递参数为name的参数
- Query=name

重新启动发起请求,没有设置name参数报错
在这里插入图片描述
设置name参数
在这里插入图片描述
设置指定参数
在这里插入图片描述

 - Query=name,xushu|zhuge

设置name的参数只能是xushu或者zhuge否则断言失败
发送请求报错
在这里插入图片描述
将参数改为xushu请求成功,改为zhuge也请求成功
在这里插入图片描述

  • 基于路由权重的断言工厂

WeightRoutePredicateFactory:接收-个[组名 权重],然后对于同-一个组内的路由按照权重转发

routes:
	-id: weight_ route1
	uri: host1
	predicates:
		-Path=/ product/**
		-Weight=group3,1
	-id: weight_ route2
	uri: host2
	predicates:
		- Path=/ product/**
		-Weight= group3, 9

4、自定义路由断言工厂

自定义路由断言工厂需要继承AbstractRoutePredicateFactory类,重写apply方法的逻辑。

apply方法中可以通过exchange. getRequest()倒ServerHttpRequest对象,从而可以获取到请求的参数、请求方式、请求头等信息

1、必须是Spring组件bean
2、类必须加上RoutePredicateFactory作为结尾
3、必须继承AbstractRoutePredicateFactory
4、必须声明静态内部声明属性来接受配置文件当中配置的断言信息
5、需要结合shortcutFieldOrder进行绑定
6、通过apply方法进行逻辑判断 true 就是匹配成功 false就是匹配失败

注意:命名需要以RoutePredicateFactory结尾
在这里插入图片描述
在这里插入图片描述


@Component
public class CheckAuthRoutePredicateFactory
        extends AbstractRoutePredicateFactory<CheckAuthRoutePredicateFactory.Config> {

    public CheckAuthRoutePredicateFactory() {
        super(CheckAuthRoutePredicateFactory.Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("name");
    }

    @Override
    public Predicate<ServerWebExchange> apply(CheckAuthRoutePredicateFactory.Config config) {
        return new GatewayPredicate() {
            @Override
            public boolean test(ServerWebExchange exchange) {

                if(config.getName().equals("xushu")){
                    return true;
                }
                return false;
            }

        };
    }


    // 用于接收配置文件中 断言的信息
    @Validated
    public static class Config {
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

}

在这里插入图片描述

重新启动项目
在这里插入图片描述
访问http://localhost:8088/order/add
在这里插入图片描述
修改对应的断言名称
在这里插入图片描述

查询启动
http://localhost:8088/order/add
在这里插入图片描述

5、过滤器工厂( GatewayFilter Factories)配置

在这里插入图片描述
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayilter-factories

在这里插入图片描述

在这里插入图片描述

5.1、添加请求头参数

在这里插入图片描述

          filters:
            - AddRequestHeader=X-Request-color,red

在这里插入图片描述

    @RequestMapping("/header")
    public String header(@RequestHeader("X-Request-color") String color){
        return color;
    }

在这里插入图片描述
重新启动两个项目

http://localhost:8088/order/header
在这里插入图片描述

5.2、添加请求参数

在这里插入图片描述

- AddRequestParameter=color,blue

在这里插入图片描述

  @RequestMapping("/parameter")
    public String parameter(@RequestParam("color") String color){
        return color;
    }

http://localhost:8088/order/parameter
在这里插入图片描述

5.3、为匹配的路由统一添加前缀

在这里插入图片描述

  servlet:
    context-path: /mall-order

在这里插入图片描述

            - PrefixPath=/mall-order #添加前缀对应微服务需要配置context-path

重新启动两个项目
在这里插入图片描述
访问http://localhost:8088/order/add
在这里插入图片描述
现在访问http://localhost:8020/mall-order/order/add
在这里插入图片描述
然而访问8082必须携带前缀
http://localhost:8020/mall-order/order/add
在这里插入图片描述

5.4、配置重定向

在这里插入图片描述

- RedirectTo=302, https://www.baidu.com

在这里插入图片描述
访问http://localhost:8088/order/add
重定向到了百度
在这里插入图片描述

5.5、自定义状态

在这里插入图片描述

- SetStatus= 404

在这里插入图片描述
访问http://localhost:8088/order/add
虽然访问成功了,但是返回状态码为404
在这里插入图片描述

6、自定义过滤器工厂

继承AbstractNameValueGatewayFilterFactory且我们的自定义名称必须要以GatewayFilterFactory结尾并交给spring管理
创建CheckAuthGatewayFilterFactory
在这里插入图片描述


/***
 */
@Component
public class CheckAuthGatewayFilterFactory
        extends AbstractGatewayFilterFactory<CheckAuthGatewayFilterFactory.Config> {

    public CheckAuthGatewayFilterFactory() {
        super(Config.class);
    }
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("value");
    }
    @Override
    public GatewayFilter apply(Config config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                String name=exchange.getRequest().getQueryParams().getFirst("name");

                if(StringUtils.isNotBlank(name)){
                    if(config.getValue().equals(name)){
                        return chain.filter(exchange);
                    }
                    else {
                        // 返回404
                        exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
                        return exchange.getResponse().setComplete();
                    }
                }
                // 正常请求
                return chain.filter(exchange);
            }
        };
    }

    public static class Config {
        private String value;
        public String getValue() {
            return value;
        }
        public void setValue(String value) {
            this.value = value;
        }
    }

}

在这里插入图片描述

            - CheckAuth=xushu

7、全局过滤器(Global Filters

在这里插入图片描述
局部过滤器和全局过滤器的区别

局部:针对某个路由,需要在路由中进行配置
全局:针对所有路由请求,一旦定义就会投入使用

GlobalFilter接口和GatewayFilter有一样的接口定义, 只不过,GlobalFilter 会作用于所有路由。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

@Component
public class LogFilter implements GlobalFilter {
    Logger log= LoggerFactory.getLogger(this.getClass());
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info(exchange.getRequest().getPath().value());
        return chain.filter(exchange);
    }
}

重新启动:http://localhost:8088/order/add?name=xushu

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

8、Reactor Netty访问日志

要启用Reactor Netty访问日志,请设置

-Dreactor.netty.http.server.accessLogEnabled=true

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

它必须是Java系统属性,而不是Spring Boot属性

您可以将日志记录系统配置为具有单独的访问日志文件。以下示例创建一个Logback配置:

<appender name=" accessLog" class="ch.qos.logback.core.FileAppender">
	<file>access_log.log</file>
	<encoder>
		<pattern>%msg%n</pattern>
	</encoder>
</appender>

<appender name=" async" class="ch.qos.logback.classic.AsyncAppender">
	<appender-ref ref="accessLog" />
</appender>

<logger name="reactor.netty.http.server.AccessLog" level="INFO" additivity="false">
	<appender-ref ref=" async"/>
</logger>
8.1、Gateway跨域配置(CORS Configuration)

通过ym|配置的方式
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#cors-configuration

在这里插入图片描述

      globalcors:
        cors-configurations:
          '[/**]': # 允许跨域访问的资源
            allowedOrigins: "*" #跨域允许的来源 例如:www.smsm.com
            allowedMethods:
              - GET
              - POST
              - PUT

模拟跨域请求,设置发起请求的页面
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
    <div >
        <table border="1">
        <thead>
        <tr>
            <th>id</th>
            <th>username</th>
            <th>age</th>
        </tr>
        </thead>
        <tbody id="userlist">
        </tbody>
    </table>
    </div>
    <input type="button" value="用户列表" onclick="getData()">
    <script>
        function getData() {
            $.get('http://localhost:8088/order/add',function(data){
                alert(data)
            });
        }
    </script>
</body>
</html>

在这里插入图片描述
访问网页
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

            allowedOrigins: "localhost:8088" #跨域允许的来源 例如:www.smsm.com

在这里插入图片描述
再次访问访问网页(抛出跨域异常
在这里插入图片描述
设置*运行所有的来源访问
在这里插入图片描述
Spring自带的跨域方式
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


@Configuration
public class CorsConfig {
    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedMethod("*");   //允许运行method
        config.addAllowedOrigin("*");   //允许的来源
        config.addAllowedHeader("*");   //允许的请求头参数

        // 允许访问的资源
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**",config);
        return new CorsWebFilter(source);
    }
}

在这里插入图片描述

Java之SpringCloud Alibaba【一】【Nacos一篇文章精通系列 跳转
Java之SpringCloud Alibaba【二】【微服务调用组件Feign】 跳转
Java之SpringCloud Alibaba【三】【微服务Nacos-config配置中心】 跳转
Java之SpringCloud Alibaba【四】【微服务 Sentinel服务熔断 跳转
Java之SpringCloud Alibaba【五】【微服务 Sentinel整合openfeign进行降级 跳转
Java之SpringCloud Alibaba【六】【Alibaba微服务分布式事务组件—Seata】 跳转
Java之SpringCloud Alibaba【七】【Spring Cloud微服务网关Gateway组件】 跳转
Java之SpringCloud Alibaba【八】【Spring Cloud微服务Gateway整合sentinel限流 跳转
Java之SpringCloud Alibaba【九】【Spring Cloud微服务Skywalking】 跳转

原文地址:https://blog.csdn.net/qq_44757034/article/details/133737232

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_12371.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注