网关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),然后执行了实际分发地址的逻辑。

相关推荐
蝎子莱莱爱打怪7 小时前
XZLL-IM干货系列 04|Netty 长连接实战:Pipeline 怎么排、心跳怎么跳、连接怎么管
后端·微服务·面试
SamDeepThinking1 天前
Java微服务练习方式
java·后端·微服务
米丘4 天前
微前端之 Web Components 完全指南
微服务·html
霸道流氓气质7 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
霸道流氓气质7 天前
Spring Boot 微服务性能优化完全指南
spring boot·微服务·性能优化
地瓜伯伯7 天前
从MESI缓存一致性协议讲透synchronized的底层
java·spring boot·spring·spring cloud·微服务·springcloud
Devin~Y7 天前
大厂 Java 面试实录:从音视频内容社区到 AI RAG 的全链路技术设计
java·spring boot·redis·spring cloud·微服务·kafka·音视频
递归尽头是星辰7 天前
AI 访问数据仓库:从直连到微服务化
数据仓库·人工智能·微服务·dataagent·ai数据治理
Hadoop_Liang8 天前
使用Kubernetes Gateway API实现域名访问应用
容器·kubernetes·gateway
就改了8 天前
Windows 环境 SkyWalking 完整实操教程
windows·微服务·skywalking