栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

spring-cloud 网关Gateway

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

spring-cloud 网关Gateway

网关是流量的入口 用来转发、权限校验、限流等

网关的作用 一个微服务项目 如果不使用网关 那么就意味着 权限校验、拦截黑名单请求等这种功能都需要在每个微服务中一一实现 10个微服务需要权限校验就需要写10次 如果把权限校验功能单独放到公共服务中 每个微服务也都要写同样的权限校验代码 后续升级也是问题 所以就有了网关 首先请求来了先去网关 在网关中权限校验等功能 满足了条件网关去调用微服务

gateway给我们实现了网关的功能

核心概念

 路由(route)
路由就是我们想让gateway去调用哪个微服务

 断言(predicates)
用户给服务端发送了一个请求 会来到网关 然后网关会根据这样请求地址进行判断要去调用那个微服务  这个断言就是用来写条件的

 过滤器(filter)
过滤器 可以做权限校验的功能跟Spring mvc过滤器差不多

gateway使用

引入依赖


    org.springframework.cloud
    spring-cloud-starter-gateway




    com.alibaba.cloud
    spring-cloud-starter-alibaba-nacos-discovery

编写yml配置文件

server:
  port: 8888
spring:
  application:
    name: mall-gateway
  #配置nacos注册中心地址
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

    gateway:
      discovery:
        locator:
          # 默认为false,设为true开启通过微服务创建路由的功能,即可以通过微服务名访问服务
          # http://localhost:8888/mall-order/order/findOrderByUserId/1
          enabled: true
      # 是否开启网关    
      enabled: true 

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

官方文档 很详细
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

自定义断言工厂

@Component
@Slf4j
public class CheckAuthRoutePredicateFactory extends AbstractRoutePredicateFactory {

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

@Override
public Predicate apply(Config config) {
    return new GatewayPredicate() {

        @Override
        public boolean test(ServerWebExchange serverWebExchange) {
            log.info("调用CheckAuthRoutePredicateFactory" + config.getName());
            if(config.getName().equals("11")){
                return true;
            }
            return false;
        }
    };
}


@Override
public List shortcutFieldOrder() {
    return Collections.singletonList("name");
}

public static class Config {

    private String name;

    public String getName() {
        return name;
    }

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

当yml文件配置了这个断言会进入这个apply方法 config可以得到请求中的信息 test方法返回false就不会去调用微服务

断言实现类名字 CheckAuthRoutePredicateFactory 前面是CheckAuth 后面是RoutePredicateFactory 前面的CheckAuth是自定义 后面RoutePredicateFactory必须这样写 这是一个规定

使用自定义断言工厂

yml中配置

spring:
  cloud:
    gateway:
      #设置路由:路由id、路由到微服务的uri、断言
      routes:
      - id: order_route  #路由ID,全局唯一
        uri: http://localhost:8020  #目标微服务的请求地址和端口
        predicates:
         # 测试:http://localhost:8888/order/findOrderByUserId/1
        - Path=/order
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
        // Register the block exception handler for Spring Cloud Gateway.
        return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
    }

    
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public GlobalFilter sentinelGatewayFilter() {
        return new SentinelGatewayFilter();
    }

}

手动设置限流规则 如果这个类被ioc管理了 在sentinel管理界面 会跟官网地址中显示的界面不一样 导入官网给的依赖也会不一样
用户可以通过 GatewayRuleManager.loadRules(rules) 手动加载网关规则

GatewayConfiguration中添加

    @PostConstruct
    public void doInit() {
        //初始化自定义的API
        initCustomizedApis();
        //初始化网关限流规则
        initGatewayRules();
        //自定义限流异常处理器
        initBlockRequestHandler();
    }

    private void initCustomizedApis() {
        Set definitions = new HashSet<>();
        ApiDefinition api = new ApiDefinition("user_service_api")
                .setPredicateItems(new HashSet() {{
                    add(new ApiPathPredicateItem().setPattern("/user/**")
                            .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
                }});
        definitions.add(api);
        GatewayApiDefinitionManager.loadApiDefinitions(definitions);
    }

    private void initGatewayRules() {
        Set rules = new HashSet<>();
        //resource:资源名称,可以是网关中的 route 名称或者用户自定义的 API 分组名称。
        //count:限流阈值
        //intervalSec:统计时间窗口,单位是秒,默认是 1 秒。
        rules.add(new GatewayFlowRule("order_route")
                .setCount(2)
                .setIntervalSec(1)
        );
        rules.add(new GatewayFlowRule("user_service_api")
                .setCount(2)
                .setIntervalSec(1)
        );

        // 加载网关规则
        GatewayRuleManager.loadRules(rules);
    }

    private void initBlockRequestHandler() {
        BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
            @Override
            public Mono handleRequest(ServerWebExchange exchange, Throwable t) {
                HashMap result = new HashMap<>();
                result.put("code",String.valueOf(HttpStatus.TOO_MANY_REQUESTS.value()));
                result.put("msg", HttpStatus.TOO_MANY_REQUESTS.getReasonPhrase());

                return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
                        .contentType(MediaType.APPLICATION_JSON)
                        .body(BodyInserters.fromValue(result));
            }
        };
        //设置自定义异常处理器
        GatewayCallbackManager.setBlockHandler(blockRequestHandler);
    }

gateway高可用 启动多个gateway实例 使用Nginx这种负载均衡框架进行负载实现

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/356541.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号