项目示例 - 3.服务网关 - 3.Gateway

项目示例 - 3.服务网关 - 3.Gateway

关联知识:

  • 分布式微服务 - 3.服务网关 - 4.Gateway

内容提要:

  • 基本使用
  • 自定义断言
  • 自定义局部、全局过滤器

基本使用

  1. 建Module:微服务起名为gateway-server
  2. 改pom:引入以下依赖
xml 复制代码
    <dependencies>
        <!--gateway-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <!--Nacos服务注册-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>
  1. 写yml:在resources目录下创建application.yml文件,并做以下配置
yml 复制代码
server:
  port: 80

spring:
  application:
    name: gateway-server
  cloud:
    nacos:
      discovery:
        # nacos的地址
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          # 从服务注册中心根据别名来进行路由
          enabled: true
      routes:
        # 路由Id,自定义,唯一即可
        - id: nacos-provider-test
          # 成功匹配后,要转换成的路由地址(配合服务注册中心使用别名)
          uri: lb://nacos-provider
          # 成功匹配后,要转换成的路由地址(不配合服务注册中心)
          #uri: http://localhost:8001
          # 断言
          predicates:
            # 路径匹配的进行路由
            - Path=/**
  1. 主启动:在src下创建如下主启动类
java 复制代码
package learn.demo;

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

@SpringBootApplication
public class GatewayServer {

    public static void main(String[] args) {
        SpringApplication.run(GatewayServer.class, args);
    }

}
  1. 测试:
    1. 启动nacos,能正常打开nacos首页
    2. 启动nacos-provider微服务,浏览器访问localhost:8001/nacos/provider/test 接口,能正常返回信息,且在nacos服务列表中可看到成功注册
    3. 启动本微服务后,浏览器访问localhost/nacos/provider/test 接口,能正常返回信息

自定义断言

  1. 创建自定义断言类:
java 复制代码
package learn.demo.config;

import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

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

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

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

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return new Predicate<ServerWebExchange>() {
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
                List<String> strings = serverWebExchange.getRequest().getHeaders().get(config.key);
                if (strings==null || strings.isEmpty())
                    return false;
                return config.value.equals(strings.get(0));
            }
        };
    }

    public static class Config {
        private String key;
        private String value;

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }

}
  1. application.yml中配置断言:
yml 复制代码
server:
  port: 80

spring:
  application:
    name: gateway-server
  cloud:
    nacos:
      discovery:
        # nacos的地址
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          # 从服务注册中心根据别名来进行路由
          enabled: true
      routes:
        # 路由Id,自定义,唯一即可
        - id: nacos-provider-test
          # 成功匹配后,要转换成的路由地址(配合服务注册中心使用别名)
          uri: lb://nacos-provider
          # 成功匹配后,要转换成的路由地址(不配合服务注册中心)
          #uri: http://localhost:8001
          # 断言
          predicates:
            # 路径匹配的进行路由
            - Path=/**
            - Custom=test, a
  1. 测试:
    1. 启动nacos,能正常打开nacos首页
    2. 启动nacos-provider微服务,浏览器访问localhost:8001/nacos/provider/test 接口,能正常返回信息,且在nacos服务列表中可看到成功注册
    3. 启动本微服务后,API工具访问localhost/nacos/provider/test 接口,返回404。在header中,携带key为test、value为a的参数后再次访问,可以正常返回信息。

自定义过滤器

自定义局部过滤器

  1. 创建自定义过滤器类:
java 复制代码
package learn.demo.config;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;

@Component
public class CustomGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomGatewayFilterFactory.Config> {

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

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

    @Override
    public GatewayFilter apply(Config config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                // pre操作
                String pre;
                List<String> strings = exchange.getRequest().getHeaders().get("pre");
                if (strings==null || strings.isEmpty())
                    pre="no args";
                else
                    pre=strings.get(0);

                return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                    // 异步post操作
                    exchange.getResponse().getHeaders().set(config.key, pre+" | "+config.value);
                }));
            }
        };
    }

    public static class Config {
        private String key;
        private String value;

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }

}
  1. 添加配置:
yml 复制代码
server:
  port: 80

spring:
  application:
    name: gateway-server
  cloud:
    nacos:
      discovery:
        # nacos的地址
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          # 从服务注册中心根据别名来进行路由
          enabled: true
      routes:
        # 路由Id,自定义,唯一即可
        - id: nacos-provider-test
          # 成功匹配后,要转换成的路由地址(配合服务注册中心使用别名)
          uri: lb://nacos-provider
          # 成功匹配后,要转换成的路由地址(不配合服务注册中心)
          #uri: http://localhost:8001
          # 断言
          predicates:
            # 路径匹配的进行路由
            - Path=/**
            - Custom=test, a
          filters:
            - Custom=post,test
  1. 测试:
    1. 启动nacos,能正常打开nacos首页
    2. 启动nacos-provider微服务,浏览器访问localhost:8001/nacos/provider/test 接口,能正常返回信息,且在nacos服务列表中可看到成功注册
    3. 启动本微服务后,API工具访问localhost/nacos/provider/test 接口,返回404。在header中,携带key为test、value为a的参数后再次访问,可以正常返回信息,查看响应头中有key为post、value为no args | test的参数。

自定义全局过滤器

  1. 创建自定义过滤器类:
java 复制代码
package learn.demo.config;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // pre操作
        String pre;
        List<String> strings = exchange.getRequest().getHeaders().get("pre");
        if (strings==null || strings.isEmpty())
            pre="no args";
        else
            pre=strings.get(0);

        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            // 异步post操作
            exchange.getResponse().getHeaders().set("post", pre+" | test");
        }));
    }

    // 值越小,优先级越高
    @Override
    public int getOrder() {
        return 0;
    }
}
  1. 修改配置文件:
yml 复制代码
server:
  port: 80

spring:
  application:
    name: gateway-server
  cloud:
    nacos:
      discovery:
        # nacos的地址
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          # 从服务注册中心根据别名来进行路由
          enabled: true
      routes:
        # 路由Id,自定义,唯一即可
        - id: nacos-provider-test
          # 成功匹配后,要转换成的路由地址(配合服务注册中心使用别名)
          uri: lb://nacos-provider
          # 成功匹配后,要转换成的路由地址(不配合服务注册中心)
          #uri: http://localhost:8001
          # 断言
          predicates:
            # 路径匹配的进行路由
            - Path=/**
            - Custom=test, a
  1. 测试:
    1. 启动nacos,能正常打开nacos首页
    2. 启动nacos-provider微服务,浏览器访问localhost:8001/nacos/provider/test 接口,能正常返回信息,且在nacos服务列表中可看到成功注册
    3. 启动本微服务后,API工具访问localhost/nacos/provider/test 接口,返回404。在header中,携带key为test、value为a的参数后再次访问,可以正常返回信息,查看响应头中有key为post、value为no args | test的参数。
相关推荐
Moment5 分钟前
Node.js v25.0.0 发布——性能、Web 标准与安全性全面升级 🚀🚀🚀
前端·javascript·后端
IT_陈寒19 分钟前
Vite 3.0 性能优化实战:5个技巧让你的构建速度提升200% 🚀
前端·人工智能·后端
程序新视界38 分钟前
MySQL的整体架构及功能详解
数据库·后端·mysql
绝无仅有40 分钟前
猿辅导Java面试真实经历与深度总结(二)
后端·面试·github
绝无仅有1 小时前
猿辅导Java面试真实经历与深度总结(一)
后端·面试·github
Victor3562 小时前
Redis(76)Redis作为缓存的常见使用场景有哪些?
后端
Victor3562 小时前
Redis(77)Redis缓存的优点和缺点是什么?
后端
摇滚侠5 小时前
Spring Boot 3零基础教程,WEB 开发 静态资源默认配置 笔记27
spring boot·笔记·后端
AAA小肥杨6 小时前
基于k8s的Python的分布式深度学习训练平台搭建简单实践
人工智能·分布式·python·ai·kubernetes·gpu
斯班奇的好朋友阿法法6 小时前
rabbitmq在微服务中配置监听开关
微服务·rabbitmq·ruby