网关Gateway

目录

Gateway作用

Gateway使用


Gateway作用

在微服务项目中,没有引入网关时,项目架构如下:

引入网关后,架构如下:

引入网关后,有如下优势:

1、客户端请求经过网关向后台统一分发请求,后台微服务的增加、减少对客户端影响较小

2、客户端请求到每个后台微服务,可以经过网关实现统一的鉴权认证

3、网关可以对后台微服务做限流管理

Gateway使用

Gateway中有如下核心概念:

1、路由route:路由信息包括一个ID、一个目的URI、一组断言工厂、一组Filter组成。如果断言为真,则说明请求的 URL 和配置的路由匹配。

2、断言predicates:可以理解为匹配到路由的条件

3、过滤器Filter:对匹配的路由请求和响应进行处理

如下图配置信息,当访问http://网关ip:端口/blog-user/blogUser/getById,系统会将地址自动转发到 http://blog-user服务ip:端口/blogUser/getById 的这个请求中,并且注意,通过uri: lb://blog-user这样的配置,如果系统存在多个blog-user服务实例,gateway网关会负载均衡(轮询)的方式转发的对应的blog-user服务实例

在微服务项目开发过程中,通常会建立一个网关项目,专门负责对各个微服务请求转发的管理,示例中建立了blog-gateway项目,步骤如下:

1、添加gateway依赖

由于gateway应用也会注册到nacos上,所以nacos服务发现的依赖也需要加上

2、配置网关信息

从下图中可以看出,配置了2个网关路由规则,

当网关请求地址是:http://localhost:7777/blog-user/blogUser/getById时,系统会从nacos找到 blog-user微服务名,进而请求到实际的地址:http://localhost:8088/blogUser/getById

当网关请求地址是:http://localhost:7777/blog-content/blogContent/getById?id=1时,系统会从nacos找到 blog-content微服务名,进而请求到实际的地址:http://localhost:8888/blogContent/getById?id=1http://localhost:9999/blogContent/getById?id=1

blog-gateway注册在nacos中的信息如下:

blog-user注册在nacos中的信息如下:

blog-content注册在nacos中的信息如下:

3、实现网关自定义的过滤器

自定义过滤器分两种。全局过滤器:实现globalFilter和order接口。局部过滤器:实现AbstractGatewayFilterFactory接口并自定义或者使用父类的Config类 ,然后在配置文件中将过滤器进行配置(指明哪种路由用到自定义过滤器)。

下图自定义了网关过滤器CustomValidator,并配置在yml中,当请求网关地址:http://localhost:7777/blog-user/blogUser/getById 时,会先执行过滤器逻辑,然后再执行请求实际地址逻辑。

java 复制代码
package com.gingko.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.annotation.Order;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * 自定义过滤器 要在yml文件里配置自定义过滤器的过滤器名称CustomValidator (CustomValidatorGatewayFilterFactory)
 * (GatewayFilterFactory是默认名称,前面的就是自定义过滤器的名称)
 * filters:
 *   - CustomValidator=condition1,condition2,condition3,condition4
 */
@Order(1)
@Component
@Slf4j
public class CustomValidatorGatewayFilterFactory
        extends AbstractGatewayFilterFactory<CustomValidatorGatewayFilterFactory.Config> {

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

    @Override
    public GatewayFilter apply(Config config) {
        return ((exchange, chain) -> {
            log.info("进入自定义过滤器...");
            ServerHttpRequest request = exchange.getRequest();
            ServerHttpResponse response = exchange.getResponse();
            String key = config.getParam();
            log.info("参数信息:{},{},{},{}" ,config.getParam(),config.getParam2(),config.getParam3(),config.getParam4() );
            return chain.filter(exchange);
        });
    }

    /**
     *  如果是自定义config 则需要重写该方法返回list集合 以便routdefine通过反射传回参数
     *  ShortcutConfiguratble 这个类获取配置
     *  RouteDefinitionRouteLocator.getFilters 获得所有过滤器 然后按顺序执行
     * @return
     */
    @Override
    public List<String> shortcutFieldOrder() {
        List<String> list = new ArrayList<>();
        list.add("param");
        list.add("param2");
        list.add("param3");
        list.add("param4");
        return list;
    }

    /**
     * 你再路由配置那里给过滤器设置了多少参数那么就创建多少个参数变量来接收值
     */
    static public class Config {
        private String param;
        private String param2;
        private String param3;
        private String param4;

        public String getParam2() {
            return param2;
        }

        public void setParam2(String param2) {
            this.param2 = param2;
        }

        public String getParam3() {
            return param3;
        }

        public void setParam3(String param3) {
            this.param3 = param3;
        }

        public String getParam4() {
            return param4;
        }

        public void setParam4(String param4) {
            this.param4 = param4;
        }

        public String getParam() {
            return param;
        }

        public void setParam(String param) {
            this.param = param;
        }
    }
}

控制台运行结果如下:从日志时间上可以看出,请求网关地址:http://localhost:7777/blog-user/blogUser/getById 后,先执行的过滤器逻辑,打印输出了参数信息(p1,p2,p3,p4),然后执行了实际分发地址的逻辑。

相关推荐
一条咸鱼_SaltyFish2 小时前
[Day15] 若依框架二次开发改造记录:定制化之旅 contract-security-ruoyi
java·大数据·经验分享·分布式·微服务·架构·ai编程
2503_946971864 小时前
【Kernel/Consensus】2026年度第二周内核重构与分布式共识战争基准索引 (Benchmark Index)
网络安全·微服务·重构·数据集·分布式系统·系统内核
程序猿阿伟5 小时前
《Python生态事件溯源与CQRS轻量化落地指南》
大数据·python·微服务
超级小猪5 小时前
007-spring cloud alibaba之Sentinel限流
微服务
喵叔哟6 小时前
18.核心服务实现(下)
数据库·后端·微服务·架构
indexsunny6 小时前
互联网大厂Java求职面试实战:微服务与Spring Boot在电商场景中的应用
java·数据库·spring boot·微服务·kafka·hibernate·电商
wangbing11257 小时前
平台介绍-开放API后台微服务
数据库·微服务·架构
jasnet_u7 小时前
SpringBoot3.x+SpringCloudAlibaba2023+JDK17微服务基础框架搭建
微服务·云原生·架构
一条咸鱼_SaltyFish7 小时前
[Day16] Bug 排查记录:若依框架二次开发中的经验与教训 contract-security-ruoyi
java·开发语言·经验分享·微服务·架构·bug·开源软件
没有bug.的程序员8 小时前
Kubernetes 与微服务的融合架构:调度、弹性、健康检查深度协同
jvm·微服务·云原生·架构·kubernetes·健康检查·弹性伸缩